不会飞的章鱼

熟能生巧,勤能补拙;念念不忘,必有回响。

Kubernetes网络原理——网络模型与CNI网络插件

Kubernetes网络模型

Kubernetes 是通过一个叫作 CNI 的接口,维护了一个单独的网桥来代替 docker0。
这个网桥的名字就叫作:CNI 网桥,它在宿主机上的设备名称默认是:cni0。

在这里,Kubernetes 为 Flannel 分配的子网范围是 10.244.0.0/16。
这个参数可以在部署的时候指定,比如:

1
kubeadm init --pod-network-cidr=10.244.0.0/16

注:也可以在部署完成后,通过修改 kube-controller-manager 的配置文件来指定。

假设 Infra-container-1 要访问 Infra-container-2(也就是 Pod-1 要访问 Pod-2)
,这个 IP 包的源地址就是 10.244.0.2,目的 IP 地址是 10.244.1.3。而此时,Infra-container-1 里的 eth0 设备,同样是以 Veth Pair 的方式连接在 Node 1 的 cni0 网桥上。所以这个 IP 包就会经过 cni0 网桥出现在宿主机上。

需要注意的是,CNI 网桥只是接管所有 CNI 插件负责的、即 Kubernetes 创建的容器(Pod)。而此时,如果你用 docker run 单独启动一个容器,那么 Docker 项目还是会把
这个容器连接到 docker0 网桥上。所以这个容器的 IP 地址,一定是属于 docker0 网桥的
172.17.0.0/16 网段。

Kubernetes 之所以要设置这样一个与 docker0 网桥功能几乎一样的 CNI 网桥,主要原因
包括两个方面:

  • Kubernetes 项目并没有使用 Docker 的网络模型(CNM),所以它并不希望、也不具备配置 docker0 网桥的能力;
  • 这还与 Kubernetes 如何配置 Pod,也就是 Infra 容器的 Network Namespace 密切相关。

我们知道,Kubernetes 创建一个 Pod 的第一步,就是创建并启动一个 Infra 容器,用
来“hold”住这个 Pod 的 Network Namespace,所以,CNI 的设计思想,就是:Kubernetes 在启动 Infra 容器之后,就可以直接调用CNI 网络插件,为这个 Infra 容器的 Network Namespace,配置符合预期的网络栈。

CNI 插件的部署和实现方式

我们在部署 Kubernetes 的时候,有一个步骤是安装 kubernetes-cni 包,它的目的就是在
宿主机上安装CNI 插件所需的基础可执行文件。
在安装完成后,你可以在宿主机的 /opt/cni/bin 目录下看到它们

这些 CNI 的基础可执行文件,按照功能可以分为三类:

  • 第一类:Main 插件,它是用来创建具体网络设备的二进制文件。
  • 第二类: IPAM(IP Address Management)插件,它是负责分配 IP 地址的二进制文件。
  • 第三类:由 CNI 社区维护的内置 CNI 插件。

接下来,你就需要在宿主机上安装 flanneld(网络方案本身)。而在这个过程中,flanneld 启动后会在每台宿主机上生成它对应的CNI 配置文件(它其实是一个ConfigMap),从而告诉 Kubernetes,这个集群要使用 Flannel 作为容器网络方案。

总结

Kubernetes 网络模型

  • 所有容器都可以直接使用 IP 地址与其他容器通信,而无需使用 NAT。
  • 所有宿主机都可以直接使用 IP 地址与所有容器通信,而无需使用 NAT。反之亦然。
  • 容器自己“看到”的自己的 IP 地址,和别人(宿主机或者容器)看到的地址是完全一样的。

容器与容器之间要“通”,容器与宿主机之间也要“通”。并且,Kubernetes 要求这个“通”还必须是直接基于容器和宿主机的 IP 地址来进行的。

------ 本文结束------
如果本篇文章对你有帮助,可以给作者加个鸡腿~(*^__^*),感谢鼓励与支持!