滴普技术荟-云原生基座OpenKube开放容器实践(五):linux配置跨主机容器通信

90 阅读6分钟

在本章主要完成以下几件事情:

1.配置linux主机路由完成跨主机容器通信

2.配置linux ip tunnel完成跨主机容器通信

3.配置linux vxlan完成跨主机容器通信

主机路由

前面我们已经介绍了几种从容器到主机通信的配置方式,接下来我们通过配置主机路由来打通不同主机的容器,首先在两台主机上分别创建一个新的NS然后配置到各自主机的通信,环境如下:

host1: host-name:worker2 ip:10.57.4.20 pod-cidr:192.168.10.0/24

host2: host-name:worker3 ip:10.57.4.21 pod-cidr:192.168.11.0/24

首先在host1上执行:

然后在host2上执行:

如无意外,两台主机和各自的ns1应该是可以相互ping通的了,这时候的状态如下:

要让两台主机的n1相互通信,只需要在两台主机上再加一条路由即可: host1:

host2: 如无意外,这时候 两台主机的NS1已经可以相互ping通了,但这里的意外太多了: 1.首先,如果你的两台主机不在同一个网段,这是不通的,主机所在网络的路由器不知道如何转发192.168.0.0/16网段的流量,数据包应该会被丢弃; 2.其次,如果你是在阿里云或腾讯云的主机上试,也是不通的,因为这两大云平台的主机都不是二层直连的,当数据从host1离开的时候,目的地址为192.168.11.10,这个地址ECS所在的VPC的路由表不知道怎么转发,也会丢弃,所以要去主机所在网络的路由表中添加两条到192.168.10.0/24和192.168.11.0/24两个网段的条目; 3.如果是在华为云的ECS上,则要关闭ECS的网卡的“源/目的检查”; 4.最后,还要记得在ECS所属的安全组里添加对于这两个网段的来源信任。

一个CNI插件通常包含两部分,一个binary和一个daemon,那个daemon的其中一个功能就是一直监听来自api-server的node新增、删除事件,把相关的pod-cidr和node-ip添加到各个节点的主机路由条目上。

IP tunnel

ip tunnel的方式就是在各个主机上建立一个one-to-many的ip tunnel,然后把其它节点的pod-cidr加到主机路由上,只不过dev就不再是eth0了,而是新建的ip tunnel设备,我们接着上面的环境继续操作: 首先删除在两台主机上增加的主机路由 host1: host2: 然后在两台主机上分别创建一个one-to-many的ip tunnel(所谓的one-to-many,就是配置ip tunnel时,不指定remote address) host1:

host2:

此时的状态: 这时候两个ns1应该已经可以相互ping通了,而且这次不管什么云平台不管安全组开没开不管什么源目的检查,应该都能通了,因为ip tunnel的原理是在原来的ip头上再加一层ip头,外层的ip头用的源目的是主机的ip,让主机所在的网络感觉这是正常的主机流量,在host1中执行:

在host2的eth0用tcpdump打印一下流量,就能看到有两层ip头:

vxlan

vxlan的方式有点像ip tunnel的方式,也是在两个主机建立一个overlay的网络,只不过vxlan是overlay在二层,我们接着上面的环境继续往下做,先把mustang.tun0删除 在两个节点上执行:

接下来在host1上执行如下命令创建vxlan设备:

然后查看vxlan0的设备的mac地址,记下来:

记住如下信息A:(192.168.10.0/24  下一跳192.168.10.1、  下一跳MAC 02:40:94:ce:82:cc 、下一跳的MAC所在主机IP 10.57.4.21)

在host2上执行:

查看host2的vxlan0设备的mac,记下来:

记住如下信息B:(192.168.11.0/24  下一跳192.168.11.1 、  下一跳MAC 02:3f:39:67:7d:f9 、下一跳的MAC所在主机IP 10.57.4.20)

回到host1上执行如下命令:这里用的是记录的信息A,第一条命令加主机路由,第二条命令加邻居表,第三条加FDB

host2也一样,只不过用的是记录的信息B:

这时候两台主机的NS1应该可以相互ping通了,在host2的容器里ping一下host1的容器,在host1打开网卡监听,拦截的数据如下:

可以看到也是两层包头,外层包头显示这是otv(overlay transport virtualization)包,对于otv,用一句话解释: OTV is a "MAC in IP" technique to extend Layer 2 domains over any transport。

对比

用主机路由的方式,因为没有封包拆包的性能损耗,所以速度是最快的,但因为受限的场景较多,反而使用得并不广泛;ip tunnel和vxlan因为要封包拆包,性能会比主机路由的方式差一些,但没有场景限制,基本上只要节点是通的,容器就能通,所以使用比较广泛。

虽然同是overlay模式,vxlan和ip tunnel之间的性能还是有比较大的差异。vxlan在外层是依赖两台主机的UDP通信,而且第一层是到了MAC层才开始再次封包,查FDB和ARP表,相对于ip tunnel只是在IP头的外面再加一层IP头来说性能损耗多了很多,我们通过实测发现vxlan会比ip tunnel性能下降20%左右。

总结

通过前面一系列的文章,我们可以了解到,跨主机容器通信的方式与同主机容器间通信方式是分开的,你可以用纯veth/bridge/macvlan/ipvlan等方式实现同主机容器通信,可以用host-gw/ip tunnel/vxlan/弹性网卡来实现跨主机的容器通信,现在主流的cni基本上就是在这几种选择中组合。

上面的三种跨主机容器通信的方式,其中的主机路由就是flannel的host-gw和calico的BGP模式的原理,而ip tunnel就是calico的IPIP模式的原理(flannel的最新版也应该很快会支持IPIP,看代码已经加上了),vxlan方式就是flannel的vxlan模式的原理。

这个系列的文章出发点是为了剖析k8s常用的CNI组件的原理,到这一步我们已经把主流的几个cni的几种模式的原理都覆盖了,但还差一个,就是flannel最原始的udp模式,这种模式自从flannel出了vxlan后就很少人再用了,因为性能损耗更大,flannel的vxlan用的就是udp协议,跟flannel的udp模式有哪些区别呢?下一章将单独讲flannel的udp模式。

了解更多信息请登录:www.deepexi.com/bbs/develop…