主流Docker网络的实现原理概述_第1页
主流Docker网络的实现原理概述_第2页
主流Docker网络的实现原理概述_第3页
主流Docker网络的实现原理概述_第4页
主流Docker网络的实现原理概述_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 主流 Docker 网络的实现原理概述 目 录 TOC o 1-3 h z u HYPERLINK l _Toc66482680 主流 Docker 网络的实现原理概述 PAGEREF _Toc66482680 h 1 HYPERLINK l _Toc66482681 二、Docker原生的Overlay PAGEREF _Toc66482681 h 5 HYPERLINK l _Toc66482682 2.1 Overlay网络环境 PAGEREF _Toc66482682 h 5 HYPERLINK l _Toc66482683 2.2 容器南北流量 PAGEREF _Toc664826

2、83 h 6 HYPERLINK l _Toc66482684 2.3 容器东西向流量 PAGEREF _Toc66482684 h 7 HYPERLINK l _Toc66482685 2.4 ARP代理 PAGEREF _Toc66482685 h 8 HYPERLINK l _Toc66482686 2.5 VTEP表静态配置 PAGEREF _Toc66482686 h 9 HYPERLINK l _Toc66482687 2.6 总结 PAGEREF _Toc66482687 h 10 HYPERLINK l _Toc66482688 三、和Docker Overlay差不多的Wea

3、ve PAGEREF _Toc66482688 h 10 HYPERLINK l _Toc66482689 四、简单优雅的Flannel PAGEREF _Toc66482689 h 13 HYPERLINK l _Toc66482690 4.1 Flannel简介 PAGEREF _Toc66482690 h 14 HYPERLINK l _Toc66482691 4.2 Flannel Overlay网络 PAGEREF _Toc66482691 h 14 HYPERLINK l _Toc66482692 4.3 Flannel host-gw网络 PAGEREF _Toc66482692

4、 h 16 HYPERLINK l _Toc66482693 4.4 Flannel利用云平台路由实现跨主机通信 PAGEREF _Toc66482693 h 17 HYPERLINK l _Toc66482694 五、黑科技最多的Calico PAGEREF _Toc66482694 h 24 HYPERLINK l _Toc66482695 5.1 Calico环境配置 PAGEREF _Toc66482695 h 24 HYPERLINK l _Toc66482696 5.2 Calico容器内部网络 PAGEREF _Toc66482696 h 25 HYPERLINK l _Toc6

5、6482697 5.3 Calico主机路由 PAGEREF _Toc66482697 h 27 HYPERLINK l _Toc66482698 5.4 Calico多网络支持 PAGEREF _Toc66482698 h 27 HYPERLINK l _Toc66482699 5.5 Calico跨网段通信 PAGEREF _Toc66482699 h 30 HYPERLINK l _Toc66482700 六、与OpenStack网络集成的Kuryr PAGEREF _Toc66482700 h 31一、容器网络简介容器网络主要解决两大核心问题:一是容器的IP地址分配,二是容器之间的相互

6、通信。本文重在研究第二个问题并且主要研究容器的跨主机通信问题。实现容器跨主机通信的最简单方式就是直接使用host网络,这时由于容器IP就是宿主机的IP,复用宿主机的网络协议栈以及underlay网络,原来的主机能通信,容器也就自然能通信,然而带来的最直接问题就是端口冲突问题。因此通常容器会配置与宿主机不一样的属于自己的IP地址。由于是容器自己配置的IP,underlay平面的底层网络设备如交换机、路由器等完全不感知这些IP的存在,也就导致容器的IP不能直接路由出去实现跨主机通信。要解决如上问题实现容器跨主机通信,主要有如下两个思路:思路一:修改底层网络设备配置,加入容器网络IP地址的管理,修改

7、路由器网关等,该方式主要和SDN结合。思路二:完全不修改底层网络设备配置,复用原有的underlay平面网络,解决容器跨主机通信,主要有如下两种方式:Overlay隧道传输。把容器的数据包封装到原主机网络的三层或者四层数据包中,然后使用原来的网络使用IP或者TCP/UDP传输到目标主机,目标主机再拆包转发给容器。Overlay隧道如Vxlan、ipip等,目前使用Overlay技术的主流容器网络如Flannel、Weave等。修改主机路由。把容器网络加到主机路由表中,把主机当作容器网关,通过路由规则转发到指定的主机,实现容器的三层互通。目前通过路由技术实现容器跨主机通信的网络如Flannel

