docker bridge 到 k8s pod 跨节点网络通信机制演进
2020 还没来得及品味就即将过去一个季度,愿剩下的时光不被辜负。进入正题,docker container是单进程模式,能够解决一些单一的问题,在现实中,我们常常需要多个进程放在一个「盒子」里、或者多个节点共同完成通信过程,接下来,说下这个过程的网络通信是如何实现的?
[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 模式做详细讲解。
-
docker启动后建立名为docker0的虚拟网桥。 -
容器启动时在主机上创建一对虚拟网卡veth pair设备。这一对虚拟设备完成一组数据完整流通的链路,数据从一个设备进入,从另一个设备出来。容器中重命名为eth0,宿主机上的以veth*显示并插在docker0网桥上。可以通过如下命令查看,docker0上插了 veth42f3f11 和 vethe8589bd 两张虚拟设备,见(a)图。
[root@localhost ~]# brctl show
bridge name bridge id STP enabled interfaces
br-c7c3d1f77969 8000.02429160f0dd no
docker0 8000.02420a13dd3a no veth42f3f11
vethe8589bd
(a)
(b)
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#
如果访问外部网络,也非常简单,数据包先经过docker0网卡,根据宿主机路由规则连接到eth0网卡,转发到外部网络。见(c)图所示。
(c)
docker 在默认网络设置情况下,节点A 的docker0 跟节点B 的docker0 没有任何关联,网络也是不通的,这就导致不能满足我们跨节点通信要求。Kubernetes 的 Pod 又是通过何种方式实现的呢?
3、pod 通信机制
如果要说明 pod 的通信机制,要从一个镜像说起,在 kubectl 安装kubernetes 的时候一定会看到 k8s.gcr.io/pause 这个镜像,不知道有没有疑问,这个到底是干嘛的?其它几个镜像顾名思义,但是这个【暂停】是什么?没错,他就是用来 hold 一个 Pod 内部多个 Container 网络通信。
[root@k8s-client1 ~]# docker ps |grep sp-nginx
e34adacf9be1 0a81924719d1 "/usr/local/nginx/b…" 3 seconds ago Up 2 seconds k8s_sp_nginx-deployment-84b5d9cb66-hkfp6_default_5c27af26-6b7e-11ea-8d03-70fd45ac3f1f_0
f245174b9a51 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)图所示。
4、跨 node pod 通信
跨节点 Pod 通信,相当于创建一个整个集群公用的【 网桥 】然后把集群中所有的 Pod 连接起来,就可以通信了。
(e)
(f)
5、总结
本文由浅到深的讲解了 docker 网络模式实现以及 Kubernetes Pod 跨节点之间通信原理和实现方式。简单介绍了dockers、Kubernetes网络通信方式,其内部通过网卡、回环设备、路由表、iptables等实现,如果你是个喜欢深究的人,可以研究下组网过程。
推荐
原创不易,随手关注或者”在看“,诚挚感谢!
本文分享自微信公众号 - 云原生技术爱好者社区(programmer_java)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
没内鬼,来点干货!volatile和synchronized
题外话 这篇笔记是我《没内鬼》系列第二篇,其实我计划是把设计模式和多线程并发分为两个系列,统一叫《一起学系列》来系统的介绍 相关的知识,但是想到这篇笔记去年就写成了,一直不发心也痒痒,所以整理一番就发出来,希望大家指正~ 另外推荐我上一篇爆文:没内鬼,来点干货!SQL优化和诊断 一起学习,一起进步! volatile关键字 volatile关键字是在一般面试中经常问到的一个点,大家对它的回答莫过于两点: 保证内存可见性 防止指令重排 那为了更有底气,那咱们就来深入看看吧 JMM内存模型 咱们在聊volatile关键字的时候,首先需要了解JMM内存模型,它本身是一种抽象的概念并不真实存在,草图如下: JMM内存模型规定了线程的工作机理:即所有的共享变量都存储在主内存,如果线程需要使用,则拿到主内存的副本,然后操作一番,再放到主内存里面去 这个可以引发一个思考,**这是不是就是多线程并发情况下线程不安全的根源?**假如所有线程都操作主内存的数据,是不是就不会有线程不安全的问题,随即引发下面的问题 为什么需要JMM内存模型 关于这个问题,我感觉过于硬核,我只能简单的想象假如没有JMM,所有线...
- 下一篇
重启了下 Jenkins,踩到了一个深埋多年的坑
问题描述 业务方反馈,Jenkins 上某个 job 没有将 release 版本的组件发布到 maven 私服,以致依赖方无法引用依赖。 了解这个问题的更多信息: 该 job 构建状态为 success,它使用 maven-release-plugin 时,没有将 release 版本的组件发布到 maven 私服,而是将 SNAPSHOT 版本的包发布到 maven 私服,同时 git 仓库的 pom.xml 版本也没升级,但是倒是打了 tag。 初步定位,切换备份 为什么会出现这个问题呢? 回顾最近 对 Jenkins 做的修改,共有两项 曾修改了 maven 工具的位置,难道是这个影响了? 也曾修改了 Jenkins 的 JVM 参数,然后重启了 Jenkins,难道是这个影响了? 理论上,修改maven 工具的位置和修改 Jenkins 的 JVM 参数,和这个没关系的 恢复maven 工具的位置,问题没有解决 恢复 Jenkins 的 JVM 参数,然后重启了 Jenkins,问题依旧 那那到底是什么原因呢?经过一段时间定位,这个奇怪的问题并没有得到解决,一时找不...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- Windows10,CentOS7,CentOS8安装Nodejs环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS8安装Docker,最新的服务器搭配容器使用
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS7安装Docker,走上虚拟化容器引擎之路