新聞中心
在最前,周末寫到這篇的時(shí)候我就發(fā)現(xiàn)可能是給自己挖了很大的坑,整個(gè) Kubernetes 網(wǎng)關(guān)相關(guān)的內(nèi)容會(huì)非常復(fù)雜且龐大。

成都創(chuàng)新互聯(lián)公司于2013年成立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目網(wǎng)站設(shè)計(jì)、做網(wǎng)站網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元繁昌做網(wǎng)站,已為上家服務(wù),為繁昌各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:18982081108
深入探索 Kubernetes 網(wǎng)絡(luò)模型和網(wǎng)絡(luò)通信
認(rèn)識(shí)一下容器網(wǎng)絡(luò)接口 CNI(本篇)
源碼分析:從 kubelet、容器運(yùn)行時(shí)看 CNI 的使用
從 Flannel 學(xué)習(xí) Kubernetes VXLAN 網(wǎng)絡(luò)
Cilium CNI 與 eBPF
...
看自己能學(xué)到哪一步~
在 《深入探索 Kubernetes 網(wǎng)絡(luò)模型和網(wǎng)絡(luò)通信》 文章中,我們介紹了網(wǎng)絡(luò)命名空間(network namespace) 如何在 Kubernetes 網(wǎng)絡(luò)模型中工作,通過示例分析 pod 間的流量傳輸路徑。整個(gè)傳輸過程需要各種不同組件的參與才完成,而這些組件與 pod 相同的生命周期,跟隨 pod 的創(chuàng)建和銷毀。容器的維護(hù)由 kubelet 委托給容器運(yùn)行時(shí)(container runtime)來完成,而容器的網(wǎng)絡(luò)命名空間則是由容器運(yùn)行時(shí)委托網(wǎng)絡(luò)插件完成。
創(chuàng)建 pod(容器)的網(wǎng)絡(luò)命名空間
創(chuàng)建接口
創(chuàng)建 veth 對(duì)
設(shè)置命名空間網(wǎng)絡(luò)
設(shè)置靜態(tài)路由
配置以太網(wǎng)橋接器
分配 IP 地址
創(chuàng)建 NAT 規(guī)則
...
上篇我們也提到不同網(wǎng)絡(luò)插件對(duì) Kubernetes 網(wǎng)絡(luò)模型有不同的實(shí)現(xiàn),主要集中在跨節(jié)點(diǎn)的 pod 間通信的實(shí)現(xiàn)上。用戶可以根據(jù)需要選擇合適的網(wǎng)絡(luò)插件,這其中離不開 CNI(container network interface)。這些網(wǎng)絡(luò)插件都實(shí)現(xiàn)了 CNI 標(biāo)準(zhǔn),可以與容器編排系統(tǒng)和運(yùn)行時(shí)良好的集成。
runtime-with-cni
CNI 是什么
CNI 是 CNCF 下的一個(gè)項(xiàng)目,除了提供了最重要的 規(guī)范[1] 、用來 CNI 與應(yīng)用集成的 庫(kù)[2]、實(shí)行 CNI 插件的 CLI `cnitool`[3],以及 可引用的插件[4]。本文發(fā)布時(shí),最新版本為 v1.1.2。
CNI 只關(guān)注容器的網(wǎng)絡(luò)連接以及在容器銷毀時(shí)清理/釋放分配的資源,也正因?yàn)檫@個(gè),即使容器發(fā)展迅速,CNI 也依然能保證簡(jiǎn)單并被 廣泛支持[5]。
CNI 規(guī)范
CNI 的規(guī)范涵蓋了以下幾部分:
網(wǎng)絡(luò)配置文件格式
容器運(yùn)行時(shí)與網(wǎng)絡(luò)插件交互的協(xié)議
插件的執(zhí)行流程
將委托其他插件的執(zhí)行流程
返回給運(yùn)行時(shí)的執(zhí)行結(jié)果數(shù)據(jù)類型
1. 網(wǎng)絡(luò)配置格式
這里貼出規(guī)范中的配置示例,規(guī)范[6] 中定義了網(wǎng)絡(luò)配置的格式,包括必須字段、可選字段以及各個(gè)字段的功能。示例使用定義了名為 dbnet? 的網(wǎng)絡(luò),配置了插件 bridge? 和 tuning,這兩個(gè)插件。
CNI 的插件一般分為兩種:
接口插件(interface plugin):用來創(chuàng)建網(wǎng)絡(luò)接口,比如示例中的bridge。
鏈?zhǔn)讲寮╟hained):用來調(diào)整已創(chuàng)建好的網(wǎng)絡(luò)接口,比如示例中的tuning。
{
"cniVersion": "1.0.0",
"name": "dbnet",
"plugins": [
{
"type": "bridge",
// plugin specific parameters
"bridge": "cni0",
"keyA": ["some more", "plugin specific", "configuration"],
"ipam": {
"type": "host-local",
// ipam specific
"subnet": "10.1.0.0/16",
"gateway": "10.1.0.1",
"routes": [
{"dst": "0.0.0.0/0"}
]
},
"dns": {
"nameservers": [ "10.1.0.1" ]
}
},
{
"type": "tuning",
"capabilities": {
"mac": true
},
"sysctl": {
"net.core.somaxconn": "500"
}
},
{
"type": "portmap",
"capabilities": {"portMappings": true}
}
]
}2. 容器運(yùn)行時(shí)與網(wǎng)絡(luò)插件交互的協(xié)議
CNI 為容器運(yùn)行時(shí)提供 四個(gè)不同的操作[7]:
ADD - 將容器添加到網(wǎng)絡(luò),或修改配置
DEL - 從網(wǎng)絡(luò)中刪除容器,或取消修改
CHECK - 檢查容器網(wǎng)絡(luò)是否正常,如果容器的網(wǎng)絡(luò)出現(xiàn)問題,則返回錯(cuò)誤
VERSION - 顯示插件的版本
規(guī)范對(duì)操作的輸入和輸出內(nèi)容進(jìn)行了定義。主要幾個(gè)核心的字段有:
CNI_COMMAND:上面的四個(gè)操作之一
CNI_CONTAINERID:容器 ID
CNI_NETNS:容器的隔離域,如果用的網(wǎng)絡(luò)命名空間,這里的值是網(wǎng)絡(luò)命名空間的地址
CNI_IFNAME?:要在容器中創(chuàng)建的接口名,比如 eth0
CNI_ARGS:執(zhí)行參數(shù)時(shí)傳遞的參數(shù)
CNI_PATH:插件可執(zhí)行文件的朝招路徑
3. 插件的執(zhí)行流程
CNI 將容器上網(wǎng)絡(luò)配置的 ADD、DELETE? 和 CHECK 操作,成為附加(attachment)。
容器網(wǎng)絡(luò)配置的操作,需要一個(gè)或多個(gè)插件的共同操作來完成,因此插件有一定的執(zhí)行順序。比如前面的示例配置中,要先創(chuàng)建接口,才能對(duì)接口進(jìn)行調(diào)優(yōu)。
拿 ADD? 操作為例,首先執(zhí)行的一般是 interface plugin?,然后在執(zhí)行 chained plugin?。以前一個(gè)插件的 輸出 PrevResult? 與下一個(gè)插件的配置會(huì)共同作為下一個(gè)插件的 輸入。 如果是第一個(gè)插件,會(huì)將網(wǎng)絡(luò)配置作為輸入的一部分。插件可以將前一個(gè)插件的 PrevResult? 最為自己的輸出,也可以結(jié)合自身的操作對(duì) PrevResult? 進(jìn)行更新。最后一個(gè)插件的輸出 PrevResult 作為 CNI 的執(zhí)行結(jié)果返回給容器運(yùn)行時(shí),容器運(yùn)行時(shí)會(huì)保存改結(jié)果并將其作為其他操作的輸入。
DELETE? 的執(zhí)行與 ADD? 的順序正好相反,要先移除接口上的配置或者釋放已經(jīng)分配的 IP,最后才能刪除容器網(wǎng)絡(luò)接口。DELETE? 操作的輸入就是容器運(yùn)行時(shí)保存的 ADD 操作的結(jié)果。
cni-plugin-execution-flow
除了定義單次操作中插件的執(zhí)行順序,CNI 還對(duì)操作的并行操作、重復(fù)操作等進(jìn)行了說明[8]。
4. 插件委托
有一些操作,無論出于何種原因,都不能合理地作為一個(gè)松散的鏈接插件來實(shí)現(xiàn)。相反,CNI 插件可能希望將某些功能委托給另一個(gè)插件。一個(gè)常見的例子是 IP 地址管理(IP Adress Management,簡(jiǎn)稱 IPAM),主要是為容器接口分配/回收 IP 地址、管理路由等。
CNI 定義了第三種插件 -- IPAM 插件。CNI 插件可以在恰當(dāng)?shù)臅r(shí)機(jī)調(diào)用 IPAM 插件,IPAM 插件會(huì)將執(zhí)行的結(jié)果返回給委托方。IPAM 插件會(huì)根據(jù)指定的協(xié)議(如 dhcp)、本地文件中的數(shù)據(jù)、或者網(wǎng)絡(luò)配置文件中 ipam 字段的信息來完成操作:分配 IP、設(shè)置網(wǎng)關(guān)、路由等等。
"ipam": {
"type": "host-local",
// ipam specific
"subnet": "10.1.0.0/16",
"gateway": "10.1.0.1",
"routes": [
{"dst": "0.0.0.0/0"}
]
}5. 執(zhí)行結(jié)果
插件可以返回一下三種結(jié)果之一,規(guī)范對(duì) 結(jié)果的格式[9] 進(jìn)行了定義。
Success:同時(shí)會(huì)包含PrevResult? 信息,比如 ADD? 操作后的 PrevResult 返回給容器運(yùn)行時(shí)。
Error:包含必要的錯(cuò)誤提示信息。
Version:這個(gè)是VERSION 操作的返回結(jié)果。
庫(kù)
CNI 的庫(kù)是指 `libcni`[10],用于 CNI 和應(yīng)用程序集成,定義了 CNI 相關(guān)的接口和配置。
type CNI interface {
AddNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
CheckNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) error
DelNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) error
GetNetworkListCachedResult(net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
GetNetworkListCachedConfig(net *NetworkConfigList, rt *RuntimeConf) ([]byte, *RuntimeConf, error)
AddNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
CheckNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error
DelNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error
GetNetworkCachedResult(net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
GetNetworkCachedConfig(net *NetworkConfig, rt *RuntimeConf) ([]byte, *RuntimeConf, error)
ValidateNetworkList(ctx context.Context, net *NetworkConfigList) ([]string, error)
ValidateNetwork(ctx context.Context, net *NetworkConfig) ([]string, error)
}以添加網(wǎng)絡(luò)的部分代碼為例:
func (c *CNIConfig) addNetwork(ctx context.Context, name, cniVersion string, net *NetworkConfig, prevResult types.Result, rt *RuntimeConf) (types.Result, error) {
...
return invoke.ExecPluginWithResult(ctx, pluginPath, newConf.Bytes, c.args("ADD", rt), c.exec)
}執(zhí)行的邏輯簡(jiǎn)單來說就是:
查找可執(zhí)行文件
加載網(wǎng)絡(luò)配置
執(zhí)行ADD 操作
結(jié)果處理
總結(jié)
這篇學(xué)習(xí)了 CNI 規(guī)范的內(nèi)容、網(wǎng)絡(luò)插件的執(zhí)行流程,對(duì) CNI 抽象的網(wǎng)絡(luò)管理接口有了大致的了解。
下一篇將結(jié)合源碼的分析,了解 kubelet、容器運(yùn)行時(shí)、CNI 網(wǎng)絡(luò)插件之間如何進(jìn)行交互。
參考
https://www.tigera.io/learn/guides/kubernetes-networking/kubernetes-cni/
https://github.com/containernetworking/cni
https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/
參考資料
[1]
規(guī)范: https://github.com/containernetworking/cni/blob/main/SPEC.md
[2]
庫(kù): https://github.com/containernetworking/cni/blob/main/libcni
[3]
cnitool?: https://github.com/containernetworking/cni/blob/main/cnitool
[4]
可引用的插件: https://github.com/containernetworking/plugins
[5]
廣泛支持: https://github.com/containernetworking/cni/blob/main/README.md#who-is-using-cni
[6]
規(guī)范: https://github.com/containernetworking/cni/blob/main/SPEC.md#section-1-network-configuration-format
[7]
四個(gè)不同的操作: https://github.com/containernetworking/cni/blob/master/SPEC.md#cni-operations
[8]
CNI 還對(duì)操作的并行操作、重復(fù)操作等進(jìn)行了說明: https://github.com/containernetworking/cni/blob/main/SPEC.md#lifecycle--ordering
[9]
結(jié)果的格式: https://github.com/containernetworking/cni/blob/main/SPEC.md#section-5-result-types
[10]
libcni?: https://github.com/containernetworking/cni/tree/main/libcni
新聞標(biāo)題:認(rèn)識(shí)一下容器網(wǎng)絡(luò)接口CNI
文章出自:http://m.fisionsoft.com.cn/article/cdigieh.html


咨詢
建站咨詢