8、host-gw、Calico等。本文接下来将详细介绍目前主流容器网络的实现原理。在开始正文内容之前,先引入两个后续会一直使用的脚本:第一个脚本为docker_netns.sh:NAMESPACE=$1if -z $NAMESPACE ; then ls -1/var/run/docker/netns/ exit 0fiNAMESPACE_FILE=/var/run/docker/netns/$NAMESPACEif ! -f $NAMESPACE_FILE ; then NAMESPACE_FILE=$(docker inspect -f .NetworkSettings.SandboxKey

9、 $NAMESPACE 2/dev/null)fiif ! -f $NAMESPACE_FILE ; then echo Cannot open network namespace $NAMESPACE: No such file or directory exit 1fishiftif $# -lt 1 ; then echo No command specified exit 1finsenter -net=$NAMESPACE_FILE $该脚本通过指定容器id、name或者namespace快速进入容器的network namespace并执行相应的shell命令。如果不指定任何参数,

10、则列举所有Docker容器相关的network namespaces。4-a4a048ac67abe31dbbc394default# ./docker_netns.sh busybox ip addr # Enter busybox namespace1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet /8 scope host lo valid_lft forever p

11、referred_lft forever354: eth0if355: mtu 1450 qdisc noqueue state UP group default link/ether 02:42:c0:a8:64:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet /24 brd 55 scope global eth0 valid_lft forever preferred_lft forever356: eth1if357: mtu 1500 qdisc noqueue state UP group

12、 default link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 1 inet /16 brd 55 scope global eth1 valid_lft forever preferred_lft forever另一个脚本为find_links.sh:DOCKER_NETNS_SCRIPT=./docker_netns.shIFINDEX=$1if -z $IFINDEX ; thenfornamespacein $($DOCKER_NETNS_SCRIPT); do

13、 printf e1;31m%s: e0mn $namespace $DOCKER_NETNS_SCRIPT $namespace ip -c -o link printf ndoneelsefornamespacein $($DOCKER_NETNS_SCRIPT); doif $DOCKER_NETNS_SCRIPT $namespace ip -c -o link | grep -Pq$IFINDEX: ; then printf e1;31m%s: e0mn $namespace $DOCKER_NETNS_SCRIPT $namespace ip -c -o link | grep

14、-P $IFINDEX: ; printf nfidonefi该脚本根据ifindex查找虚拟网络设备所在的namespace:abe31dbbc394:354: eth0if355: mtu 1450 qdisc noqueue state UP mode DEFAULT group default link/ether 02:42:c0:a8:64:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0该脚本的目的是方便查找veth的对端所在的namespace位置。如果不指定ifindex,则列出所有namespaces的link设备。二、Docker原生的Ove

15、rlayLaurent Bernaille在DockerCon2017上详细介绍了Docker原生的Overlay网络实现原理,作者还总结了三篇干货文章一步一步剖析Docker网络实现原理,最后还教大家一步一步从头开始手动实现Docker的Overlay网络,这三篇文章为:Deep dive into docker overlay networks part 1Deep dive into docker overlay networks part 2Deep dive into docker overlay networks part 3建议感兴趣的读者阅读,本节也大量参考了如上三篇文章的内容

16、。2.1 Overlay网络环境测试使用两个Node节点:Node名主机IPnode-18node-254首先创建一个overlay网络:在两个节点分别创建两个busybox容器:容器列表如下:Node名主机IP容器IPnode-18/16node-254/16我们发现容器有两个IP,其中eth0 /16为我们创建的Overlay网络ip,两个容器能够互相ping通。而不在同一个node的容器IP eth1都是,因此172.18.0.

17、0/16很显然不能用于跨主机通信,只能用于单个节点容器通信。2.2 容器南北流量这里的南北流量主要是指容器与外部通信的流量,比如容器访问互联网。我们查看容器的路由:default via dev eth/16 dev eth0 scope link src /16 dev eth1 scope link src 由此可知容器默认网关为,也就是说容器是通过eth1出去的:77: eth1if78: mtu 1500 qdisc noqueue link/ether 02:42:

