2020 还没来得及品味就即将过去一个季度,愿剩下的时光不被辜负。进入正题,docker container是单进程模式,可以解决一些单一的问题,在现实中,咱们经常须要多个进程放在一个「盒子」里、或者多个节点共同完成通讯过程,接下来,说下这个过程的网络通讯是如何实现的?
css
[root@localhost ~]# docker network lsNETWORK ID NAME DRIVER SCOPEc250329fad3c bridge bridge localc7c3d1f77969 compose_extnetwork bridge local199b85fbf2fa host host localb488be9da3d6 none null local
共享主机网络模式 - hostjava
host指的是共享主机的网络和端口,可是破坏了 container 的隔离性;node
无网络模式 - nonenginx
其中无网络模式是指加入此模式下的容器都不能通讯,比较鸡肋;web
自定义docker
自定义主要用于实现DNS解析和服务发现,特殊场景下定制使用;bash
默认网络模式 - bridge微信
网桥是 docker 默认网络模式,也是平时用的最多的一种,这里主要对 docker 的 bridge 模式作详细讲解。网络
-
docker启动后创建名为docker0的虚拟网桥。 -
容器启动时在主机上建立一对虚拟网卡veth pair设备。这一对虚拟设备完成一组数据完整流通的链路,数据从一个设备进入,从另外一个设备出来。容器中重命名为eth0,宿主机上的以veth*显示并插在docker0网桥上。能够经过以下命令查看,docker0上插了 veth42f3f11 和 vethe8589bd 两张虚拟设备,见(a)图。
[root@localhost ~]# brctl showbridge name bridge id STP enabled interfacesbr-c7c3d1f77969 8000.02429160f0dd no docker0 8000.02420a13dd3a no veth42f3f11 vethe8589bd

(a)
(b)
架构
bash-4.4# routeKernel IP routing tableDestination Gateway Genmask Flags Metric Ref Use Ifacedefault 172.17.0.1 0.0.0.0 UG 0 0 0 eth0172.17.0.0 * 255.255.0.0 U 0 0 0 eth0bash-4.4#
若是访问外部网络,也很是简单,数据包先通过docker0网卡,根据宿主机路由规则链接到eth0网卡,转发到外部网络。见(c)图所示。
(c)
docker 在默认网络设置状况下,节点A 的docker0 跟节点B 的docker0 没有任何关联,网络也是不通的,这就致使不能知足咱们跨节点通讯要求。Kubernetes 的 Pod 又是经过何种方式实现的呢?
三、pod 通讯机制
若是要说明 pod 的通讯机制,要从一个镜像提及,在 kubectl 安装kubernetes 的时候必定会看到 k8s.gcr.io/pause 这个镜像,不知道有没有疑问,这个究竟是干吗的?其它几个镜像顾名思义,可是这个【暂停】是什么?没错,他就是用来 hold 一个 Pod 内部多个 Container 网络通讯。
[root@k8s-client1 ~]# docker ps |grep sp-nginxe34adacf9be1 0a81924719d1 "/usr/local/nginx/b…" 3 seconds ago Up 2 seconds k8s_sp_nginx-deployment-84b5d9cb66-hkfp6_default_5c27af26-6b7e-11ea-8d03-70fd45ac3f1f_0f245174b9a51 0a81924719d1 "/usr/local/nginx/b…" 5 seconds ago Up 4 seconds k8s_sp_nginx-deployment-84b5d9cb66-zfbhr_default_5c281ef0-6b7e-11ea-8d03-70fd45ac3f1f_0
如上所示,你能够看到在建立 nginx pod 过程当中,不只建立了一个nginx 容器,并附带了一个 pause 容器,并且 pause 容器是在 nginx容器以前建立的,这个被暂停的容器把全部的容器收纳到一块儿,一个基础容器,惟一目的就是保存全部的命名空间。容器中 pod 共享同一个 IP 地址。故同一个 Pod 中 Container 能够作到直接经过 localhost 直接通讯,那么同一个节点多个 Pod 之间如何通讯的呢?
(d)
pause 容器启动以前,会为容器建立虚拟一对 ethernet 接口,一个保留在宿主机 vethxxx(插在网桥上),一个保留在容器网络命名空间内,并重命名为eth0。两个虚拟接口的两端,从一端进入,另外一端出来。任何 Pod 链接到该网桥的 Pod 均可以收发数据。如(d)图所示。
四、跨 node pod 通讯
跨节点 Pod 通讯,至关于建立一个整个集群公用的【 网桥 】而后把集群中全部的 Pod 链接起来,就能够通讯了。
(e)
(f)
五、总结
本文由浅到深的讲解了 docker 网络模式实现以及 Kubernetes Pod 跨节点之间通讯原理和实现方式。简单介绍了dockers、Kubernetes网络通讯方式,其内部经过网卡、回环设备、路由表、iptables等实现,若是你是个喜欢深究的人,能够研究下组网过程。
推荐
原创不易,随手关注或者”在看“,诚挚感谢!
本文分享自微信公众号 - 云原生技术爱好者社区(programmer_java)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。