Kubernetes之POD、容器之间的网络通信

前言Kubernetes(简称K8S)是开源的容器集群管理系统 , 可以实现容器集群的自动化部署、自动扩缩容、维护等功能 。它既是一款容器编排工具 , 也是全新的基于容器技术的分布式架构领先方案 。在Docker技术的基础上 , 为容器化的应用提供部署运行、资源调度、服务发现和动态伸缩等功能 , 提高了大规模容器集群管理的便捷性 。
基础概念ContainerContainer(容器)是一种便携式、轻量级的操作系统级虚拟化技术 。它使用 NameSpace 隔离不同的软件运行环境 , 并通过镜像自包含软件的运行环境 , 从而使得容器可以很方便的在任何地方运行 。由于容器体积小且启动快 , 因此可以在每个容器镜像中打包一个应用程序 。一对一的关系
PODKubernetes 使用 Pod 来管理容器 , 每个 Pod 可以包含一个或多个紧密关联的容器 。一对多的关系

Kubernetes之POD、容器之间的网络通信

文章插图
 
NodeNode 是 Pod 真正运行的主机 , 可以是物理机 , 也可以是虚拟机 , 也称为宿主机 。为了管理 Pod , 每个 Node 节点上至少要运行docker 、kubelet 服务 。
Kubernetes之POD、容器之间的网络通信

文章插图
 
NamespaceNamespace 是对一组资源和对象的抽象集合 , 比如可以用来将系统内部的对象划分为不同的项目组或用户组 。常见的 pods, services, replication controllers 和 deployments 等都是属于某一个 namespace 的(默认是 default) , 而 node, persistentVolumes 等则不属于任何 namespace
ServiceService 是应用服务的抽象 , 通过 labels 为应用提供负载均衡和服务发现 。匹配 labels 的 Pod IP 和端口列表组成 endpoints , 由 kube-proxy 负责将服务 IP 负载均衡到这些 endpoints 上
网络通讯方式了解了上面的基本概念后 , 我们考虑一下K8s集群中docker容器之间是如何通讯的?我们这里需要区分一下不同的场景
1)在同一个POD上Container通信
2)同一个Node,不同POD
3)不同Node , 不同POD
我们先来看看上面的不同场景是怎么通信的
同一个POD上Container通信在k8s中每个Pod中管理着一组Docker容器 , 这些Docker容器共享同一个网络命名空间 , Pod中的每个Docker容器拥有与Pod相同的IP和port地址空间 , 并且由于他们在同一个网络命名空间 , 他们之间可以通过localhost相互访问 。
什么机制让同一个Pod内的多个docker容器相互通信?就是使用Docker的一种网络模型:–net=container
container模式指定新创建的Docker容器和已经存在的一个容器共享一个网络命名空间 , 而不是和宿主机共享 。新创建的Docker容器不会创建自己的网卡 , 配置自己的 IP , 而是和一个指定的容器共享 IP、端口范围等
在k8s中每个Pod容器有一个pause容器有独立的网络命名空间 , 在Pod内启动Docker容器时候使用 –net=container就可以让当前Docker容器加入到Pod容器拥有的网络命名空间(pause容器)
Kubernetes之POD、容器之间的网络通信

文章插图
 
这里就是为什么k8s在调度pod时 , 尽量把关系紧密的服务放到一个pod中 , 这样网络的请求耗时就可以忽略 , 因为容器之间通信共享了网络空间 , 就像local本地通信一样 。
同一个Node , 不同Pod
Kubernetes之POD、容器之间的网络通信

文章插图
 

Kubernetes之POD、容器之间的网络通信

文章插图
 
上图就是同一个node , 不同pod之间的通信 , 就是使用linux虚拟以太网设备或者说是由两个虚拟接口组成的veth对使不同的网络命名空间链接起来 , 这些虚拟接口分布在多个网络命名空间上(这里是指多个Pod上) 。
通过网桥把veth0和veth1组成为一个以太网 , 他们直接是可以直接通信的 , 另外这里通过veth对让pod1的eth0和veth0、pod2的eth0和veth1关联起来 , 从而让pod1和pod2相互通信 。
不同Node , 不同Pod
Kubernetes之POD、容器之间的网络通信

文章插图
 
上图就是不同node之间的pod通信 , Node1中的Pod1如何和Node2的Pod4进行通信的 , 我们来看看具体流程:


推荐阅读