18、ac:12:00:02 brd ff:ff:ff:ff:ff:ff# ./find_links.sh 78default:78: vethf2de5d4if77: mtu 1500 qdisc noqueue master docker_gwbridge state UP mode DEFAULT groupdefaultlink/ether 2e:6a:94:6a:09:c5 brd ff:ff:ff:ff:ff:ff link-netnsid 1通过find_links.sh脚本查找ifindex为78的link在默认namespace中,并且该link的master为docker_gwb

19、ridge,也就是说该设备挂到了docker_gwbridgebridge。bridge name bridge id STP enabled interfacesdocker0 8000.02427406ba1anodocker_gwbridge 8000.0242bb868ca3no vethf2de5d4而正是bridgedocker_gwbridge的IP,也就是说docker_gwbridge是该节点的所有容器的网关。由于容器的IP是/16私有IP地址段,不能出公网,因此必然通过NAT实现容器IP与主机IP地址转换,查看iptables nat

20、表如下:-A POSTROUTING -s /16! -o docker_gwbridge -j MASQUERADE由此可验证容器是通过NAT出去的。我们发现其实容器南北流量用的其实就是Docker最原生的bridge网络模型,只是把docker0换成了docker_gwbridge。如果容器不需要出互联网,创建Overlay网络时可以指定-internal参数,此时容器只有一个Overlay网络的网卡,不会创建eth1。2.3 容器东西向流量容器东西流量指容器之间的通信,这里特指跨主机的容器间通信。显然容器是通过eth0实现与其他容器通信的:75: eth0if76:

21、mtu 1450 qdisc noqueue link/ether 02:42:0a:14:00:03 brd ff:ff:ff:ff:ff:ff# ./find_links.sh 761-19c5d1a7ef:76: veth0if75: mtu 1450 qdisc noqueue master br0 state UP mode DEFAULT groupdefault link/ether 6a:ce:89:a2:89:4a brd ff:ff:ff:ff:ff:ff link-netnsid 1eth0的对端设备ifindex为76,通过find_links.sh脚本查找ifinde

22、x 76在1-19c5d1a7efnamespace下,名称为veth0,并且master为br0,因此veth0挂到了br0 bridge下。通过docker_netns.sh脚本可以快速进入指定的namespace执行命令:76: veth0if75: mtu 1450 qdisc noqueue master br0 state UP mode DEFAULT groupdefault link/ether 6a:ce:89:a2:89:4a brd ff:ff:ff:ff:ff:ff link-netnsid 1# ./docker_netns.sh 1-19c5d1a7ef brct

23、l showbridge name bridge id STP enabled interfacesbr0 8000.6ace89a2894ano veth0 vxlan0可见除了veth0,bridge还绑定了vxlan0:74: vxlan0: mtu 1450 qdisc noqueue master br0 state UNKNOWN mode DEFAULT groupdefault link/ether 96:9d:64:39:76:4e brd ff:ff:ff:ff:ff:ff link-netnsid 0 promiscuity 1 vxlan id 256 srcport

24、00 dstport 4789 proxy l2miss l3miss ttl inherit ageing 300 udpcsum noudp6zerocsumtx noudp6zerocsumrx.vxlan0是一个VxLan虚拟网络设备,因此可以推断Docker Overlay是通过vxlan隧道实现跨主机通信的。这里直接引用Deep dive into docker overlay networks part 1的图:图中/16对应前面的/16网段。2.4 ARP代理如前面所述,跨主机的两个容器虽然是通过Overlay通信的,但容器自己却不知道,

25、他们只认为彼此都在一个二层中(同一个子网),或者说大二层。我们知道二层是通过MAC地址识别对方的,通过ARP协议广播学习获取IP与MAC地址转换。当然通过Vxlan隧道广播ARP包理论上也没有问题,问题是该方案将导致广播包过多,广播的成本会很大。和OpenStack Neutron的L2 Population原理一样,Docker也是通过ARP代理+静态配置解决ARP广播问题。我们知道,虽然Linux底层除了通过自学习方式外无法知道目标IP的MAC地址是什么,但是应用却很容易获取这些信息,比如Neutron的数据库中就保存着Port信息,Port中就有IP和MAC地址。Docker也一样会把e

