导读:阿里云 K8S 集群网络目前有两种方案:一种是 flannel 方案;另一种是基于 calico 和弹性网卡 eni 的 terway 方案。Terway 和 flannel 相似,不一样的地方在于 terway 支持 Pod 弹性网卡,以及 NetworkPolicy 功能。本文中,做者基于当前的 1.12.6 版本,以 flannel 为例,深刻分析阿里云 K8S 集群网络的实现方法。node
整体上来讲,阿里云 K8S 集群网络配置完成以后,以下图所示:包括集群 CIDR、VPC 路由表、节点网络、节点的 podCIDR、节点上的虚拟网桥 cni0、链接 Pod 和网桥的 veth 等部分。网络
相似的图你们可能在不少文章中都看过,但由于其中相关配置过于复杂,比较难理解。这里咱们能够看下这些配置背后的逻辑。框架
基本上咱们能够把这些配置分三种状况来理解:集群配置,节点配置以及 Pod 配置。与这三种状况对应的,实际上是对集群网络 IP 段的三次划分:首先是集群 CIDR,接着是为每一个节点分配 podCIDR(即集群 CIDR 的子网段),最后在 podCIDR 里为每一个 Pod 分配本身的 IP。工具
集群的建立,基于云资源 VPC 和 ECS,在建立完 VPC 和 ECS 以后,咱们基本上能够获得以下图的资源配置。咱们获得一个 VPC,这个 VPC 的网段是 192.168.0.0/16,咱们获得若干 ECS,他们从 VPC 网段里分配到 IP 地址。oop
在以上出初始资源的基础上,咱们利用集群建立控制台获得集群 CIDR。这个值会以参数的形式传给集群节点 provision 脚本,并被脚本传给集群节点配置工具 kubeadm。kubeadm 最后把这个参数写入集群控制器静态 Pod 的 yaml 文件 kube-controller-manager.yaml。阿里云
集群控制器有了这个参数,在节点 kubelet 注册节点到集群的时候,集群控制器会为每一个注册节点,划分一个子网出来,即为每一个节点分配 podCIDR。如上图,Node B 的子网是 172.16.8.1/25,而 Node A 的子网是 172.16.0.128/25。这个配置会记录到集群 node 的 podCIDR 数据项里。插件
通过以上集群阶段,K8S 有了集群 CIDR,以及为每一个节点划分的 podCIDR。在此基础上,集群会下发 flanneld 到每一个阶段上,进一步搭建节点上,能够给 Pod 使用的网络框架。这里主要有两个操做:命令行
注意:实际实现上,cni0 的建立,是在第一个使用 Pod 网络的 Pod 被调度到节点上的时候,由下一节中 flannal cni 建立的,可是从逻辑上来讲,cni0 属于节点网络,不属于 Pod 网络,因此在此描述。3d
在前边的三个阶段,集群实际上已经为 Pod 之间搭建了网络通讯的干道。这个时候,若是集群把一个 Pod 调度到节点上,kubelet 会经过 flannel cni 为这个 Pod 自己建立网络命名空间和 veth 设备,而后,把其中一个 veth 设备加入到 cni0 虚拟网桥里,并为 Pod 内的 veth 设备配置 IP 地址。这样 Pod 就和网络通讯的干道链接在了一块儿。
这里须要强调的是,前一节的 flanneld 和这一节的 flannel cni 彻底是两个组件。flanneld 是一个 daemonset 下发到每一个节点的 pod,它的做用是搭建网络(干道),而 flannel cni 是节点建立的时候,经过 kubernetes-cni 这个 rpm 包安装的 cni 插件,其被 kubelet 调用,用来为具体的 pod 建立网络(分枝)。理解这二者的区别,有助于咱们理解 flanneld 和 flannel cni 相关的配置文件的用途。好比 /run/flannel/subnet.env,是 flanneld 建立的,为 flannel cni 提供输入的一个环境变量文件;又好比 /etc/cni/net.d/10-flannel.conf,也是 flanneld pod(准确的说,是 pod 里的脚本 install-cni)从 pod 里拷贝到节点目录,给 flannel cni 使用的子网配置文件。blog
以上完成 Pod 网络环境搭建。基于以上的网络环境,Pod 能够完成四种通讯:本地通讯;同节点 Pod 通讯;跨节点 Pod 通讯;以及 Pod 和 Pod 网络以外的实体通讯。
其中本地通讯,说的是 Pod 内部,不一样容器之间的通讯。由于 Pod 内网容器之间共享一个网络协议栈,因此他们之间的通讯,能够经过 loopback 设备完成。
同节点 Pod 之间的通讯,是 cni0 虚拟网桥内部的通讯,这至关于一个二层局域网内部设备通讯。
跨节点 Pod 通讯略微复杂一点,但也很直观,发送端数据包,经过 cni0 网桥的网关,流转到节点上,而后通过节点 eth0 发送给 VPC 路由。这里不会通过任何封包操做。当 VPC 路由收到数据包时,它经过查询路由表,确认数据包目的地,并把数据包发送给对应的 ECS 节点。而进去节点以后,由于 flanneld 在节点上建立了 cni0 的路由,因此数据包会被发送到目的地的 cni0 局域网,再到目的地 Pod。
最后一种状况,Pod 与非 Pod 网络的实体通讯,须要通过节点上 iptables 规则作 SNAT,而此规则就是 flanneld 依据命令行 --ip-masq 选项作的配置。
以上是阿里云 K8S 集群网络的搭建和通讯原理。咱们主要经过网络搭建和通讯两个角度去分析 K8S 集群网络。其中网络搭建包括初始阶段、集群阶段、节点阶段以及 Pod 阶段,这么分类有助于咱们理解这些复杂的配置。而理解了各个配置,集群通讯原理就比较容易理解了。
原文连接本文为云栖社区原创内容,未经容许不得转载。