k8s---深入解析容器跨主机网络

k8s—深入解析容器跨主机网络

请大佬收下我虔诚的仰视

容器跨主通信的原理,从Flannel项目说起,Flannel项目只是一个框架,真正提供容器网络功能的是Flannel的后端实现。目前Flannel支持3种后端实现。
1.vxlan。
2.host-gw
3.udp
udp模式。性能最差。最早支持;整个模式已经被 弃用;但是最容易理解;
模拟环境:node1上container1.ip 1.2.docker0网桥地址1.1/24
node2.container2.ip 2.3 docker0网桥地址:2.1/24
从1.2.ping数据包到2.3。跨主机通信。
1.2里的进程发起的ip包。原地址src1.2.dest2.3.dest地址并不在node1的docker0。因此这个包会交给默认路由规则,通过容器的网关进入docker0网桥。从而出现到了宿主机上,此时这个ip地址下一个目的地地址就取决于宿主机的路由规则,此时Flannel就会在宿主机上创建一系列的路由规则;在node1上会匹配到node2的路由规则段。从而进入一个flannel0的设备中。这个设备是一个tun设备;
在linux中tun设备是一种三层工作的虚拟网络设备,tun设备的作用是在操作系统内核和用户应用程序之间传递ip包
当操作系统将ip包发送到flannel0设备之后,flannel0设备就会将这个包交给创建这个设备的应用程序,也就是flanel进程。这是一个内核态到用户态的流动方向;flanel进程收到这个ip包。看到整个ip包的目的地址时2.3.就会把它发送给node2.。flaneld如何知道2.3在node2上呢。
用到一个flanel非常重要的概念。子网subnet。在Flannel管理的容器网络中。一台宿主机上的所有容器都属于该宿主机被分配的一个子网,node1的子网1.0/24.。node2上的子网2.0/24.。这些子网和宿主机的对应关系时保存在etcd中的。当flaneld进程处理flanel0设备传入的ip包的时候就根据destip的地址。匹配到对应的子网。2.0/24.从etcd中找到整个子网对应的宿主机的ip地址时node2的地址。就可以通过上述的node2的ip地址访问到node2.这样就传递到了node2上;
Flanneld进程收到container1发给container2的ip包之后,就会将整个ip包直接封装在一个udp包里,然后发给udp。这个封装的udp包src时flaneld所在的node1的地址,dest是node2的地址;
flaneld进程监听8285端口;
所以udp包发送到node2的8285端口就可以了;然后flaneld将ip包发送给他所管理的tun设备,所以将ip包发送给tun设备。这是用户态到内核态的过程。linux内核网络栈就会负责整个ip包。具体做法通过本机的路由表找到ip包的下一步流向;匹配到路由表规则流向对应网络设备。container2是在node2的docker0网桥上的。所以流向docker0网桥。通过veth再流向容器container2的内部;这样container2就接收到了ip包;
在这里插入图片描述
Flannel UDP模式提供的其实是一个三层的覆盖网络,首先他对发出的ip包进行udp封装,然后在接收端进行解封装拿到原始的ip包,接着将ip包转发到目的容器。这相当于Flannel在不同宿主机之间打通了一条tun隧道。使得这两个容器可以直接使用ip地址进行通讯。而无需关心容器和宿主机之间的分布情况;
udp一个严重的性能问题。就是它多了一个额外的步骤,flaneld的处理过程。用到了flanel0设备,在此过程中,发出ip包的过程中需要经过3此用户态和内核态的数据复制。
第一次,容器态的容器进程发出ip包经过docker0网桥进入内核态,容器用户态进入内核态;
第二次,ip包根据路由表进入tun。flanel0设备,内核态进入用户态;
第三次,flaneld进程进行udp封包后重新进入内核态,将udp包通过宿主机eth0发出去;
此外。flanel进行udp封装和解封装都是在用户态完成的。llinux系统中上下文切换和用户态内核态的切换操作的代价较高。这是造成Flannel UDP模式性能不佳的主要原因;

2.VXLAN模式。–这是linux内核本身就支持的一种网络虚拟化技术。vxlan可以完全在内核态完成封装和解封账的工作。从而通过前面的tun机制构建出覆盖网络overlay
为了能在二层网络上打通隧道,vxlan会在宿主机上设备一个特殊的网络设备作为隧道的两端。整个设备叫做vtep。vtep设备作用跟之前的flaneld进程非常相似,
在这里插入图片描述
图中。每台宿主机上的鸣叫flanel.1的设备就是所需的vtep设备,他既有ip地址,又有mac地址;
现在container1的ip 1.2.发出请求。dest地址时2.3.container容器进程发出请求。通过vth到到docker0网桥,然后被路由表路由到flanel.1设备进行处理。flanel.1设备需要找到ip包dest的出口。也就是目的宿主机vtep设备;这个设备的信息正式由每台宿主机的flaneld进程维护的;
当node2启动加入flanel网络之后,在node1以及其他节点上。flaneld就会增加一条达到node2节点的路由规则;路由规则都会经过flanel.1设备。并且最后发往的 吓一跳的地址时node2的vtep设备,即node2的flanel.1设备的ip地址;这样node1的vtep时源vtep设备。node2的vtep设备是目的vtep设备;
源vtep设备收到ip包就想办法给ip包加上一个目的mac地址。封装成一个二层数据帧,然后发送到目的vtep设备。这个目的mac地址要根据三层ip地址查询对应的mac地址。这是arp表的功能。这里的arp表记录是flaneld进程启动时自动添加到node上的;有了这个mac地址就可以进行二层封包工作了。封装完成就是一个内部数据帧。
接下来linux内核还需要将内部数据帧进一步封装成宿主机网络里的普通数据帧,好让他载着内部数据帧通过eth0网卡进行传输;这种宿主机对应的数据帧称之为外部数据帧;
为实现搭便车。linux内核会在内部数据帧的加上一个特殊的vxlan头。标识这是vxlan要使用的数据帧。这个头里有个重要的标志叫做vni。整个vni的值默认是1.这也是为什么vtep设备叫做flanel.1的原因;这里的1其实时vni的值;
然后linux内核会将这个数据帧封装进udp包发出去;这个udp的目的地址数据时通过一个FDB的转发数据库来获取的;fdb信息是flanneld进程负责维护的。

----这里都把我转晕了。。
反正就是内部封装。然后外部封装。然后udp封装传递到node2上。node2的网络栈进行解封装。传递到node2的docker0再到容器内;

–大佬是真的太强了!!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值