26、ndpoint信息保存到KV数据库中,如etcd:有了这些数据完全可以实现通过静态配置的方式填充IP和MAC地址表(neigh表)替换使用ARP广播的方式。因此vxlan0还负责了本地容器的ARP代理:而vxlan0代理回复时直接查找本地的neigh表回复即可,而本地neigh表则是Docker静态配置,可查看Overlay网络namespaced neigh表: dev vxlan0 lladdr 02:42:0a:14:00:03 PERMANENT dev vxlan0 lladdr 02:42:0a:14:00:04 PERMANENT记录中的PER

27、MANENT说明是静态配置而不是通过学习获取的,IP 、正是另外两个容器的IP地址。每当有新的容器创建时,Docker通过Serf以及Gossip协议通知节点更新本地neigh ARP表。2.5 VTEP表静态配置前面介绍的ARP代理属于L2层问题,而容器的数据包最终还是通过Vxlan隧道传输的,那自然需要解决的问题是这个数据包应该传输到哪个node节点?如果只是两个节点,创建vxlan隧道时可以指定本地ip(local IP)和对端IP(remote IP)建立点对点通信,但实际上显然不可能只有两个节点。我们不妨把Vxlan出去的物理网卡称为VTEP(VX

28、LAN Tunnel Endpoint),它会有一个可路由的IP,即Vxlan最终封装后的外层IP。通过查找VTEP表决定数据包应该传输到哪个remote VTEP:容器MAC地址Vxlan IDRemote VTEP02:42:0a:14:00:032565402:42:0a:14:00:0425645.VTEP表和ARP表类似,也可以通过广播洪泛的方式学习,但显然同样存在性能问题,实际上也很少使用这种方案。在硬件SDN中通常使用BGP EVPN技术实现Vxlan的控制平面。而Docker解决的办法和ARP类似,通过静态配置的方式填充VTEP表,我

29、们可以查看容器网络namespace的转发表(Forward database,简称fdb),.02:42:0a:14:00:04 dev vxlan0 dst 45 link-netnsid 0 self permanent02:42:0a:14:00:03 dev vxlan0 dst 54 link-netnsid 0 self permanent.可见MAC地址02:42:0a:14:00:04的对端VTEP地址为45,而02:42:0a:14:00:03的对端VTEP地址为54,两条记录都是per

30、manent,即静态配置的,而这些数据来源依然是KV数据库,endpoint中locator即为容器的node IP。2.6 总结容器使用Docker原生Overlay网络默认会创建两张虚拟网卡,其中一张网卡通过bridge以及NAT出容器外部,即负责南北流量。另一张网卡通过Vxlan实现跨主机容器通信,为了减少广播,Docker通过读取KV数据静态配置ARP表和FDB表,容器创建或者删除等事件会通过Serf以及Gossip协议通知Node更新ARP表和FDB表。三、和Docker Overlay差不多的Weaveweave是weaveworks公司提供的容器网络方案,实现上和Docker原生

31、Overlay网络有点类似。初始化三个节点8、54、45如下:分别在三个节点启动容器:docker run -d -name busybox-node-1-net weave busybox sleep 3600# node-2docker run -d -name busybox-node-2-net weave busybox sleep 3600# node-3docker run -d -name busybox-node-3-net weave busybox sleep 3600在容器中我们相互ping:从结果发现,

32、Weave实现了跨主机容器通信,另外我们容器有两个虚拟网卡,一个是Docker原生的桥接网卡eth0,用于南北通信,另一个是Weave附加的虚拟网卡ethwe0,用于容器跨主机通信。另外查看容器的路由:default via dev eth0/16 dev eth0 scope link src /24 dev ethwe0 scope link src 28/4 dev ethwe0 scope link其中/4是一个组播地址,可见Weave是

33、支持组播的,参考Container Multicast Networking: Docker & Kubernetes | Weaveworks.我们只看第一个容器的ethwe0,VETH对端ifindex为14:default:14: vethwl816281577if13: mtu 1376 qdisc noqueue master weave state UP mode DEFAULT groupdefault link/ether de:12:50:59:f0:d9 brd ff:ff:ff:ff:ff:ff link-netnsid 0可见ethwe0的对端在default name

