k8s网络通信原理
时间:2023-10-11 09:37:00
https://blog.csdn.net/qq_41688840/article/details/108708415
了解和分析Pod中的container容器网络必须首先理解docker容器网络的几种模式和常用用法。然后我们一步一步地用这个问题来验证我们的推断是否正确。
1.docker容器网络模式
1.1 默认bridge桥接网络
默认分配docker0网桥网段ip给容器, 每个容器的network namespace都是相互隔离的。docker自己生成一个veth pair(虚拟网卡对) 一端放在docker0网桥上, 一端放在容器内。
通过docker inspect 容器查看容器网络模式信息:
网络详情:
1.2 共享宿主机host的网络栈
宿主机网络栈 以及端口port范围。
通过docker inspect 容器查看容器网络模式信息:
1.3 container共享模式
它的网络栈可以指定容器容器共享其网络栈。 这类似于上述共享宿主机网络栈 ,不同之处在于,共享的对象只是从宿主机转变为容器。
K8S里面多个container共享一个pod该模式也实现了网络栈和端口范围。 每当一个Pod如果是创建的,首先创建一个 “pause” 容器, 之后这个pod其他容器共享这个pause集装箱网络栈,实现外部pod进行通信 , 然后通过localhost进行pod内部的container的通信。如下图所示:
我们可以找到这种共享模式, 相比bridge有三种桥接模式eth0网卡而言, 只有一个eth0网卡只出现在了"pause容器"里面,nginx和php-fpm复用了"pause容器"的network namespace,使用简单的理解"pause容器"的eth0网卡与外部通信。
通过docker inspect 容器查看容器网络模式信息:
如果NetworkMode是conatiner共享类型,则Networks字段为空。我们应该找到共享。conatiner只能查看详细信息。
1.4 none模式
该模式只分配给容器进行隔离network namespace, 网卡不会分配 ip地址等。假设我们没有手动配置网络信息, 所以这种网络模式下的容器不能上网。 然后这种模式给了我们很大的自由度来配置容器网络, 这意味着我们可以自己配置容器 网卡信息 ip地址等。简单理解,docker给你裸机容器,后面的网卡veth 网卡信息 ip可以自行分配地址等。
网络详情:
docker netwokr ls // 显示当前docker存在的网络模式列表:
k8s网络插件也是基于此进行网络分配的ip地址 网卡等给"pause容器"继续往下看会有详细的分析。
2.举例分析
2.1 验证一个Pod中多个conatiner是否分享这个Pod的ip以及端口范围
运行一个deployemnt, 这个deployment里面的Pod运行三个容器:
nginx
busybox
php-fpm
用这个例子类来验证K8S容器之间的通信和使用docker网络模式是否与上述预期一致。
docker ps 看到这个pod运行了4个容器:
第一个: 8bf44ff2b133是Pod里面运行的php容器
第二个: 2e10bc93d413是这个Pod的nginx容器
第三个: ed2fc5bf201e 是这个Pod的busybox容器
第四个: 9bafb86e521c 是这个Pod的pause容器
我们分别进入这个3容器查看分布的内部eth0的ip地址:
php-fpm容器内部ip信息: 10.244.0.34
nginx容器内部ip信息: 10.244.0.34
busybox容器内部ip信息: 10.244.0.34
我们在三个容器容器内部ip地址一样, 现在来看看K8S Pod分配的ip是否也与上述三个容器内部相匹配?ip地址一样?
完全一致。这也证实了同一个。Pod里面有很多container共享这个Pod的ip地址。 事实上,共享可以再次验证Pod端口范围, 在这个Pod再运行一个nginx容器会报错。 80端口已被占用 , 第二个再操作nginx默认还是监听80端口,所以报错了 ,你可以自己试试。
2.2 验证多个container是否是共享了pause容器的network namespace?
pause容器的id简写是: 9bafb86e521c
分别执行docker inspect -f ‘{undefined{.HostConfig.NetworkMode}}’ 以上三个容器(NetworkMode)这个字段可以看到当前容器的网络模式:
php容器docker inspect:
现在可以看到这个php容器的networkMode使用的是 "容器共享network namespace"的模式, 下面的容器是共享的network namepsace
container: 9bafb86e521c43d9cc33757ecef2d4ef8342c17cce032fabe0c9d7a543ac7960
nginx容器inspect:
container: 9bafb86e521c43d9cc33757ecef2d4ef8342c17cce032fabe0c9d7a543ac7960
busybox容器inspect:
container: 9bafb86e521c43d9cc33757ecef2d4ef8342c17cce032fabe0c9d7a543ac7960
由此可见 这3个container的都采用了"共享conatiner network namespace"与外部通信的模式。 这个共享的容器是Pod里面的pause容器。
2.3 在busybox在容器中检查端口监管情况
由此看出,busybox以及nginx php-fpm 3个容器通过localhost通信, 并分享这一点Pod其实端口的范围也会是"pause容器"的ip和端口范围。(K8S中的Pod只是逻辑概念, 这四个容器逻辑上形成了逻辑Pod,这一点要明确,底层只是一个容器)。
2.4 查看pause容器网络模式
现在我们来看看"pause容器"的docker inspect 详细信息:
我们现在发现了这个puase使用的docker网络模式是:
none类型和模型id是
9b9cd04e8d5742aaea058d8d72a450641058cbd71e13219c17564960b7b3c747
查看当前docker的网络模式列表:
docker network ls
1
1
2
9b9cd04e8d57 这种网络模式是none类型。
两者一致。
3.总结
(使用本环境flannel网络插件).由此验证K8S管理网络插件ip地址分配和veth pair(虚拟网卡对)和网桥连接, pause容器采用了docker的none网络模式, 再次使用网络插件ip和veth虚拟网卡分配Pod的pause容器, 重复使用其他容器"共享container"的网络模式来共享这个pause网络可以与外部通信。
k8s只是提供了CNI只要任何接口overlay网络分配解决方案或具体实现屏蔽了底层网络分配的实现,只要对接或实现CNI接口规范,那么k8s这个插件可以用k8s中的pod网络配置。市场上有一些常见的CNI插件例如Flannel, Calico等。
————————————————
版权声明:本文为CSDN博主「柯南二号」遵循原创文章CC 4.0 BY-SA版权协议,请附上原始来源链接和本声明。
原文链接:https://blog.csdn.net/qq_41688840/article/details/108708415