k8s 的网络插件 (network plugin) 简介和个人总结.

简介

k8s 没有提供容器与容器, 容器与主机之间连通性的方式. 但使用了网络插件(network plugin)的形式来实现, 目前主要区分了两种实现 CNI(Container Network Interface) 和 kubenet.

分类

  1. CNI
  2. kubenet

CNI

通过设置 kubelet 的 –network-plugin=cni 来选择使用 cni, --cni-conf-dir (默认在 /etc/cni/net.d)来指定 cni 的配置文件地址, 配置文件规范有 CNI specification, cni 配置中所需的可执行文件通过 --cni-bin-dir (默认在 /opt/cni/bin)指定.
如果 --cni-conf-dir 下有多份目录, 只有按文件名字母顺序的第一个会被采用.
CNI 提供几个 plugins, 在项目 containernetworking/plugins, type 有 bridge/ipvlan/loopback/macvlan/ptp/vlan, ipam 有 dhcp/host-local. 编译项目, 然后写上配置文件, 则 k8s 集群会使用此类插件.
CNI 也有很多第三方的实现, 如 calico/flannel……

kubenet

kubenet 一般是用在 cloud provider 上, 如 aws/GCE.
kubenet 实现的很简单, 即创建一个叫 cbr0 的 Linux bridge 和一对 veth pair, 将 pod 连接到 cbr0. 剩下的将容器的连通, 都依赖 cloud provider, 也就是云服务商.
kubenet 依赖这几个插件 bridge/lo/host-local(>=0.2.0).
部分如 AWS 的服务商的 MTU 不(有点)一(奇)样(怪), 所以需要设置 --network-plugin-mtu=9001.
另外, kubenet 是整体编译在 k8s 中的, 所以需要合入 k8s 代码. 然而他们似乎并不想新增 cloud provider 了. 参考 cloudprovider/README.md
目前的 cloud provider 有 aws/azure/cloudstack/gce/openstack/ovirt/photon/vsphere. providers

说到底

  1. CNI 只是份规范, 规定了第三方需要做什么, 怎么做. 所以踊跃出现了大量的 CNI 实现, 而且实现 pod 的连通上也是各显神通.
  2. kubenet 呢则做的很少, 只负责将 pod 连接到一块本机的 bridge 网卡, 剩下的 pod 之间连通性都需要云服务商来提供.
  3. k8s 对网络插件就这里是看是二选一的方式, 甚至在各种实现 CNI 的选择上, 也是 N 选 1 的情况(默认读取文件名最小的配置来用).
  4. 但还是会有一些实现 multi-CNI 的插件, 就是能够使得 pod 使用不同的 CNI 以及它们所使用的 ipam 来获取 IP, multi-CNI 一般会依赖一些 pod 上额外的信息(如 annotation)来决定具体使用哪个或哪几个 CNI 插件. 就能够实现 pod 有不同网络下的 IP, 甚至是多个 IP 地址. 如 Intel-Corp/multus-cni, Huawei-PaaS/CNI-Genie. 主要也是因为各个 CNI/ipam 的实现, 最终都是一个可执行文件的形式, 执行的最终结果 almost 直接输出到 stdout, 所以也就给了这种 multi-CNI 可乘之机, 就是读取 pod 的 annotation, 然后再去执行所需的 CNI 插件.

Reference

Network Plugins
Github: kubernetes/kubernetes