34、space下,名称为vethwl816281577,该虚拟网卡桥接到weavebridge下:bridge name bridge id STP enabled interfacesweave 8000.d2939d07704bno vethwe-bridge vethwl816281577weavebridge下除了有vethwl816281577,还有vethwe-bridge:9: vethwe-bridgevethwe-datapath: mtu 1376 qdisc noqueue master weave state UP mode DEFAULT groupdefault lin

35、k/ether 0e:ee:97:bd:f6:25 brd ff:ff:ff:ff:ff:ff可见vethwe-bridge与vethwe-datapath是一个VETH对,我们查看对端vethwe-datapath:8: vethwe-datapathvethwe-bridge: mtu 1376 qdisc noqueue master datapath state UP mode DEFAULT groupdefault link/ether f6:74:e9:0b:30:6d brd ff:ff:ff:ff:ff:ff promiscuity 1 veth openvswitch_sl

36、ave addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535vethwe-datapath的master为datapath,由openvswitch_slave可知datapath应该是一个openvswitch bridge,而vethwe-datapath挂到了datapath桥下,作为datapath的port。为了验证,通过ovs-vsctl查看:96548648-a6df-4182-98da-541229ef7b63 ovs_version: 2.9.2使用ovs-vsc

37、tl发现并没有datapath这个桥。官方文档中fastdp how it works中解释为了提高网络性能,没有使用用户态的OVS,而是直接操纵内核的datapath。使用ovs-dpctl命令可以查看内核datapath:systemdatapath: lookups: hit:109 missed:1508 lost:3 flows: 1 masks: hit:1377 total:1 hit/pkt:0.85 port 0: datapath (internal) port 1: vethwe-datapath port 2: vxlan-6784(vxlan: packet_type

38、=ptap)可见datapath类似于一个OVS bridge设备,负责数据交换,该设备包含三个port:port 0: datapath (internal)port 1: vethwe-datapathport 2: vxlan-6784除了vethwe-datapath,还有一个vxlan-6784,由名字可知这是一个vxlan:10: vxlan-6784: mtu 65535 qdisc noqueue master datapath state UNKNOWN mode DEFAULT groupdefault qlen 1000 link/ether d2:21:db:c1:9b

39、:28 brd ff:ff:ff:ff:ff:ff promiscuity 1 vxlan id 0 srcport 00 dstport 6784 nolearning ttl inherit ageing 300 udpcsum noudp6zerocsumtx udp6zerocsumrx external openvswitch_slave addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535最后Weave的网络流量图如下:四、简单优雅的Flannel4.1 Flannel

40、简介Flannel网络是目前最主流的容器网络之一,同时支持overlay(如vxlan)和路由(如host-gw)两种模式。Flannel和Weave以及Docker原生overlay网络不同的是,后者的所有Node节点共享一个子网,而Flannel初始化时通常指定一个16位的网络,然后每个Node单独分配一个独立的24位子网。由于Node都在不同的子网,跨节点通信本质为三层通信,也就不存在二层的ARP广播问题了。另外,我认为Flannel之所以被认为非常简单优雅的是,不像Weave以及Docker Overlay网络需要在容器内部再增加一个网卡专门用于Overlay网络的通信,Flannel

41、使用的就是Docker最原生的bridge网络,除了需要为每个Node配置subnet(bip)外,几乎不改变原有的Docker网络模型。4.2 Flannel Overlay网络我们首先以Flannel Overlay网络模型为例,三个节点的IP以及Flannel分配的子网如下:Node名主机IP分配的子网node-18/24node-254/24node-345/24在三个集成了Flannel网络的Node环境下分别创建一个busybox容器:容器列表如下:Node

42、名主机IP容器IPnode-18/24node-254/24node-345/24查看容器namespace的网络设备:416: eth0if417: mtu 8951 qdisc noqueue state UP mode DEFAULT groupdefault link/ether 02:42:28:0f:2b:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 promiscuity 0 veth addrgenmode eui64

43、numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535和Docker bridge网络一样只有一张网卡eth0,eth0为veth设备,对端的ifindex为417.我们查找下ifindex 417的link信息:default:417: veth1cfe340if416: mtu 8951 qdisc noqueue master docker0 state UP mode DEFAULT groupdefault link/ether 26:bd:de:86:21:78 brd ff:ff:ff:ff:ff:ff

