带你玩转kubernetes-k8s(第46篇:深入分析k8s网络原理[CNM、CNI]网络模型)
? ? ? 隨著容器技術在企業生產系統中的逐步落地,用戶對容器云的網絡特性要求也越來越高。跨主機容器間的網絡互通已經成為基本要求,更高的要求包括容器固定IP地址、一個容器多個IP地址、多個子網隔離、ACL控制策略、與SDN集成等。目前主流的容器網絡模型主要有Docker公司提出的Container Network Model(CNM)模型和CoreOS公司提出的Container Network Interface(CNI)模型。
1.CNM模型
? ? CNM模型是由Docker公司提出的容器網絡模型,現在已經被Cisco Contiv、Kuryr、Open Virtual Networking(OVN)、Project Calico、 VMware、Weave和Plumgrid等項目采納。另外,Weave、Project Calico、Kuryr和Plumgrid等項目也為CNM提供了網絡插件的具體實現。
? ??CNM模型主要通過Network Sandbox、Endpoint和Network這3個組件進行實現,
?
◎ Network Sandbox:容器內部的網絡棧,包括網絡接口、路由表、DNS等配置的管理。Sandbox可用Linux網絡命名空間、FreeBSD Jail等機制進行實現。一個Sandbox可以包含多個Endpoint。
◎ Endpoint:用于將容器內的Sandbox與外部網絡相連的網絡接口。可以使用veth對、Open vSwitch的內部port等技術進行實現。一個Endpoint僅能夠加入一個Network。
◎ Network:可以直接互連的Endpoint的集合。可以通過Linux網橋、VLAN等技術進行實現。一個Network包含多個Endpoint。
2.CNI模型
? ?CNI是由CoreOs公司公司提出的另一種容器網絡規范,現在已經被Kubernetes、rkt、Apache Mesos、Cloud Foundry和Kurma等項目采納。另外,Contiv Networking, Project Calico、Weave、SR-IOV、Cilium、Infoblox、Multus、Romana、Plumgrid和Midokura等項目也為CNI提供網絡插件的具體實現。下圖描述了容器運行環境與各種網絡插件通過CNI進行連接的模型。
? ? ? CNI定義的是容器運行環境與網絡插件之間的簡單接口規范,通過一個JSON Schema定義CNI插件提供的輸入和輸出參數。一個容器可以通過綁定多個網絡插件加入多個網絡中。
CNI規范概述
? ? ? ? CNI提供了一種應用容器的插件化網絡解決方案,定義對容器網絡進行操作和配置的規范,通過插件的形式對CNI接口進行實現。CNI是由rkt Networking Proposal發展而來的,試圖提供一種普適的容器網絡解決方案。CNI僅關注在創建容器時分配網絡資源,和在銷毀容器時刪除網絡資源,這使得CNI規范非常輕巧、易于實現,得到了廣泛的支持。
? ? ? 在CNI模型中只涉及兩個概念: 容器和網絡。
◎ 容器(Container):是擁有獨立Linux網絡命名空間的環境,例如使用Docker或rkt創建的容器。關鍵之處是容器需要擁有自己的Linux網絡命名空間,這是加入網絡的必要條件。
◎ 網絡(Network):表示可以互連的一組實體,這些實體擁有各自獨立、唯一的IP地址,可以是容器、物理機或者其他網絡設備(比如路由器)等。
? ? ? 對容器網絡的設置和操作都通過插件(Plugin)進行具體實現,CNI插件包括兩種類型:CNI Plugin和IPAM(IP Address Management)Plugin。CNI Plugin負責為容器配置網絡資源,IPAM Plugin負責對容器的IP地址進行分配和管理。IPAM Plugin作為CNI Plugin的一部分,與CNI Plugin一起工作。
CNI Plugin插件詳解
? ? CNI Plugin包括3個基本接口的定義:添加(ADD)、刪除(DELETE)、檢查(CHECK)和版本查詢(VERSION)。這些接口的具體實現要求插件提供一個可執行的程序,在容器網絡添加或刪除時進行調用,以完成具體的操作。
? (1)添加:將容器添加到某個網絡。主要過程為在Container Runtime創建容器時,先創建好容器內的網絡命名空間(Network Namespace),然后調用CNI插件為該netns進行網絡配置,最后啟動容器內的進程。
添加接口的參數如下:
◎ Version:CNI版本號。
◎ ContainerID: 容器ID。
◎ Network namespace path:容器的網絡命名空間路徑,例如/proc/[pid]/ns/net。
◎ Network configuration:網絡配置JSON文檔,用于描述容器待加入的網絡。
◎ Extra arguments:其他參數,提供基于容器的CNI插件簡單配置機制。
◎ Name of the interface inside the container:容器內的網卡名。
返回的信息如下。
◎ Interfaces list:網卡列表,根據Plugin的實現,可能包括Sandbox Interface名稱、主機Interface名稱、每個Interface的地址等信息。
◎ IPs assigned to the interface:IPv4或者IPv6地址、網關地址、路由信息等。
◎ DNS information:DNS相關的信息。
(2)刪除:容器銷毀時將容器從某個網絡中刪除。
刪除接口的參數如下:
◎ Version:CNI版本號。
◎ ContainerID: 容器ID。
◎ Network namespace path:容器的網絡命名空間路徑,例如/proc/[pid]/ns/net。
◎ Network configuration:網絡配置JSON文檔,用于描述容器待加入的網絡。
◎ Extra arguments:其他參數,提供基于容器的CNI插件簡單配置機制。
◎ Name of the interface inside the container:容器內的網卡名。
(3)檢查:檢查容器網絡是否正確設置。
檢查接口的參數如下:
◎ ContainerID: 容器ID。
◎ Network namespace path:容器的網絡命名空間路徑,例如/proc/[pid]/ns/net。
◎ Network configuration:網絡配置JSON文檔,用于描述容器待加入的網絡。
◎ Extra arguments:其他參數,提供基于容器的CNI插件簡單配置機制。
◎ Name of the interface inside the container:容器內的網卡名。
(4)版本查詢:查詢網絡插件支持的CNI規范版本號。
無參數,返回值為網絡插件支持的CNI規范版本號。
? ? ? CNI插件應能夠支持通過環境變量和標準輸入傳入參數。可執行文件通過網絡配置參數中的type字段標識的文件名在環境變量CNI_PATH設定的路徑下進行查找。一旦找到,容器運行時將調用該可執行程序,并傳入以下環境變量和網絡配置參數,供該插件完成容器網絡資源和參數的設置。
環境變量參數如下:
◎ CNI_COMMAND:接口方法,包括ADD、DEL和VERSION。
◎ CNI_CONTAINERID:容器ID。
◎ CNI_NETNS:容器的網絡命名空間路徑,例如/proc/[pid]/ns/net。
◎ CNI_IFNAME:待設置的網絡接口名稱。
◎ CNI_ARGS:其他參數,為key=value格式,多個參數之間用分號分隔,例如"FOO=BAR; ABC=123"。
◎ CNI_PATH:可執行文件的查找路徑,可以設置多個。
網絡配置參數則由一個JSON報文組成,以標準輸入(stdin)的方式傳遞給可執行程序。
網絡配置參數如下:
◎ name(string): 網絡名稱,應在一個管理域內唯一。
◎ type(string):CNI插件的可執行文件的名稱。
◎ args(dictionary):其他參數。
◎ ipMasq(boolean):是否設置IP Masquerade(需插件支持),適用于主機可作為網關的環境中。
◎ ipam:IP地址管理的相關配置。
- type(string):IPAM可執行的文件名。
◎ dns:DNS服務的相關配置。
nameservers(list of strings):名字服務器列表,可以使用IPv4或IPv6地址。
- domain(string):本地域名,用于短主機名查詢。
- search(list of strings):按優先級排序的域名查詢列表。
- options(list of strings):傳遞給resolver的選項列表。
下面的例子定義了一個名為dbnet的網絡配置參數,IPAM使用host-local進行設置:
{"cniVersion": "0.4.0","name": "dbnet","type": "bridge","bridge": "cni0","ipam": {"type": "host-local","subnet": "10.1.0.0/16","gateway": "10.1.0.1"}, "dns": {"nameservers": ["10.1.0.1"]}}3.IPAM Plugin插件詳解
? ? ? 為了減輕CNI Plugin對IP地址管理的負擔,在CNI規范中設置了一個新的插件專門用于管理容器的IP地址(還包括網關、路由等信息),被稱為IPAM Plugin。通常由CNI Plugin在運行時自動調用IPAM Plugin完成容器IP地址的分配。
? ? ?IPAM Plugin負責為容器分配IP地址、網關、路由和DNS,典型的實現包括host-local和dhcp。與CNI Plugin類似,IPAM插件也通過可執行程序完成IP地址分配的具體操作。IPAM可執行程序也處理傳遞給CNI插件的環境變量和標準輸入(stdin)傳入的網絡配置參數。
? ? ?如果成功完成了容器IP地址的分配,則IPAM插件應該通過標準輸出(stdout)返回以下JSON報文:
? ??
{"cniVersion": "0.4.0","ips":[{"version": "<4-or-6>","address": "<ip-and-prefix-in-CIDR>","gateway": "<ip-address-of-the-gateway>" (optional)},..........],"routes":[{"dst": "<ip-and-prefix-in-cidr>","gw": "<ip-of-next-hop>"},........]"dns":{"nameservers": <list-of-nameservers> (optional)"domain": <name-of-local-domain> (optional)"search": <list-of-options> (optional)} }?
其中包括ips、routes和dns三段內容。
◎? ?ips段:分配給容器的IP地址(也可能包括網關)。
◎ routes段:路由規則記錄。
◎ dns段:DNS相關的信息。
4.多網絡插件
? ?在很多情況下,一個容器需要連接多個網絡,CNI規范支持為一個容器運行多個CNI Plugin來實現這個目標。多個網絡插件將按照網絡配置列表中的順序執行,并將前一個網絡配置的執行結果傳遞給后面的網絡配置。多網絡配置用JSON報文進行配置,包括如下信息。
◎ cniVersion(string):CNI版本號。
◎ name(string):網絡名稱,應在一個管理域內唯一,將用于下面的所有Plugin。
◎ plugins(list):網絡配置列表。
下面的例子定義了兩個網絡配置參數,分別作用于兩個插件,第1個為bridge,第2個為tuning。CNI將首先執行第1個bridge插件設置容器的網絡,然后執行第2個tuning插件:
{"cniVersion": "0.4.1","name": "dbnet","plugins": [{"type": "bridge",// type (plugin) specific"bridge": "cni0",// args may be ignored by plugins"args": {"labels": {"appVersion": "1.0"}},"ipam": {"type": "host-local",// ipam specific"subnet": "10.1.0.0/16","gateway": "10.1.0.1"},"dns": {"nameserver": [ "10.1.0.1" ]}},{"type": "tuning","sysctl": {"net.core.somaxconn": "500"}}] }在容器運行且執行第1個bridge插件時,網絡配置參數將被設置為:
{"cniVersion": "0.4.1","name": "dbnet","type": "bridge","bridge": "cni0","args": {"labels": {"appVersion": "1.0"}},"ipam": {"type": "host-local","subnet": "10.1.0.0/16","gateway": "10.1.0.1"},"dns": {"nameservers": [ "10.1.0.1" ]} }接下來執行第2個tuning插件,網絡配置參數將被設置為:
{"cniVersion": "0.4.1","name": "dbnet","type": "tuning","sysctl": {"net.core.somaxconn": "500"},"prevResult": {"ips": [{"version": "4","address": "10.0.0.5/32""interface": 2} ] ,"interfaces": [{"name": "cni0","mac": :"xxxx",},{"name": "veth3243","nac":"xxxx",},{"name": "eth0","mac":"xxxx","sandbox":"/var/ryb/netns/blue",}],"dbs":{"baneservers": ["10.1.0.1"] }} }? ? ?其中,prevResult字段包含的信息為上一個bridge插件執行的結果。
? ? ?在刪除多個CNI Plugin時,則以逆序執行刪除操作,以上例為例,將先刪除tuning插件的網絡配置,其中prevResult字段包含的信息為新增操作(ADD)時補充的信息:
{"cniVersion": "0.4.0","name": "dbnet","type": "tuning","sysctl": {"net.core.somaxconn": "500"},"prevResult":{"ips":["version": "4","address": "10.0.0.5/32""interface": 2],"interfaces": [{"name": "cni0","mac": :"xxxx",},{"name": "veth3243","nac":"xxxx",},{"name": "eth0","mac":"xxxx","sandbox":"/var/ryb/netns/blue",}],"dbs":{"baneservers": ["10.1.0.1"] }} }然后刪除bridge插件的網絡配置,其中prevResult字段包含的信息也是在新增操作(ADD)時補充的信息:
{"cniVersion": "0.4.1","name": "dbnet","type": "bridge","vridge": "cni0""agrs" :{"appVersion": "1.0"},"ipam": {"type": "host-local",// ipam specific"subnet": "10.1.0.0/16","gateway": "10.1.0.1"},"dns": {"nameserver": [ "10.1.0.1" ]},"prevResult":{"ips":["version": "4","address": "10.0.0.5/32""interface": 2],"interfaces": [{"name": "cni0","mac": :"xxxx",},{"name": "veth3243","nac":"xxxx",},{"name": "eth0","mac":"xxxx","sandbox":"/var/ryb/netns/blue",}],"dbs":{"baneservers": ["10.1.0.1"] }] }命令返回信息說明
? ? ?對于ADD或DELETE操作,返回碼為0表示執行成功,非0表示失敗,并以JSON報文的格式通過標準輸出(stdout)返回操作的結果。
? ? ?以ADD操作為例,成功將容器添加到網絡的結果將返回以下JSON報文。其中ips、routes和dns段的信息應該與IPAM Plugin(IPAM Plugin的說明詳見下節)返回的結果相同,重要的是interfaces段,應通過CNI Plugin進行設置并返回。
?
?
? 接口調用失敗時,返回碼不為0,應通過標準輸出返回包含錯誤信息的如下JSON報文:
??
{"cniVersion": "0.4.0","code": <numeric-error-code>,"msg": <short-error-message>,"details": <long-error-message> (optional) }錯誤碼包括如下內容。
◎ CNI版本不匹配。
◎ 在網絡配置中存在不支持的字段,詳細信息應在msg中說明。
?
?
小結:
?本章內容大家作文了解即可。
謝謝大家的支持與瀏覽
?
總結
以上是生活随笔為你收集整理的带你玩转kubernetes-k8s(第46篇:深入分析k8s网络原理[CNM、CNI]网络模型)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 修改文件中的某个字段
- 下一篇: flutter复制口令返回app监听粘贴