k8s正迅速成为云计算中部署和管理软件的新标准,那么K8s的容器网络是如何通信的呢?在了解容器网络通信原理之前,重温一下K8s主要组件的定义:
- 节点:是K8s中最小的计算硬件单元。它是集群中单个机器的表示。在大多数生产系统中,节点很可能是数据中心中的物理机器,或者是托管在像阿里云平台这样的云供应商上的虚拟机;
- 容器:在K8s上运行的程序被打包成Linux容器。容器是一个被广泛接受的标准,因此已经有许多预先构建的映像可以部署在K8s上。容器化允许你创建自足式的Linux执行环境。任何程序和它的所有依赖项都可以打包成一个文件,然后在网络上共享。任何人都可以下载该容器并在其基础设施上部署它,所需的设置非常少;
- POD:是K8s中最小的可部署和管理单元。换句话讲,如果需要在K8s中运行单个容器,那么你就得为这个容器创建一个Pod。同时,一个Pod可以包含多个容器,这些容器往往是紧耦合的。怎么样个紧耦合法呢?试着想象这么一个场景,一个Pod中的多个容器代表需要运行在同一个服务器上的多个进程。这种类比是合理的,因为在许多方面,Pod就类似于一台服务器;
- 外部网络:容器应用部署完成后,需要对外提供服务,这里的外部可能是互联网、也可能是内部网络;
那么容器网络是如何实现在:POD内部通信、同节点的POD之间通信、不同节点的POD之间通信、外部网络与POD之间通信的呢?下面我们分别来介绍:
1、pod内部通信
同一Pod中的任何容器都将共享相同的名称空间和本地网络,容器可以很容易地与其他容器在相同的POD中进行通信,k8s中每个Pod中管理着一组容器,这些容器共享同一个网络命名空间,Pod中的每个容器拥有与Pod相同的IP和port地址空间,并且由于他们在同一个网络命名空间,他们之间可以通过localhost相互访问(可见POD内部的通信是不经过数据IP数据通信通信网络的)。
2、同节点的POD之间通信
不同pod之间的通信,就是使用linux虚拟以太网设备或者说是由两个虚拟接口组成的以太网接口对使不同的网络命名空间链接起来,这些虚拟接口分布在多个POD上,通过网桥把不同的POD组成为一个以太网,直接进行二层以太网通信。
3、不同节点的POD之间通信
当跨节点通信时,本节点内无法找到目的POD的MAC地址,则会查找三层路由表转发,这需要依靠不同节点间的网路配置来实现,对于如何来配置网络,k8s在网络这块自身并没有实现网络规划的具体逻辑,而是制定了一套CNI接口规范,开放给社区来实现,目前主流的网络配置方案有:Flannel、weave、calico,Macvlan等,其中Flannel和weave方案都采用VXLAN网络模型,calico采用的BGP三层路由网络模型,Macvlan是Linux自带的虚拟网卡实现简单的二层通信。
4、外部网络与POD之间通信
Pod之间通过他们自己的ip地址进行通信,但是pod的ip地址是不持久的,当集群中pod的规模缩减或者pod故障或者node故障重启后,新的pod的ip就可能与之前的不一样的。所以k8s中衍生出来Service来解决这个问题。k8s中 Service管理了一系列的Pods,每个Service有一个虚拟的ip,要访问service管理的Pod上的服务只需要访问你这个虚拟ip就可以了,这个虚拟ip是固定的,当service下的pod规模改变、故障重启、node重启时候,对使用service的用户来说是无感知的,因为他们使用的service的ip没有变。当数据包到达Service虚拟ip后,数据包会被通过k8s给该servcie自动创建的负载均衡器路由到背后的pod容器。
以上就是K8S容器网络通信的基本原理!