44、link-netnsid 0可见ifindex 417在default namespace下,名称为veth1cfe340并且master为docker0,因此挂到了docker0的bridge下。bridge name bridge id STP enabled interfacesdocker0 8000.0242d6f8613eno veth1cfe340 vethd1fae9ddocker_gwbridge 8000.024257f32054no和Docker原生的bridge网络没什么区别,那它是怎么解决跨主机通信的呢?实现跨主机通信,要么Overlay隧道封装,要么静态路由,显然d

45、ocker0没有看出有什么overlay的痕迹,因此只能通过路由实现了。不妨查看下本地路由如下:default via dev eth0 proto dhcp src 8 metric 100/24 via dev flannel.1 onlink/24 dev docker0 proto kernel scope link src /24 via dev flannel.1 onlink.我们只关心40.15开头的路由,忽略

46、其他路由,我们发现除了/24直接通过docker0直连外,其他均路由转发到了flannel.1。而/24为本地Node的子网,因此在同一宿主机的容器直接通过docker0通信即可。我们查看flannel.1的设备类型: link/ether 0e:08:23:57:14:9a brd ff:ff:ff:ff:ff:ff promiscuity 0 vxlan id 1local8 dev eth0 srcport 00 dstport 8472 nolearning ttl inherit ageing 300 udpcsum no

47、udp6zerocsumtx noudp6zerocsumrx addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535可见flannel.1是一个Linux Vxlan设备,其中.1为VNI值,不指定默认为1。由于不涉及ARP因此不需要proxy参数实现ARP代理,而本节点的容器通信由于在一个子网内,因此直接ARP自己学习即可,不需要Vxlan设备学习,因此有个nolearning参数。而flannel.1如何知道对端VTEP地址呢?我们依然查看下转发表fdb:4e:55:ee:0a

48、:90:38 dev flannel.1 dst 45self permanentda:17:1b:07:d3:70 dev flannel.1 dst 54self permanent其中45、54正好是另外两个Node的IP,即VTEP地址,而4e:55:ee:0a:90:38以及da:17:1b:07:d3:70为对端的flannel.1设备的MAC地址,由于是permanent表,因此可推测是由flannel静态添加的,而这些信息显然可以从etcd获取:PublicIP:8,B

49、ackendType:vxlan,BackendData:VtepMAC:0e:08:23:57:14:9aPublicIP:54,BackendType:vxlan,BackendData:VtepMAC:da:17:1b:07:d3:70PublicIP:45,BackendType:vxlan,BackendData:VtepMAC:4e:55:ee:0a:90:38因此Flannel的Overlay网络实现原理简化如图:可见除了增加或者减少Node,需要Flannel配合配置静态路由以及fdb表,容器的创建与删除完全不需要Flannel干预,

50、事实上Flannel也不需要知道有没有新的容器创建或者删除。4.3 Flannel host-gw网络前面介绍Flannel通过Vxlan实现跨主机通信,其实Flannel支持不同的backend,其中指定backend type为host-gw支持通过静态路由的方式实现容器跨主机通信,这时每个Node都相当于一个路由器,作为容器的网关,负责容器的路由转发。需要注意的是,如果使用AWS EC2,使用Flannel host-gw网络需要禁用MAC地址欺骗功能,如图:使用OpenStack则最好禁用Neutron的port security功能。同样地,我们在三个节点分别创建busybox容器,

51、结果如下:Node名主机IP容器IPnode-18/24node-254/24node-345/24我们查看8的本地路由:default via dev eth0 proto dhcp src 8 metric 100/24 via 54 dev eth0/24 dev docker0 proto kernel scope link src

52、/24 via 45 dev eth0.我们只关心40.15前缀的路由,发现/24的下一跳为54,正好为node2 IP,而/24的下一跳为本地docker0,因为该子网就是node所在的子网,/24的下一跳为45,正好是node3 IP。可见,Flannel通过配置静态路由的方式实现容器跨主机通信,每个Node都作为路由器使用。host-gw的方式相对Overlay由于没有vxlan的封包拆包过程,直接路由就过去了,因此性能相对

