一、什么是CNI?
CNI-容器網絡接口,CNI(容器網絡接口)是Cloud Native Computing Foundation項目,由一個規范和庫(用於編寫用於在Linux容器中配置網絡接口的插件)以及許多受支持的插件組成。CNI僅涉及容器的網絡連接以及刪除容器時刪除分配的資源。由於這種關注,CNI具有廣泛的支持,並且該規范易於實現。
除規范外,此存儲庫還包含一個Go語言源代碼庫,該庫用於將CNI集成到應用程序中,以及一個示例命令行工具,用於執行CNI插件。一個單獨的存儲庫包含參考插件和用於制作新插件的模板。
模板代碼可以直接為現有的容器網絡項目創建CNI插件。CNI還為從頭創建新的容器網絡項目提供了一個良好的框架。
二、為什么開發CNI?
Linux上的應用程序容器是一個快速發展的領域,在該領域內,由於高度特定於環境,因此無法很好地解決網絡問題。我們相信,許多容器運行時和協調器將尋求解決使網絡層可插入的相同問題。
為避免重復,我們認為在網絡插件和容器執行之間定義一個通用接口是謹慎的:因此,我們提出了該規范,以及Go庫和一組插件。
三、誰在使用CNI?
容器運行時
- rkt-集裝箱發動機
- Kubernetes-一個簡化容器操作的系統
- OpenShift-具有其他企業功能的Kubernetes
- Cloud Foundry-雲應用程序平台
- Apache Mesos-分布式系統內核
- Amazon ECS-高度可擴展的高性能容器管理服務
- 奇異性-針對HPC,EPC和AI優化的容器平台
- OpenSVC-用於遺留和容器化應用程序堆棧的協調器
第三方插件
- Calico項目-第3層虛擬網絡
- Weave-多主機Docker網絡
- Contiv Networking-各種用例的策略網絡
- SR-IOV
- Cilium-容器的BPF和XDP
- Infoblox-容器的企業IP地址管理
- Multus-一個多插件
- Romana-支持Kubernetes的第3層CNI插件支持網絡策略
- CNI-Genie-通用CNI網絡插件
- Nuage CNI-用於網絡策略kubernetes支持的Nuage Networks SDN插件
- Silk-為Cloud Foundry設計的CNI插件
- 亞麻-用於開放式vSwitch的覆蓋網絡的CNI插件,適用於SDN / OpenFlow網絡環境
- Vhostuser-一個Dataplane網絡插件-支持OVS-DPDK和VPP
- Amazon ECS CNI插件-用於配置具有Amazon EC2彈性網絡接口(ENI)的容器的CNI插件的集合
- 綁定CNI-用於解決故障轉移和高可用性網絡的鏈接聚合插件
- ovn-kubernetes-基於Open vSwitch(OVS)和Open Virtual Networking(OVN)構建的容器網絡插件,同時支持Linux和Windows
- Juniper Contrail / TungstenFabric-提供覆蓋SDN解決方案,提供多雲網絡,混合雲網絡,同時支持覆蓋層,網絡策略實施,網絡隔離,服務鏈和靈活的負載平衡
- Knitter-一個支持Kubernetes多個網絡的CNI插件
- DANM-適用於Kubernetes上的TelCo工作負載的CNI兼容網絡解決方案
- VMware NSX –一個CNI插件,可實現自動NSX L2 / L3網絡和L4 / L7負載平衡;Pod,節點和群集級別的網絡隔離;Kubernetes集群的零信任安全策略。
四、接口參數
網絡插件是獨立的可執行文件,被上層的容器管理平台調用。網絡插件只有兩件事情要做:把容器加入到網絡以及把容器從網絡中刪除。調用插件的數據通過兩種方式傳遞:環境變量和標准輸入。一般插件需要三種類型的數據:容器相關的信息,比如 ns 的文件、容器 id 等;網絡配置的信息,包括網段、網關、DNS 以及插件額外的信息等;還有就是 CNI 本身的信息,比如 CNI 插件的位置、添加網絡還是刪除網絡。
我們來看一下為容器添加網絡是怎么工作的,刪除網絡和它過程一樣。
把容器加入到網絡
調用插件的時候,這些參數會通過環境變量進行傳遞:
CNI_COMMAND
:要執行的操作,可以是ADD
(把容器加入到某個網絡)、DEL
(把容器從某個網絡中刪除)CNI_CONTAINERID
:容器的 ID,比如 ipam 會把容器 ID 和分配的 IP 地址保存下來。可選的參數,但是推薦傳遞過去。需要保證在管理平台上是唯一的,如果容器被刪除后可以循環使用CNI_NETNS
:容器的 network namespace 文件,訪問這個文件可以在容器的網絡 namespace 中操作CNI_IFNAME
:要配置的 interface 名字,比如eth0
CNI_ARGS
:額外的參數,是由分號;
分割的鍵值對,比如 “FOO=BAR;hello=world”CNI_PATH
:CNI 二進制查找的路徑列表,多個路徑用分隔符:
分隔
網絡信息主要通過標准輸入,作為 JSON 字符串傳遞給插件,必須的參數包括:
cniVersion
:CNI 標准的版本號。因為 CNI 在演化過程中,不同的版本有不同的要求name
:網絡的名字,在集群中應該保持唯一type
:網絡插件的類型,也就是 CNI 可執行文件的名稱args
:額外的信息,類型為字典ipMasq
:是否在主機上為該網絡配置 IP masqueradeipam
:IP 分配相關的信息,類型為字典dns
:DNS 相關的信息,類型為字典
插件接到這些數據,從輸入和環境變量解析到需要的信息,根據這些信息執行程序邏輯,然后把結果返回給調用者,返回的結果中一般包括這些參數:
- IPs assigned to the interface:網絡接口被分配的 ip,可以是 IPv4、IPv6 或者都有
- DNS 信息:包含 nameservers、domain、search domains 和其他選項的字典
CNI 協議的內容還在不斷更新,請到官方文檔獲取當前的信息。
五、kubernets中的使用
CNI 目前已經在 kubernetes 中開始使用,也是目前官方推薦的網絡方案,具體的配置方法可以參考kubernetes 官方文檔。
kubernetes 使用了 CNI 網絡插件之后,工作過程是這樣的:
- kubernetes 先創建 pause 容器生成對應的 network namespace
- 調用網絡 driver(因為配置的是 CNI,所以會調用 CNI 相關代碼)
- CNI driver 根據配置調用具體的 cni 插件
- cni 插件給 pause 容器配置正確的網絡
- pod 中其他的容器都是用 pause 的網絡