内容简介:在Kubernetes中网络中,主要包含两种IP,分别是Pod IP和Cluster IP。 Pod IP是实际存在于网卡之上(如VETH的虚拟网卡),而Cluster IP则是一个虚拟的IP地址,该虚拟机IP由kube-proxy进行维护,kube-proxy目前提供了两种实现方式,包括默认的ip tables实现以及在K8S 1.8之后开始支持的ipvs实现。对于Kubernetes其网络而言,其实现需要确保集群中每个Pod都有一个唯一的IP地址,并且Pod之间可以直接进行跨主机通讯。在符合这一原则的
在Kubernetes中网络中,主要包含两种IP,分别是Pod IP和Cluster IP。 Pod IP是实际存在于网卡之上(如VETH的虚拟网卡),而Cluster IP则是一个虚拟的IP地址,该虚拟机IP由kube-proxy进行维护,kube-proxy目前提供了两种实现方式,包括默认的ip tables实现以及在K8S 1.8之后开始支持的ipvs实现。
对于Kubernetes其网络而言,其实现需要确保集群中每个Pod都有一个唯一的IP地址,并且Pod之间可以直接进行跨主机通讯。在符合这一原则的前提下,Kubernetes允许通过插件的方式,集成不同的容器集群网络实现。其中最常用的应该是Flannel。Flannel是由CoreOS团队针对KUbernetes设计的一个Overlay Network实现,通过隧道协议(udp,vxlan)封装容器之间的通讯报文,实现集群间网络通讯。
Flannel默认使用UDP作为集群间通讯实现,如上图所示,Flannel通过ETCD管理整个集群中所有节点与子网的映射关系,如上图所示,Flannel分别为节点A和B划分了两个子网:10.1.15.0/16和10.1.20.0/16。同时通过修改 docker 启动参数,确保Docker启动的容器能够特定的网段中如10.1.15.1/24。
-
同一Pod实例容器间通信:对于Pod而言,其可以包含1~n个容器实例,这些容器实例共享Pod的存储以及网络资源,Pod直接可以直接通过127.0.0.1进行通讯。其通过 Linux 的Network Namespace为这组容器实现了一个隔离网络。
-
相同主机上Pod间通信:对于Pod而言,每一个Pod实例都有一个独立的Pod IP,该IP是挂载到虚拟网卡(VETH)上,并且bridge到docker0的网卡上。以节点A为例,其节点上运行的Pod均在10.1.15.1/24的网段中,其属于相同网络,因此直接通过docker0进行通信。
-
对于跨节点间的Pod通信:以节点A和节点B通讯而言,由于不同节点docker0网卡的网段并不相同,因此flannel通过主机路由表的方式,将对节点B POD IP网段地址的访问路由到flannel0的网卡上。 而flannel0网卡的背后运行的则是flannel在每个节点上运行的进程flanneld。由于flannel通过ETCD维护了节点间所有网络的路由关系,原本容器将的数据报文,被flanneld封装成UDP协议,发送到了目标节点的flanneld进程,再对udp报文进行解包,后将数据发送到docker0,从而实现跨主机的Pod通讯。
解析阿里云Flannel实现
上述简单解释了Flannel默认的UDP实现过程,可以看出,由于存在大量的数据报文封装和解析的过程,其必然会导致Pod间网络性能的下降。除了默认的UDP实现以外,Flannel还支持基于vxlan的方式,vxlan是一个在已有3层物理网络上构建的2层逻辑网络的协议。
这里我们以通过阿里云Kubernetes服务创建的集群为例,解释跨主机将Pod是如何通讯的。
这里创建了两个Pod实例,其分别运行在节点cn-beijing.i-2ze52j61t5p9z4n60c9m和cn-beijing.i-2ze52j61t5p9z4n60c9l上:
$ kubectl get pods -o wide --selector app=nginx NAME READY STATUS RESTARTS AGE IP NODE nginx-56f766d96f-2dl9t 1/1 Running 0 2m 172.16.2.229 cn-beijing.i-2ze52j61t5p9z4n60c9m nginx2-6f4bb4799-t84rh 1/1 Running 0 3m 172.16.2.125 cn-beijing.i-2ze52j61t5p9z4n60c9l
以172.16.2.229访问172.16.2.125为例,我们进入到172.16.2.229所在节点的flannel容器:
$ k -n kube-system get pods -o wide --selector app=flannel NAME READY STATUS RESTARTS AGE IP NODE kube-flannel-ds-7zdnw 2/2 Running 4 31d 192.168.3.91 cn-beijing.i-2ze52j61t5p9z4n60c9k kube-flannel-ds-86d5j 2/2 Running 0 31d 192.168.3.90 cn-beijing.i-2ze52j61t5p9z4n60c9m kube-flannel-ds-9xn6p 2/2 Running 1 31d 192.168.3.87 cn-beijing.i-2ze44hu8106jqyw43i8d kube-flannel-ds-hjlb4 2/2 Running 1 31d 192.168.3.92 cn-beijing.i-2ze52j61t5p9z4n60c9l kube-flannel-ds-nb28r 2/2 Running 1 31d 192.168.3.88 cn-beijing.i-2ze8rkx46zywd36w8noo kube-flannel-ds-vmsxn 2/2 Running 1 31d 192.168.3.89 cn-beijing.i-2ze3pggklybyryt9475e
首先,在上文中说了,Flannel通过ETCD会统一为每个节点分配相应的网段:
$ k -n kube-system exec -it kube-flannel-ds-hjlb4 -c kube-flannel cat /run/flannel/subnet.env FLANNEL_NETWORK=172.16.0.0/16 FLANNEL_SUBNET=172.16.2.1/25 FLANNEL_MTU=1500 FLANNEL_IPMASQ=true
如上所示,Flannel建立了一个172.16.0.0/16的大网,而节点cn-beijing.i-2ze52j61t5p9z4n60c9m则分配了一个172.16.2.1/25的小网。所以该节点上所有Pod的IP地址一定是在该网段中(172.16.2.1 ~ 172.16.2.126)。
出口方向
从nginx-56f766d96f-2dl9t(172.16.2.229)所在节点的flannel实例kube-flannel-ds-86d5j查看网卡信息:
$ k -n kube-system exec -it kube-flannel-ds-86d5j -c kube-flannel ifconfig cni0 Link encap:Ethernet HWaddr 0A:58:AC:10:02:81 inet addr:172.16.2.129 Bcast:0.0.0.0 Mask:255.255.255.128 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:613034223 errors:0 dropped:0 overruns:0 frame:0 TX packets:410106254 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:97180782429 (90.5 GiB) TX bytes:855792296086 (797.0 GiB) docker0 Link encap:Ethernet HWaddr 02:42:31:24:3A:76 inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0 UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) eth0 Link encap:Ethernet HWaddr 00:16:3E:12:3F:B9 inet addr:192.168.3.90 Bcast:192.168.3.255 Mask:255.255.252.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:1026400899 errors:0 dropped:0 overruns:0 frame:0 TX packets:731775772 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:933504290702 (869.3 GiB) TX bytes:151441072517 (141.0 GiB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:2848730 errors:0 dropped:0 overruns:0 frame:0 TX packets:2848730 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1 RX bytes:1107009588 (1.0 GiB) TX bytes:1107009588 (1.0 GiB) veth00c70308 Link encap:Ethernet HWaddr D2:D9:ED:7B:3F:A7 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:10680903 errors:0 dropped:0 overruns:0 frame:0 TX packets:12038380 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:717656154 (684.4 MiB) TX bytes:108607531374 (101.1 GiB) # 省略其它输出
其中veth00c70308是每个Pod实例虚拟网卡,并且通过网桥的方式链接到cni0网卡:
$ k -n kube-system exec -it kube-flannel-ds-86d5j -c kube-flannel brctl show bridge name bridge id STP enabled interfaces docker0 8000.024231243a76 no cni0 8000.0a58ac100281 no veth00c70308 veth244016e7 veth41b59852 veth1bde8f9e veth5758e57f vethfb90332d veth6fd79bb3 veth80ab3625 veth2f19245f vethb593c87a vethbc655860 vethde851a00 veth0c794757 veth46c15d7c vethdddc772a veth9e77c7d5 veth17b62b88 veth3810c1b0
从172.16.2.229向172.16.2.125,从源容器发出后通过网桥全部发送到cni0的网卡上。查看系统路由表,遗憾的是在系统中找不到任何从cni0网卡向后转发的规则:
$ k -n kube-system exec -it kube-flannel-ds-86d5j -c kube-flannel route Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface default 192.168.3.253 0.0.0.0 UG 0 0 0 eth0 169.254.0.0 * 255.255.0.0 U 1002 0 0 eth0 172.16.2.128 * 255.255.255.128 U 0 0 0 cni0 172.17.0.0 * 255.255.0.0 U 0 0 0 docker0 192.168.0.0 * 255.255.252.0 U 0 0 0 eth0
这部分的路由转发在阿里云环境中是通过VPC路由表实现,如下所示:
从172.16.2.225发送到172.16.2.125的请求,匹配的路由记录为172.16.2.0/25。流量会被转发到 主机i-2ze52j61t5p9z4n60c9l,即Pod实例nginx2-6f65c584d-nglvf(172.16.2.125)所在的主机。
入口方向
出口方向,从源容器nginx-56f766d96f-2dl9t(172.16.2.229)发送到nginx2-6f4bb4799-t84rh(172.16.2.125)的流量已经正确的发送到目标节点i-2ze52j61t5p9z4n60c9l。
查看接收流量主机的路由规则:
$ k -n kube-system exec -it kube-flannel-ds-hjlb4 -c kube-flannel -- route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.3.253 0.0.0.0 UG 0 0 0 eth0 169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0 172.16.2.0 0.0.0.0 255.255.255.128 U 0 0 0 cni0 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0 192.168.0.0 0.0.0.0 255.255.252.0 U 0 0 0 eth0
根据主机路由表规则,发送到172.16.2.125的请求会落到路由表:
172.16.2.0 0.0.0.0 255.255.255.128 U 0 0 0 cni0
从而请求进入到cni0网卡,并发送到相应的容器。
相比于UDP的实现方式,在vxlan中,不需要依赖于额外的flannel接口,通过( ali-vpc backend )来代替封装IP规则以获得最佳的性能表现。
以上所述就是小编给大家介绍的《Flannel网络以及在阿里云下的实现解析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
深入理解C++11
Michael Wong、IBM XL编译器中国开发团队 / 机械工业出版社 / 2013-6 / 69.00元
《深入理解C++11:C++11新特性解析与应用》内容简介:国内首本全面深入解读C++11新标准的专著,由C++标准委员会代表和IBM XL编译器中国开发团队共同撰写。不仅详细阐述了C++11标准的设计原则,而且系统地讲解了C++11新标准中的所有新语言特性、新标准库特性、对原有特性的改进,以及如何应用所有这些新特性。 《深入理解C++11:C++11新特性解析与应用》一共8章:第1章从设计......一起来看看 《深入理解C++11》 这本书的介绍吧!