53、要好。不过正是由于它是通过路由的方式实现,每个Node相当于是容器的网关,因此每个Node必须在同一个LAN子网内,否则跨子网由于链路层不通导致无法实现路由导致host-gw实现不了。4.4 Flannel利用云平台路由实现跨主机通信前面介绍的host-gw是通过修改主机路由表实现容器跨主机通信,如果能修改主机网关的路由当然也是没有问题的,尤其是和SDN结合方式动态修改路由。目前很多云平台均实现了自定义路由表的功能,比如OpenStack、AWS等,Flannel借助这些功能实现了很多公有云的VPC后端,通过直接调用云平台API修改路由表实现容器跨主机通信,比如阿里云、AWS、Google云等

54、,不过很可惜官方目前好像还没有实现OpenStack Neutron后端。下面以AWS为例,创建了如下4台EC2虚拟机:node-1: 8/24node-2: 54/24node-3: 45/24node-4: 3/24注意第三台和其余两台不在同一个子网。三台EC2均关联了flannel-role,flannel-role关联了flannel-policy,policy的权限如下:Version: 2012-10-17,Statement: Sid: VisualEditor0,Effect: Allow,

55、Action: ec2:DescribeInstances,ec2:CreateRoute,ec2:DeleteRoute,ec2:ModifyInstanceAttribute,ec2:DescribeRouteTables,ec2:ReplaceRoute,Resource: *即EC2实例需要具有修改路由表等相关权限。之前一直很疑惑AWS的role如何与EC2虚拟机关联起来的。换句话说,如何实现虚拟机无需配置Key和Secretd等认证信息就可以直接调用AWS API,通过awscli的-debug信息可知awscli首先通过metadata获取role信息,再获取role的Key和Se

56、cret:关于AWS如何知道调用metadata的是哪个EC2实例,可参考之前的文章OpenStack虚拟机如何获取metadata.另外所有EC2实例均禁用了MAC地址欺骗功能(Change Source/Dest Check),安全组允许flannel网段/16通过,另外增加了如下iptables规则:iptables -I FORWARD -src /16-j ACCEPTflannel配置如下:Network: /16,Backend: Type: aws-vpc启动flannel,自动为每个Node分配24位子网,网段如下:Nod

57、e名主机IP容器IPnode-18/24node-254/24node-345/24node-43/24我们查看node-1、node-2、node-3关联的路由表如图:node-4关联的路由表如图:由此可见,每增加一个Flannel节点,Flannel就会调用AWS API在EC2实例的子网关联的路由表上增加一条记录,Destination为该节点分配的Flannel子网,Target为该EC2实例的主网卡。在4个节点分别创建

58、一个busybox容器,容器IP如下:Node名主机IP容器IPnode-18/24node-254/24node-345/24node-43/24所有节点ping node-4的容器,如图:我们发现所有节点都能ping通node-4的容器。但是node-4的容器却ping不通其余容器:这是因为每个Node默认只会添加自己所在路由的记录。node-4没有node-1 node-3的路由信息,因此不通。可能有人会问,node1 n

59、ode3也没有node4的路由,那为什么能ping通node4的容器呢?这是因为我的环境中node1 node3子网关联的路由是NAT网关,node4是Internet网关,而NAT网关的子网正好是node1 node4关联的子网,因此node1 node3虽然在自己所在的NAT网关路由没有找到node4的路由信息,但是下一跳到达Internet网关的路由表中找到了node4的路由,因此能够ping通,而node4找不到node1 node3的路由,因此都ping不通。以上只是默认行为,Flannel可以通过RouteTableID参数配置Node需要更新的路由表,我们只需要增加如下两个子网的

60、路由如下:Network: /16,Backend: Type: aws-vpc,RouteTableID: rtb-0686cdc9012674692,rtb-054dfd5f3e47102ae重启Flannel服务,再次查看两个路由表:我们发现两个路由表均添加了node1 node4的Flannel子网路由。此时四个节点的容器能够相互ping通。从中我们发现,aws-vpc解决了host-gw不能跨子网的问题,Flannel官方也建议如果使用AWS,推荐使用aws-vpc替代overlay方式,能够获取更好的性能:When running within an Amazon

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论