【Docker】单机容器网络的实现原理

近期在复习容器网络的相关知识,将单机容器网络到跨主机网络通信的实现方法做以总结。

这里是第一篇,后面还会发布其他笔记:

跨主通信实现方法:UDPVXLANhost-gw

不同容器具有不同namespace,位于同一个宿主机上的不同容器进行通信时,相当于不同namespace之间通信,需要借助一个设备将二者联系起来,docker0网桥就有这个作用,有了docker0网桥,还需要与容器联系起来, 我们就需要虚拟设备 veth pair,Veth Pair 常常被用作连接不同 Network Namespace 的“网线”,一端在容器上,一端插在网桥上,docker0网桥位于宿主机的名称空间内,与容器的名称空间分隔开来。

现考虑以下两个场景下的数据包传输过程:

1:当宿主机上的进程需要访问容器container1内应用时,数据包传输过程如下图中红色线条所示:数据包先到达宿主机名称空间内的docker0上,然后再转发到对应的veth pair设备上,最后出现在目标容器上。

同时docker0在转发过程中,还扮演了二层交换机的角色,docker0 网桥根据数据包的目的 MAC 地址,在它的 CAM 表(即交换机通过 MAC 地址学习维护的端口和 MAC 地址的对应表)里查到对应的端口,然后把数据包发往这个端口。这就是为什么docker0不会把数据包转发给container2对应的veth pair设备。也正是因为docker0可以作为二层交换机的这个原因,使得同一宿主机上的两个容器默认就是相互连通的(联想二层网络里的各个主机之间的通信,只要发送ARP报文就知道对方MAC地址了)。

这里所述的端口就是Veth pair设备插到docker0上的那一端,由于一旦一张虚拟网卡被“插”在网桥上,它就会变成该网桥的“从设备”。从设备会被“剥夺”调用网络协议栈处理数据包的资格,从而“降级”成为网桥上的一个端口。而这个端口唯一的作用,就是接收流入的数据包,然后把这些数据包的“生杀大权”(比如转发或者丢弃),全部交给对应的网桥。

2:当宿主机X上的容器需要访问宿主机Y上的应用时,数据包传输过程如下图中绿色线条所示:

数据包首先根据路由规则出现在Docker0网桥上,然后根据宿主机的路由表规则,将数据包给宿主机的eth0网卡设备,然后数据包经过Node X的eth0设备的转发到达Node Y上。但这个需要两个节点是能够通信的,因此在发现宿主机容器联不通外网时,应该先检查,容器和Docker0网桥是否正常通信,再检查docker0和veth pair相关的iptables规则是否设置错误。

总结:单机容器网络的实现原理

容器要想跟外界进行通信,它发出的 IP 包就必须从它的 Network Namespace 里出来,来到宿主机上。而解决这个问题的方法就是:为容器创建一个一端在容器里充当默认网卡、另一端在宿主机上的 Veth Pair 设备。

后记:本文是学习课程极客时间-张磊:《深入剖析Kubernetes》进行的总结笔记。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值