解析 | K8S之網路外掛CNI
CNI(Container Network Interface)容器網路介面,
是Linux容器網路配置的一組標準和庫,
使用者需要根據這些標準和庫來開發自己的容器網路外掛 。
在github裡已經提供了一些常用的外掛,CNI只專注解決容器網路連線和容器銷燬時的資源釋放,提供一套框架,所以CNI可以支援大量不同的網路模式,並且容易實現。
相對於k8s exec直接執行可執行程式,cni 外掛是對執行程式的封裝,規定了可執行程式的框架,當然最後還是和exec 外掛一樣,執行可執行程式。只不過exec 外掛通過命令列資料讀取引數,cni外掛通過環境變數以及配置檔案讀入引數。
相對於exec 的4個 subcommand,cni 只有2 subcommand,執行CNI外掛需要傳入以下環境變數:
CNI_COMMAND=ADD/DEL
CNI_CONTAINERID=xxxxxxxxxxxxxxxxxxx
CNI_NETNS=/proc/4390/ns/net
CNI_ARGS=IgnoreUnknown=1;K8S_POD_NAMESPACE=default;K8S_POD_NAME=22-my-nginx-2523304718-7stgs;K8S_POD_INFRA_CONTAINER_ID=xxxxxxxxxxxxxxxx
CNI_IFNAME=eth0
CNI_PATH=/opt/cni/bin.
最終的執行是./plugin netconfpath 其中plugin是二進位制可執行cni外掛,netconf 是配置檔案路徑,一般配置檔案資料夾在 /etc/cni/net.d/。
cni外掛的開發可以模仿github上面的例子,主要實現兩個函式:
funccmdAdd(args *skel.CmdArgs) 和funccmdDel(args *skel.CmdArgs)
下面bridge配置檔案例子:
{
“cniVersion”: “0.2.0”,
“name”: “mynet”,
“type”: “bridge”, //使用的cni外掛型別,cni根據這個呼叫相應二進位制檔案
“bridge”: “cni0”,
“isGateway”: true, //其他配置資訊比如IP地址等
“ipMasq”: true,
“ipam”: {
“type”:”host-local”,
“subnet”:”10.22.0.0/16″,
“routes”: [
{ “dst”:”0.0.0.0/0″ }
]
}
}
下面calico配置檔案例子:
{
“name”:”k8s-pod-network”,
“type”: “calico”,
“etcd_endpoints”:”http://10.255.13.121:2379″,
“etcd_key_file”: “”,
“etcd_cert_file”: “”,
“etcd_ca_cert_file”:””,
“log_level”: “info”,
“ipam”: {
“type”:”calico-ipam”
},
“policy”: {
“type”: “k8s”,
“k8s_api_root”:”https://10.255.0.1:443″,
“k8s_auth_token”:”eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkZWZhdWx0LXRva2VuLTN4d2NjIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlZmF1bHQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI3MGQ5Y2YyNS1jNzU2LTExZTYtYWVhNi1kMDBkYTBmNGQ0ZTIiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06ZGVmYXVsdCJ9.OqEBj0cofXDKvQiioRkt1RKuF5QSPRweYRsmKXsacDFq10jJmBzgJUZtiIysu5CDov-6OR4p2HzmBfjfWkNFuldvOMKdjZP4KmJ8C1ZAOJ20f7Rr0-hyiG3Hnem6RBK41QsIUz0dwB-SmGWR9Mx-HY3LHITFp6nn3UcaDVESIFuRLge3KSnWBlalTlI5zyxJJ5Bfuxh9J26hw8wCaZce53pkE9g2fcjxJkXdUPEzB1MZw8egu7FiQ6_WaiaYgu6uD9TQovjb8uewWR3Jq5aYvCOrwnegm2MxC8Ndt_3EUJRVNgYnf2yzaXmkDSqAtgR-PQQ2SmYWKu45MjPPiyJn3w”
},
“kubernetes”: {
“kubeconfig”:”/etc/cni/net.d/calico-kubeconfig”
}
}
Calico這邊資料是從Calico服務端獲取相應的網路資訊。
像簡單的外掛,對於容器網路資訊,比如容器應該分配的IP,可以直接從dnsmasq分配出來;如果更簡單一些,可以直接從CNI_ARGS 環境變數傳過來;複雜的外掛,比如Calico,就需要從服務端傳遞資料過來。