Container Network Interface - CNI
CNI
CNI 既 Container Network Interface 的简写.
CNI 是 Kubernetes 网络的一个标准
CNI
提供POD
的网络连接.CNI
提供分配IP地址的能力, 为POD
提供 ipv4 与 ipv6 的 DHCP 功能.CNI
还提供了NetWrok Policy
的能力, 定义POD
与POD
之间的网络规则.
CNI运行原理
根据
CNI
标准, 网络组件需要在CNI
下创建二进制执行文件, 用于配置网络环境.当
kubernetes
创建/删除pod
时, 调用二进制执行文件进行相应的网络配置.CNI
下的二进制执行文件会包含如下参数Container ID
容器ID号, 需要用于指定此容器配置网络, 也有一些CNI
组件需要利用容器ID进行数据索引.Network namespace path
当前container
真正的network namespace
路径 . 每个container
都会拥有至少一个network namespace
.namespace
是通过Linux kernel
操作的, 因此大部分CNI
组件都会根据这个路径, 通过network namespace
进行相关的网络配置.Network configuration
用于定义CNI
组件的相关配置. 包含两部分组成CNI
标准 和 网络组件额外定义.Name of the interface inside the container
在当前container
中创建网卡名称, 如:eth0
等.
network namespace
- 如上面所说每个
container
都至少拥有一个network namespace
, 但两个container
可以共用一个相同的network namespace
.
|
|
|
|
可以看到如上两个容器的网络都是同一个, 这里就可以想到
kubernetes
的pod
的网络.实际
pod
中有更灵活的设置, 详见如下架构图
Network Configuration
Network Configuration
就是一个json
格式的配置文件. 如上我们讲过 这个配置文件包含两部分CNI
标准的配置 - 根据官方CNI Spec
包含如下配置项cniVersion
定义CNI
的版本,CNI
组件必须相同, 否则报错.name
唯一的名称标识.type
CNI
组件定义的名称, 上层应用会根据这个名称去找对应的CNI
组件. 然后调用CNI
组件的二进制文件进行网络配置. 这个配置非常重要.args
额外的配置, 主要用于上层应用调用CNI
时的一些额外参数.ipMasq
标注当前CNI
组件是否支持SNAT
. 只做标识, 实际SNAT
是在CNI
组件中实现.dns
CNI
组件的 DNS 配置, 如:nameserver
、search
、domain
、options
等. 注: 在kubernetes
中, 会忽略这里的 DNS 配置, 因为kubernetes
会在自身设置 DNS 配置.ipam
既IP Address Management Plugin
, 负责IP地址的分配. 一般为host-local
和dhcp
.
一个配置文件
|
|
Kubernetes CNI
Kubernetes
目前网络有两种配置, 通过kubelet
中的--network-plugin
来指定选择哪一种配置.cni
目前kubernetes
部署方式基本都使用cni
配置网络. 如上所述,cni
包含两个部分cni
组件的二进制文件--cni-bin-dir
默认存放于/opt/cni/bin
目录下.cni
组件的 网络配置(Network Configuration) 或 网络配置列表(Network Configuration List)--cni-conf-dir
默认存放于etc/cni/net.d/
目录中.
|
|
|
|
|
|
CNI工作流程
Client
发送创建Pod
的请求.Pod
的创建中间流程忽略, 最后到kubelet
.kubelet
通过dockershim
+docker-containerd
的方式创建container
.Pod
创建完毕以后,kubelet
通过CNI
相关流程创建Pod
网络.CNI
组件搜索--cni-conf-dir
目录下的配置文件, 按照数字顺序查找合法的网络配置.Flannel
的配置文件为10-flannel.conflist
- 读取配置文件, 通过
type
或者cni
组件. - 通过
type
调用--cni-bin-dir
目录下的cni
组件的二进制文件. - 通过配置文件参数配置容器网络.
- 配置完网络以后, 调用
--cni-bin-dir
目录下的portmap
二进制文件, 将容器的IP和端口通过iptables
映射到宿主机的端口上.
Kubenet工作流程
kubenet
是个非常简单的L2 Bridge
, 其实也是通过CNI
建立一个简单的网络, 由kubenet
配置的网络只能用于单节点的网络通讯. 所以kubenet
是用于测试.