浅析Kubernetes网络模型

通过我们对各种容器网络模型的实现原理已经有了基本的认识,然而真正将容器技术发扬光大的是Kubernetes容器编排平台 。Kubernetes通过整合规模庞大的容器实例形成集群,这些容器实例可能运行在异构的底层网络环境中,如何保证这些容器间的互通是实际生产环境中首要考虑的问题之一 。
Kubernetes网络基本要求Kubernetes对容器技术做了更多的抽象,其中最重要的一点是提出pod的概念,pod是Kubernetes资源调度的基本单元,我们可以简单地认为pod是容器的一种延伸扩展,从网络的角度来看,pod必须满足以下条件:

  1. 每一个Pod都有一个独特的IP地址,所有pod都在一个可以直接连通的、扁平的网络空间中
  2. 同一个pod内的所有容器共享同一个netns网络命名空间

浅析Kubernetes网络模型

文章插图
 
基于这样的基本要求,我们可以知道:
  1. 同一个pod内的所有容器之间共享端口,可直接通过localhost+端口来访问
  2. 由于每个pod有单独的IP,所以不需要考虑容器端口与主机端口映射以及端口冲突问题
事实上,Kubernetes进一步确定了对一个合格集群网络的基本要求:
  1. 任意两个pod之间其实是可以直接通信的,无需显式地使用NAT进行地址的转换;
  2. 任意集群节点node与任意pod之间是可以直接通信的,无需使用明显的地址转换,反之亦然;
  3. 任意pod看到自己的IP跟别人看见它所用的IP是一样的,中间不能经过地址转换;
也就是说,必须同时满足以上三点的网络模型才能适用于kubernetes,事实上,在早期的Kubernetes中,并没有什么网络标准,只是提出了以上基本要求,只有满足这些要求的网络才可以部署Kubernetes,基于这样的底层网络假设,Kubernetes设计了pod-deployment-service的经典三层服务访问机制 。直到1.1发布,Kubernetes才开始采用全新的CNI(Container Network Interface)网络标准 。
CNI【浅析Kubernetes网络模型】其实,我们在前面介绍容器网络的时候,就提到了CNI网络规范,CNI相对于CNM(Container Network Model)对开发者的约束更少,更开放,不依赖于Docker 。事实上,CNI规范确实非常简单,详见:https://github.com/containernetworking/cni/blob/master/SPEC.md
浅析Kubernetes网络模型

文章插图
 
实现一个CNI网络插件只需要一个配置文件和一个可执行的文件:
  • 配置文件描述插件的版本、名称、描述等基本信息
  • 可执行文件会被上层的容器管理平台调用,一个CNI可执行文件自需要实现将容器加入到网络的ADD操作以及将容器从网络中删除的DEL操作(以及一个可选的VERSION查看版本操作)
Kubernetes使用CNI网络插件的基本工作流程:
  1. kubelet先创建pause容器生成对应的netns网络命名空间
  2. 根据配置调用具体的CNI插件,可以配置成CNI插件链来进行链式调用
  3. 当CNI插件被调用时,它根据环境变量以及命令行参数来获得网络命名空间netns、容器的网络设备等必要信息,然后执行ADD操作
  4. CNI插件给pause容器配置正确的网络,pod中其他的容器都是用pause容器的网络
如果不清楚什么是pause容器,它在pod中处于什么样的位置,请查看之前的笔记:https://morven.life/notes/from-container-to-pod/
pod网络模型要了解kubernetes网络模型的实现原理,我们就要从单个pod入手,事实上,一旦熟悉了单个pod的网络模型,就会发现kubernetes网络模型基本遵循和容器网络模型一样的原理 。
通过前面的笔记从docker容器到pod,我们知道pod启动的时候先创建pause容器生成对应的netns网络命名空间,然后其他容器共享pause容器创建的网络命名空间 。而对于单个容器的网络模型我们之前也介绍过,主要就是通过docker0网桥设备与veth设备对连接不同的容器网络命名空间,由此,我们可以得到如下图所示的单个pod网络模型的创建过程:
浅析Kubernetes网络模型

文章插图
 
可以看到,同一个pod里面的其他容器共享pause容器创建的网络命名空间,也就是说,所有的容器共享相同的网络设备,路由表设置,服务端口等信息,仿佛是在同一台机器上运行的不同进程,所以这些容器之间可以直接通过localhost与对应的端口通信;对于集群外部的请求,则通过docker0网桥设备充当的网关,同时通过iptables做地址转换 。我们会发现,这其实就是对当个容器的bridge网络模型的扩展 。


推荐阅读