您好,登錄后才能下訂單哦!
今天小編給大家分享一下kubernetes的CNI怎么安裝的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
我們安裝kubernetes時先不安裝CNI. 如果使用了sealyun離線包 那么修改下 kube/conf/master.sh
只留如下內容即可:
[root@helix105 shell]# cat master.sh kubeadm init --config ../conf/kubeadm.yaml mkdir ~/.kube cp /etc/kubernetes/admin.conf ~/.kube/config kubectl taint nodes --all node-role.kubernetes.io/master-
清空CNI相關目錄:
rm -rf /opt/cni/bin/* rm -rf /etc/cni/net.d/*
啟動kubernetes, 如果已經裝過那么kubeadm reset一下:
cd kube/shell && sh init.sh && sh master.sh
此時你的節點是notready的,你的coredns也沒有辦法分配到地址:
[root@helix105 shell]# kubectl get pod -n kube-system -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES coredns-5c98db65d4-5fh7c 0/1 Pending 0 54s <none> <none> <none> <none> coredns-5c98db65d4-dbwmq 0/1 Pending 0 54s <none> <none> <none> <none> kube-controller-manager-helix105.hfa.chenqian 1/1 Running 0 19s 172.16.60.105 helix105.hfa.chenqian <none> <none> kube-proxy-k74ld 1/1 Running 0 54s 172.16.60.105 helix105.hfa.chenqian <none> <none> kube-scheduler-helix105.hfa.chenqian 1/1 Running 0 14s 172.16.60.105 helix105.hfa.chenqian <none> <none> [root@helix105 shell]# kubectl get node NAME STATUS ROLES AGE VERSION helix105.hfa.chenqian NotReady master 86s v1.15.0
創建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", "name": "lo", "type": "loopback" } EOF
這里兩個配置一個是給容器塞一個網卡掛在網橋上的,另外一個配置負責擼(本地回環)。。
配置完后會發現節點ready:
[root@helix105 shell]# kubectl get node NAME STATUS ROLES AGE VERSION helix105.hfa.chenqian Ready master 15m v1.15.0
但是coredns會一直處于ContainerCreating狀態,是因為bin文件還沒有:
failed to find plugin "bridge" in path [/opt/cni/bin]
plugins里實現了很多的CNI,如我們上面配置的bridge.
$ cd $GOPATH/src/github.com/containernetworking/plugins $ ./build_linux.sh $ cp bin/* /opt/cni/bin $ ls bin/ bandwidth dhcp flannel host-local loopback portmap sbr tuning bridge firewall host-device ipvlan macvlan ptp static vlan
這里有很多二進制,我們學習的話不需要關注所有的,就看ptp(就簡單的創建了設備對)或者bridge
再看coredns已經能分配到地址了:
[root@helix105 plugins]# kubectl get pod -n kube-system -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES coredns-5c98db65d4-5fh7c 1/1 Running 0 3h20m 10.22.0.8 helix105.hfa.chenqian <none> <none> coredns-5c98db65d4-dbwmq 1/1 Running 0 3h20m 10.22.0.9
看一下網橋,cni0上掛了兩個設備,與我們上面的cni配置里配置的一樣,type字段指定用哪個bin文件,bridge字段指定網橋名:
[root@helix105 plugins]# brctl show bridge name bridge id STP enabled interfaces cni0 8000.8ef6ac49c2f7 no veth2b28b06f veth2c093940
為了更好理解kubelet干嘛了,我們可以找一個腳本來解釋 script 這個腳本也可以用來測試你的CNI:
為了易讀,我刪除一些不重要的東西,原版腳本可以在連接中去拿
# 先創建一個容器,這里只為了拿到一個net namespace contid=$(docker run -d --net=none golang:1.12.7 /bin/sleep 10000000) pid=$(docker inspect -f '{{ .State.Pid }}' $contid) netnspath=/proc/$pid/ns/net # 這個我們需要 kubelet啟動pod時也是創建好容器就有了pod的network namespaces,再去把ns傳給cni 讓cni去配置 ./exec-plugins.sh add $contid $netnspath # 傳入兩個參數給下一個腳本,containerid和net namespace路徑 docker run --net=container:$contid $@
NETCONFPATH=${NETCONFPATH-/etc/cni/net.d} i=0 # 獲取容器id和網絡ns contid=$2 netns=$3 # 這里設置了幾個環境變量,CNI命令行工具就可以獲取到這些參數 export CNI_COMMAND=$(echo $1 | tr '[:lower:]' '[:upper:]') export PATH=$CNI_PATH:$PATH # 這個指定CNI bin文件的路徑 export CNI_CONTAINERID=$contid export CNI_NETNS=$netns for netconf in $(echo $NETCONFPATH/10-mynet.conf | sort); do name=$(jq -r '.name' <$netconf) plugin=$(jq -r '.type' <$netconf) # CNI配置文件的type字段對應二進制程序名 export CNI_IFNAME=$(printf eth%d $i) # 容器內網卡名 # 這里執行了命令行工具 res=$($plugin <$netconf) # 這里把CNI的配置文件通過標準輸入也傳給CNI命令行工具 if [ $? -ne 0 ]; then # 把結果輸出到標準輸出,這樣kubelet就可以拿到容器地址等一些信息 errmsg=$(echo $res | jq -r '.msg') if [ -z "$errmsg" ]; then errmsg=$res fi echo "${name} : error executing $CNI_COMMAND: $errmsg" exit 1 let "i=i+1" done
總結一下:
CNI配置文件 容器ID 網絡ns kubelet --------------> CNI command ^ | | | +------------------------+ 結果標準輸出
既然這么簡單,那么就可以去看看實現了:
bridge CNI代碼
//cmdAdd 負責創建網絡 func cmdAdd(args *skel.CmdArgs) error //入參數都已經寫到這里面了,前面的參數從環境變量讀取的,CNI配置從stdin讀取的 type CmdArgs struct { ContainerID string Netns string IfName string Args string Path string StdinData []byte }
所以CNI配置文件除了name type這些特定字段,你自己也可以加自己的一些字段.然后自己去解析
然后啥事都得靠自己了
//這里創建了設備對,并掛載到cni0王橋上 hostInterface, containerInterface, err := setupVeth(netns, br, args.IfName, n.MTU, n.HairpinMode, n.Vlan)
具體怎么掛的就是調用了netlink 這個庫,sealos在做內核負載時同樣用了該庫。
err := netns.Do(func(hostNS ns.NetNS) error { //創建設備對 hostVeth, containerVeth, err := ip.SetupVeth(ifName, mtu, hostNS) ... //配置容器內的網卡名mac地址等 contIface.Name = containerVeth.Name contIface.Mac = containerVeth.HardwareAddr.String() contIface.Sandbox = netns.Path() hostIface.Name = hostVeth.Name return nil }) ... // 根據index找到宿主機設備對名 hostVeth, err := netlink.LinkByName(hostIface.Name) ... hostIface.Mac = hostVeth.Attrs().HardwareAddr.String() // 把宿主機端設備對掛給網橋 if err := netlink.LinkSetMaster(hostVeth, br); err != nil {} // 設置hairpin mode if err = netlink.LinkSetHairpin(hostVeth, hairpinMode); err != nil { } // 設置vlanid if vlanID != 0 { err = netlink.BridgeVlanAdd(hostVeth, uint16(vlanID), true, true, false, true) } return hostIface, contIface, nil
最后把結果返回:
type Result struct { CNIVersion string `json:"cniVersion,omitempty"` Interfaces []*Interface `json:"interfaces,omitempty"` IPs []*IPConfig `json:"ips,omitempty"` Routes []*types.Route `json:"routes,omitempty"` DNS types.DNS `json:"dns,omitempty"` } // 這樣kubelet就收到返回信息了 func (r *Result) PrintTo(writer io.Writer) error { data, err := json.MarshalIndent(r, "", " ") if err != nil { return err } _, err = writer.Write(data) return err }
如:
{ "cniVersion": "0.4.0", "interfaces": [ (this key omitted by IPAM plugins) { "name": "<name>", "mac": "<MAC address>", (required if L2 addresses are meaningful) "sandbox": "<netns path or hypervisor identifier>" (required for container/hypervisor interfaces, empty/omitted for host interfaces) } ], "ips": [ { "version": "<4-or-6>", "address": "<ip-and-prefix-in-CIDR>", "gateway": "<ip-address-of-the-gateway>", (optional) "interface": <numeric index into 'interfaces' list> }, ... ], "routes": [ (optional) { "dst": "<ip-and-prefix-in-cidr>", "gw": "<ip-of-next-hop>" (optional) }, ... ], "dns": { (optional) "nameservers": <list-of-nameservers> (optional) "domain": <name-of-local-domain> (optional) "search": <list-of-additional-search-domains> (optional) "options": <list-of-options> (optional) } }
以上就是“kubernetes的CNI怎么安裝”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。