容器之间网络通信原理
docker中
容器本质上 = namespace + cgroups + aufs
linux内核提供的namepspace功能,namespace不是聚合的 而是按照类型分开的:
docker创建容器的时候 像IPC这种ns是容器独有的 而network这种却是容器共享的
docker提供了一整套名为network的系统和命令来使用。
你可以使用 docker network create
命令创建一个自定义网络,然后将需要通信的容器连接到这个网络。在同一个网络中的容器可以使用容器名进行通信。
# 创建一个自定义网络
docker network create my-network
# 运行第一个容器,并连接到自定义网络
docker run -d --name container1 --network my-network my-image
# 运行第二个容器,并连接到自定义网络
docker run -d --name container2 --network my-network my-image
所以不同的容器才能通过这种方式进行通信 所以容器内的nginx才能顺利找到halo 因为本质上此时网络没有被虚拟化 他们这两个容器看到的是同一套网络。
Kubernetes中
在 Kubernetes 的 Pod 中,每个容器实际上共享的是网络命名空间。这意味着 Pod 中的所有容器都能够使用相同的网络接口和 IP 地址,它们之间可以通过 localhost
直接通信,并且共享端口空间。这种设计允许 Pod 内的容器像在同一台主机上运行的进程一样进行通信,无需担心网络隔离或端口冲突问题 。
在 Kubernetes 中,Pod 容器共享网络命名空间的实现主要依赖于一个特殊的容器——pause
容器(也称为 Infra 容器)。当一个 Pod 被创建时,Kubernetes 会首先启动这个 pause
容器,并在这个容器中初始化网络命名空间。随后,Pod 中的其他容器会加入到这个已经存在的网络命名空间中,共享 pause
容器的网络栈。
pause
容器在整个 Pod 生命周期中扮演着关键角色。它不仅负责创建和持有网络命名空间,还充当 PID 1 的角色,负责收集任何成为僵尸的子进程,确保 Pod 的健康运行。此外,pause
容器的存在使得即使 Pod 中的一个容器崩溃,其余容器仍然可以响应网络请求,因为它们仍然共享相同的网络命名空间。
在网络层面,Pod 内的容器共享相同的 IP 地址和端口空间,可以通过 localhost
直接进行相互访问。这种设计允许 Pod 内的容器像在同一台主机上运行的进程一样进行通信,无需担心网络隔离或端口冲突问题。
Kubernetes 网络模型确保每个 Pod 都有一个唯一的 IP 地址,并且 Pod 内的容器能够通过这个 IP 地址进行通信。这种模型支持 Pod 内容器的高效协同工作,同时保持了容器间的低耦合性。此外,Kubernetes 使用容器网络接口(CNI)插件来处理 Pod 之间的路由流量、负载平衡,并确保整个集群的无缝通信。