容器跨主机网络

本文以flannel项目UDP模式举例

Flannel

Flannel支持多种后端实现,包括:VXLAN、host-gw、UDP、gce、ali-vpc等

UDP模式性能最差,目前已被启用,但最易理解,以下使用UDP模式理解跨主机网络实现原理

示例

现有两台宿主机:Node1、Node2
Node1上有一个容器container1,container1的ip地址为100.96.1.2,对应docker0网桥的地址为100.96.1.1/24
Node2上有一个容器container2,container2的ip地址为100.96.2.3,对应docker0网桥的地址为100.96.2.1/24
(docker0网桥地址可通过daemon.json中bip进行配置)
现在需要让container1访问container2

流程

container1容器发出的IP包源地址为100.96.1.2,目的地址为100.96.2.3,因为目的地址不在docker0网段中,所以不走直连规则,而是会被交给默认规则,通过容器的网关进入docker0网桥(可进入容器使用ip route查看路由规则),从而出现在宿主机上,此时IP包的下一个目的地,取决于宿主机的路由规则,这些路由规则会由flannel来创建,在Node1上用ip route查看

default via 10.168.0.1 dev eth0
100.96.0.0/16 dev flannel0 proto kernel scope link src 100.96.1.0
100.96.1.0/24 dev docker0 proto kernel scope link src 100.96.1.1
10.168.0.0/24 dev eth0 proto kernel scope link src 10.168.0.2

目的地址为100.96.2.3,匹配不到docker0对应的100.96.1.0/24网段,所以会走100.96.0.0/16这条路由规则,从而进入到一个叫flannel0的设备中,这个flannel0是一个Tunnel设备

Tunnel设备
Tunnel设备是一种工作在三层的虚拟网络设备,功能为:在操作系统内核和用户应用程序直接传递IP包

以flannel0设备为例
当操作系统将一个IP包发送给flannel0设备之后,flannel0就会把这个IP包交给创建这个设备的应用程序,也就是Flannel进程(这是一个从内核态到用户态的流动方向)。当Flannel进程向flannel0设备发送一个IP包,那么这个IP包就会出现在宿主机网络协议栈,然后根据宿主机的路由表进行下一步处理(这是用户态向内核态的流动方向)。
所以,当IP包从容器经过docker0出现在宿主机,然后根据路由表进入flannel0设备后,宿主机的flanneld进程就会收到这个这个IP包,然后flanneld看到这个IP包的目的地址为100.96.2.3,就会把这个IP包发送给Node2主机。

flanneld如何知道这个IP地址对应的容器是在Node2上呢?需要知道一个概念子网
子网:在flannel管理的容器网络里,一台宿主机上的所有容器,都属于该宿主机被分配的一个子网,这些子网与宿主机的对应关系,被保存在了etcd中,只要知道该目的地址属于哪个子网,就能知道该目的地址的容器在哪台宿主机上。

flanneld 在收到 container-1 发给 container-2 的 IP 包之后, 就会把这个 IP 包直接封装在一个 UDP 包里,然后发送给 Node 2 。这个 UDP 包的源地址就是 flanneld 所在的 Node 1 的地址, 目的地址, 则是 container-2 所在的宿主机 Node 2 的地址。这个请求得以完成的原因是,每台宿主机上的 flanneld ,都监听着一个 8285 端口,所以 flanneld 只要把 UDP 包发往 Node 2 的 8285端口即可。通过这样一个普通的、宿主机之间的 UDP 通信,一个 UDP 包就从 Node1 到达了 Node 2 。而 Node 2 上监听 8285 端口的进程也是 flanneld ,所以这时候, flanneld 就可以从这个 UDP 包里解析出封装在里面的、container-1 发来的原 IP 包,然后flanneld 会直接把这个 解析出来的源IP 包发送给它所管理的 TUN 设备,即 flannel0 设备,然后根据路由表来寻找这个IP包的下一步流向,此时在Node2的路由表为:

default via 10.168.0.1 dev eth0
100.96.0.0/16 dev flannel0 proto kernel scope link src 100.96.2.0
100.96.2.0/24 dev docker0 proto kernel scope link src 100.96.2.1
10.168.0.0/24 dev eth0 proto kernel scope link src 10.168.0.3

目的地址为100.96.2.3,与100.96.2.0/24更精确匹配,所以会将这个IP包转发给docker0,然后到达目的容器。

上面流程得以实现的一个前提为docker0网桥的地址范围必须是flannel为宿主机分配的子网,可以使用bip进行配置

UDP模式性能问题

flannel UDP模式容器通信时多了一个额外的步骤,由于使用了flannel0这个TUN设备,仅在发包的过程中就需要经过三次用户态到内核态的数据拷贝
第一次:IP包从容器进程进入docker0网桥(用户态到内核态)
第二次:IP包根据路由表进入TUN(flannel0)设备从而回到用户态的flanneld进程(内核态到用户态)
第三次:flanneld进行UDP封装后重新进入内核态,通过eth0将UDP包发出

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值