前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >docker bridge 到 k8s pod 跨节点网络通信机制演进

docker bridge 到 k8s pod 跨节点网络通信机制演进

作者头像
用户5166556
发布2020-04-22 15:04:54
2K0
发布2020-04-22 15:04:54
举报

2020 还没来得及品味就即将过去一个季度,愿剩下的时光不被辜负。进入正题,docker container是单进程模式,能够解决一些单一的问题,在现实中,我们常常需要多个进程放在一个「盒子」里、或者多个节点共同完成通信过程,接下来,说下这个过程的网络通信是如何实现的?

1、docker 网络模式

可以通过如下命令行查看docker网络模式

代码语言:javascript
复制
[root@localhost ~]# docker network ls
NETWORK ID          NAME                 DRIVER              SCOPE
c250329fad3c        bridge               bridge              local
c7c3d1f77969        compose_extnetwork   bridge              local
199b85fbf2fa        host                 host                local
b488be9da3d6        none                 null                local
  • 共享主机网络模式 - host

host指的是共享主机的网络和端口,但是破坏了 container 的隔离性;

  • 无网络模式 - none

其中无网络模式是指加入此模式下的容器都不能通信,比较鸡肋;

  • 自定义

自定义主要用于实现DNS解析和服务发现,特殊场景下定制使用;

  • 默认网络模式 - bridge

网桥是 docker 默认网络模式,也是平时用的最多的一种,这里主要对 docker 的 bridge 模式做详细讲解。


2、docker 桥接如何实现同一个宿主机不同容器之间的通信

       其实主要用到两个技术知识点:

  • docker启动后建立名为docker0的虚拟网桥。
  • 容器启动时在主机上创建一对虚拟网卡veth pair设备。这一对虚拟设备完成一组数据完整流通的链路,数据从一个设备进入,从另一个设备出来。容器中重命名为eth0,宿主机上的以veth*显示并插在docker0网桥上。可以通过如下命令查看,docker0上插了 veth42f3f11 和 vethe8589bd 两张虚拟设备,见(a)图。
代码语言:javascript
复制
[root@localhost ~]# brctl show
bridge name  bridge id    STP enabled  interfaces
br-c7c3d1f77969    8000.02429160f0dd  no      
docker0    8000.02420a13dd3a  no    veth42f3f11
                            vethe8589bd

(a)

那么你可能会有疑问,多个容器之间又是如何通信的呢?如下图所示:

(b)

其原理也非常简单,如图(b)所示,container1 ping container2(172.0.0.3)网络时,同一宿主机中的两个容器网络默认是互通的,其中docker0扮演二层交换机的角色。

通过命令查看container路由信息表,如下所示:

代码语言:javascript
复制
bash-4.4# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         172.17.0.1      0.0.0.0         UG    0      0        0 eth0
172.17.0.0      *               255.255.0.0     U     0      0        0 eth0
bash-4.4#

container1 访问172.17.0.3匹配到第二条路由规则;网关是0.0.0.0,这是一条直连规则,意思是匹配到该规则的网络地址经过本机eth0网卡,再通过二层网络doceker0 直接发送到目的主机。docker0之所以能够做到从veth虚拟设备中接受数据和发送数据,是因为veth相当于docker0网桥的从设备,故docker0能够直接处理来自于veth上网络数据包,进而直接转发到container2,就完成从一个容器到另外一个容器的通信。见(b)图所示。

如果访问外部网络,也非常简单,数据包先经过docker0网卡,根据宿主机路由规则连接到eth0网卡,转发到外部网络。见(c)图所示。

(c)

docker 在默认网络设置情况下,节点A 的docker0 跟节点B 的docker0 没有任何关联,网络也是不通的,这就导致不能满足我们跨节点通信要求。Kubernetes 的 Pod 又是通过何种方式实现的呢?


3、pod 通信机制

如果要说明 pod 的通信机制,要从一个镜像说起,在 kubectl 安装kubernetes 的时候一定会看到 k8s.gcr.io/pause 这个镜像,不知道有没有疑问,这个到底是干嘛的?其它几个镜像顾名思义,但是这个【暂停】是什么?没错,他就是用来 hold 一个 Pod 内部多个 Container 网络通信。

如果在计算节点上运行 docker ps 命令

代码语言:javascript
复制
[root@localhost ~]# docker network ls
NETWORK ID          NAME                 DRIVER              SCOPE
c250329fad3c        bridge               bridge              local
c7c3d1f77969        compose_extnetwork   bridge              local
199b85fbf2fa        host                 host                local
b488be9da3d6        none                 null                local

如上所示,你可以看到在创建 nginx pod 过程中,不仅创建了一个nginx 容器,并附带了一个 pause 容器,而且 pause 容器是在 nginx容器之前创建的,这个被暂停的容器把所有的容器收纳到一起,一个基础容器,唯一目的就是保存所有的命名空间。容器中 pod 共享同一个 IP 地址。故同一个 Pod 中 Container 可以做到直接通过 localhost 直接通信,那么同一个节点多个 Pod 之间如何通信的呢?

(d)

pause 容器启动之前,会为容器创建虚拟一对 ethernet 接口,一个保留在宿主机 vethxxx(插在网桥上),一个保留在容器网络命名空间内,并重命名为eth0。两个虚拟接口的两端,从一端进入,另一端出来。任何 Pod 连接到该网桥的 Pod 都可以收发数据。如(d)图所示。


4、跨 node pod 通信

跨节点 Pod 通信,相当于创建一个整个集群公用的【 网桥 】然后把集群中所有的 Pod 连接起来,就可以通信了。

(e)

其中跨整个集群的 Pod ip 是唯一的,当报文从一个节点转发到另外一个节点时,报文首先通过 veth,然后通过网桥,转发到物理适配器网卡,最后转发到其它节点的虚拟网桥,进而到达 veth 目标容器。如(e)图所示。

其实现方式有 Flannel、calico、weave 等。

注意 k8s 的网桥跟 docker0  网桥功能类似,但是 k8s 并没有复用 docker0 网桥,其原因是 Kubernetes 为了连接 infra 容器更加方便,而是重新实现了 CNI 网络接口功能,它允许网络插件使用 CNI 接口,比如 flannel,它本身实现也经过几个过程,其本质上来说,是基于「隧道」机制实现。示意图(f)所示:

(f)

5、总结

本文由浅到深的讲解了 docker 网络模式实现以及 Kubernetes Pod 跨节点之间通信原理和实现方式。简单介绍了dockers、Kubernetes网络通信方式,其内部通过网卡、回环设备、路由表、iptables等实现,如果你是个喜欢深究的人,可以研究下组网过程。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-03-22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器镜像服务
容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档