腾讯Gaia平台的Docker应用实践(2)
其次由于Container结束时Docker Daemon可能是存活状态,也可能是已经死掉的状态,所以monitor进程在Container结束的时候会将它的启动和结束事件首先持久化到磁盘,再通知Docker Daemon更新Container状态.如果这时候Docker Daemon已经挂掉了,我们就重启一定的次数,如果没有通知成功,也不用继续等待这个Daemon进程启动就直接退出了,因为它原先已经把Container这个结束事件持久化到磁盘上了,当Docker Daemon重启之后,它就可以从磁盘加载这个Container的状态迁移文件,从而可以正确的恢复Container的状态. 第三比如说为了解决wait以及attach这些命令的问题,我们就将这些请求重定向到monitor进程进行处理,比如说attach请求的IO流,它以前是通过Daemon进行缓存的,那现在就通过monitor进程进行缓存,这样Docker Daemon挂掉对于每个Container来说并没有什么太大的影响. 第四比如说网络状态,现在Container Daemon的网络部分的代码已经全部迁出,迁出到一个新的工程叫做Libnetwork,Libnetwork中有很多的实体,比如说Libnetwork/Endpoint/Sandbox等有部分的状态是保存在内存中的,它原先自己会存储一些global的网络的状态,比如说global网络指的是一些Overlay网络,这种网络,它需要一些全局信息的保存,所以它会存在global kv,global kv可能是zkEtcd或者是Consul,我当时在做这个功能的时候就为Libnetwork引入了localstore功能,这个功能就会存储一些本地的网络的状态信息,比如说bridge模式的一些状态信息. Docker网络模式扩展相信使用Docker的人都会遇到网络部分的问题,网络部分是一个比较头疼的问题,也是每一家都会必然解决的问题.原先Docker Daemon提供了两种方式: 第一种是Host方式,是完全没有隔离的一个方式,它的优点是性能好,但是缺点也很明显,就是没有网络隔离,有端口冲突的问题. 其次Docker Daemon提供了一个bridge方式,也就是NAT的网络模式,这种网络模式提供了网络隔离的功能,它解决了端口冲突问题.但是Container IP是一个私有的IP,对外是不可见的.所以从另外一台主机的Container想要直接访问这个Container是不行的,必须得通过主机的一个映射之后的主机的一个IP,以及映射之后的端口去访问这个Container.但是端口映射提高了业务迁移的成本,他们可能会需要去改代码,或者去改配制.并且NAT的这种方式对网络的IO性能比Host方式也低了接近10%. 用户对网络的需求看一下Gaia平台在接入用户业务的过程中遇到的一些网络方面的需求.比如说用户可能会觉得端口冲突问题它不想改代码或者配置.第二就是可能有些业务会将本机的一个IP注册到ZooKeeper上做服务发现,这时候如果是使用NAT方式的话,这个私有IP如果注册到ZooKeeper上是完全没有任何意义的.第三就是有些业务会对有权限访问自己服务的IP做限制,比如说做白名单限制,这时候在同一个主机上的Container互相访问的时候,由于它的流量是从主机的Container首先发出,然后进入到global space,这时候会对它的IP进行原IP的替换,就是SNAT的过程.由于流量是从Docker 0进入的,所以它会将原IP替换成Docker 0的IP,也就是一个私有的IP,这时候在同组机的另外一个Container中看到的原IP就不是这个主机的IP,它是Docker 0的原IP,很显然这个IP是不能加入到它的白名单里面的,因为这是个私有IP,不能确定这个IP是从哪里访问过来的. 我们当初也做了一个改进,原先的SNAT的规则其实是MASQUERADE的规则,这个规则它会将原IP从哪个网卡进就会替换成哪个网卡的一个IP,后来我们加了一条规则是将它的原IP写死了,改成主机的IP,这样它在另外一个Container看到的是主机的IP,所以就不会有问题. 下面一点就是很多业务使用腾讯的TGW网关对外提供服务.我们在测试TGW对接NAT方式的时候发现报文是不通的,之所以不通是因为外面的流量访问进来之后,它会首先做一个DNAT的过程,DNAT的过程会把目的IP转化成Container的一个私有IP,之后当Container中的进程进行回包的时候,这时候其实走的是一个NAT的过程,因为它进来的时候发生了DNAT的过程,这个过程是发生在PREROUTING阶段,然后出去的时候是一个逆过程,这个时候这个包的IP的替换会发生在路由决策之后,这样在路由决策的时候destination IP还没有替换,所以导致这个TCP/IP的协议无法对包进行封包,所以会导致通过TGW对接NAT的方式是不可行的. 下面一点是某些业务,比如说GPU业务,可能要求很好的网络性能,这个也是通过NAT的方式无法解决的. 固定IP网络模式图 3 下面就看我们对于网络的改进(如图3).前面很多公司也介绍了,大家会给Container分配一个内网IP,我们也是这么做的.但是我们所不同的是我们在原先的网桥上面加了一个VLAN设备,这个起到什么怎么呢?比如说有一些内网IP跟主机的IP不处于同一个VLAN的时候,如果直接分配到Container中,通过网桥桥接起来,这时候网络是不能通的,因为需要给它出的流量打上一个vlan tag它才能通,这样我们就在原有的基础之上加了一个VLAN设备,这个VLAN设备后面再桥接一个网桥,然后让这些与主机的IP不同一个VLAN的IP的Container桥接到另外一个网桥上面,这样它出来都会打上这个vlan tag,这样就可以通了.这种方式相比NAT的方式,可能的IP对外可见,没有端口映射带来的迁移成本,也少了iptables或者是用户态进程的一个转发过程,所以性能略优于NAT的方式. 结合Gaia等上层调度系统可以实现IP漂移的功能,就是在Container发生迁移的过程中IP可以保持不变. SR-IOV(编辑:ASP站长网) |