一、 原理简介
关于 Kubernetes 网络插件,要从其初始化配置讲起,
即 /etc/systemd/system/kubelet.service.d/10-kubeadm.conf ,
该配置文件定义了 Kubernetes 系统启用的网络模式,默认网络参数是:
--network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin
--network-plugin=cni 表明 k8s 使用实现标准CNI (容器网络接口)的网络插件
--cni-conf-dir=/etc/cni/net.d 是存放 CNI 网络插件配置信息的文件夹路径
--cni-bin-dir=/opt/cni/bin 是存放 CNI 网络插件可执行文件的文件夹路径
当 k8s 需要操作网络时(如创建网络),会通过 cni-conf-dir 中的配置信息,
去 cni-bin-dir 中寻找命令文件并执行相关命令
该命令文件的接收参数与返回值遵循 CNI 接口规范,达到统一接口的效果,下边我们通过实例进行验证。
二、 示例验证
2.1 开发环境
Ubuntu 16.04 LTS ,Docker 1.12.6, Golang 1.9.2
2.2 下载和编译 CNI Plugin
CNI Plugin 是 CNI 官方提供的一些网络操作命令集合,是 CNI 插件工作的基础
# cd $GOPATH/src
# git clone https://github.com/containernetworking/plugins.git
# cd plugins
# ./build.sh
# cp ./bin/* /opt/cni/bin
2.3 编写 CNI 配置信息
# mkdir -p /etc/cni/net.d
# cat >/etc/cni/net.d/10-mynet.conf </etc/cni/net.d/99-loopback.conf <
2.4 运行容器测试
为了让 Docker 使用 CNI 网络,CNI 官方提供了相关脚本,我们通过该脚本运行容器
注意,需要通过环境变量告知脚本 CNI 配置文件和执行命令的路径
# cd $GOPATH/src
# git clone https://github.com/containernetworking/cni.git
# cd cni/scripts
# export CNI_PATH=/opt/cni/bin/
# export NETCONFPATH=/etc/cni/net.d
# ./docker-run.sh --rm busybox ifconfig | grep -Pi "(eth0|lo|inet addr)"
2.5 我们可以使用自己编写的 CNI 脚本插件,来查看容器启动和结束时向 CNI 插件到底传递了什么信息
首先,删除之前的 CNI 配置文件
# rm -f /etc/cni/net.d/*conf
然后,编写新的 CNI 配置文件
# cat >/etc/cni/net.d/10-mynet.conf <
编写,CNI 执行脚本 (注意,信息的接收既包含环境变量方式,也包含标准输入方式,即参数接收有两个途径)
# cat >/opt/cni/bin/dummy <&2 echo \$1
}
logit "CNI method: \$CNI_COMMAND"
logit "CNI container id: \$CNI_CONTAINERID"
logit "-------------- Begin config"
while read line
do
logit "\$line"
done < /dev/stdin
logit "-------------- End config"
EOF
# chmod 0755 /opt/cni/bin/dummy
测试,查看 CNI 调用情况
# cd $GOPATH/src/cni/scripts
# ./docker-run.sh --rm busybox ifconfig
CNI 插件根据这些信息执行实际的任务,这就是 CNI 网络的调用原理了。