1. 程式人生 > >CNCF CNI系列之一:淺談kubernetes的網路與CNI(以flannel為例)

CNCF CNI系列之一:淺談kubernetes的網路與CNI(以flannel為例)

一、前言

kubernetes作為container的orchestration框架,主要的功能是在更高的層次對kubernetes服務和承載服務的實體(container)的部署、配置、可靠性進行管理,對應有namespace、POD、deployment、service等kubernetes的資源供application服務的提供者進行不同粒度上的配置和控制。

同樣,在網路層面,kubernetes沒有進入的更底層的具體container的網路互通互聯的解決方案的設計中,而是將網路互通功能一分為二,主要關注kubernetes的服務在網路中的暴露以及POD本身網路的配置動作,但是POD具體需要配置的網路引數以及service、POD之間的互通互聯,則交給CNI來解決。

這樣kubernetes其實本身不具有太複雜的網路功能,從而能夠將更多的經歷投放在kubernetes服務和承載服務的實體的管理上,最終能夠對外呈現一個易於管理、可用性高的應用服務叢集。

kubernetes的服務在網路中的暴露請參見文章《如何利用iptables對外暴露Kubernetes的service》,主要是藉助於iptables將請求至kubernetes服務入口的資料包在kubernetes worker node網路協議棧內進行修改,從而達到最終將資料包導向到某一個POD(SNAT/DNAT),這個POD可能在本地或者其他worker node。至於這個資料包在kubernetes worker node網路協議棧處理完畢後如何根據DNAT或者SNAT的要求到達該POD,則需要CNI配置的kubernetes POD互聯互通網路進行處理。

轉載自https://blog.csdn.net/cloudvtech

二、CNI概覽

CNI(container network interface)的目的在於定義一個標準的介面規範,使得kubernetes在增刪POD的時候,能夠按照規範向CNI例項提供標準的輸入並獲取標準的輸出,再將輸出作為kubernetes管理這個POD的網路的參考。

在滿足這個輸入輸出以及呼叫標準的CNI規範下,kubernetes委託CNI例項去管理POD的網路資源併為POD建立互通能力。

CNI本身實現了一些基本的外掛(https://github.com/containernetworking/plugins), 比如bridge、ipvlan、macvlan、loopback、vlan等網路介面管理外掛,還有dhcp、host-local等IP管理外掛,並且主流的container網路解決方案都有對應CNI的支援能力,比如Flannel、Calico、Weave、Contiv、SR-IOV、Amazon ECS CNI Plugins等。

轉載自https://blog.csdn.net/cloudvtech

三、kubernetes與CNI的介面(以flannel vxlan backend為例)

1.啟動flannel service

flanneld的配置檔案/etc/sysconfig/flanneld 內容如下:

FLANNEL_ETCD_ENDPOINTS="http://192.168.166.101:4001"
FLANNEL_ETCD_PREFIX="/test/network"

flannel service會建立一個名叫flannel.1的vxlan裝置並且生成flannel資訊檔案 flannel/subnet.env 

FLANNEL_NETWORK=172.22.0.0/16
FLANNEL_SUBNET=172.22.9.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=false

2.生成kubernetes可以識別的CNI配置檔案 /etc/cni/net.d/10-flannel.conf

類似這樣{  "name": “cni0",  "type": "flannel",  "delegate": {    "isDefaultGateway": true  }}或者這樣{        "name": "cni0",        "type": "flannel"}或者這樣{        "name": "cni0",        "type": "flannel",        "delegate": {                "bridge": "cni0",                "mtu": 1400        }} 

3. kubernetes部署POD並配置網路

kubelet檢視/etc/cni/net.d/10-flannel.conf配置檔案呼叫合適的CNI plugin。這個配置檔案告訴kubernetes使用flannel CNI外掛。kubetlet會配置環境變數並呼叫/opt/cni/bin/flannel,CNI用於支援flannel的二進位制程式。

CNI相關的環境變數如下:

export CNI_COMMAND=ADD
export CNI_IFNAME=busybox1
export CNI_NETNS=/proc/30283/ns/net
export CNI_CONTAINERID=9a3c6a6f7942 

flannel相關的環境變數如下:

FLANNEL_NETWORK=172.22.0.0/16
FLANNEL_SUBNET=172.22.9.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=false

然後使用如下命令呼叫flannel CNI:

/opt/cni/bin/flannel < /etc/cni/net.d/10-flannel.conf flannel CNI程式碼地址:

4.flannel CNI建立給bridge CNI的配置

{
        "name": “cni0",
        "type": "bridge",
        "mtu": 1472,
        "ipMasq": false,
        "isGateway": true,
        "ipam": {
                "type": "host-local",
                "subnet": "172.22.9.1/24"
        }
} 

5. flannel CNI使用上面生成的引數呼叫bridge CNI將container加入的網路中


6. bridge CNI生成POD的網路配置並設定相關路由

bridge CNI先生成一個名為cni0的bridge並掛載到flannel.1


bridge CNI 建立veth pair並將一端放入宿主機的netns:


bridge CNI程式碼地址如下:

https://github.com/containernetworking/plugins/blob/master/plugins/main/bridge/bridge.go

7.bridge CNI返回flannel CNI,flannel CNI向kubelet返回

返回的內容如下,包括IP地址、閘道器、路由等:

{
    "ip4": {
        "ip": "172.22.9.10/24",
        "gateway": "172.22.9.1",
        "routes": [
            {
                "dst": "172.22.0.0/16",
                "gw": "172.22.9.1"
            },
            {
                "dst": "0.0.0.0/0",
                "gw": "172.22.9.1"
            }
        ]
    },
    "dns": {}
} 


轉載自https://blog.csdn.net/cloudvtech