[Kubernetes] Kubernetes Docker CNI 网络插件开发示例

一、  原理简介

           关于 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 <<EOF
{
    "cniVersion": "0.2.0",
    "name": "mynet",
    "type": "bridge",
    "bridge": "cni0",
    "isGateway": true,
    "ipMasq": true,
    "ipam": {
        "type": "host-local",
        "subnet": "10.22.0.0/16",
        "routes": [
            { "dst": "0.0.0.0/0" }
        ]
    }
}
EOF
# cat >/etc/cni/net.d/99-loopback.conf <<EOF
{
    "cniVersion": "0.2.0",
    "type": "loopback"
}
EOF
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)"
          
         可以看到,docker 容器的网络地址是我们配置的 CNI 网络 10.22.0.0/16(这里底层直接使用的 bridge)

2.5    我们可以使用自己编写的 CNI 脚本插件,来查看容器启动和结束时向 CNI 插件到底传递了什么信息

          首先,删除之前的 CNI 配置文件

# rm -f /etc/cni/net.d/*conf
          然后,编写新的 CNI 配置文件
# cat >/etc/cni/net.d/10-mynet.conf <<EOF
{
    "cniVersion": "0.2.0",
    "name": "my_dummy_network",
    "type": "dummy"
}
EOF
          编写,CNI 执行脚本 (注意,信息的接收既包含环境变量方式,也包含标准输入方式,即参数接收有两个途径)
# cat >/opt/cni/bin/dummy <<EOF
#!/bin/bash
logit () {
 >&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 
         

         可以看到,方法分别执行了 ADD(增加网络) DEL(移除网络),同时传入了容器 ID 等网络相关信息,

         CNI 插件根据这些信息执行实际的任务,这就是 CNI 网络的调用原理了。







猜你喜欢

转载自blog.csdn.net/shida_csdn/article/details/79752411