Container Network Interface(CNI)的基本思想,是先創建好網路命名空間 (netns) ,然後調用外掛程式,替這個網路命名空間配置網路,之後再啟動容器內的進程。 CNI 通過 Json Schema 描述當前容器網路的配置,實現標準化。專注於

  • 創建容器時分配 IP、網段等等
  • 容器被回收時刪除網路資源

CNI 作為 Kubernetes 和底層網路之間的一個抽象存在,遮罩了底層網路實現的細節、實現了 Kubernetes 和具體網路實現方案的解耦。


Kubernetes 中有運行著 Pod 的時後,可以通過 ssh 登錄到 cluster 中的任何一個節點上,然後進行如下做,都是可以做到的 !

  • 使用 kubectl get pods ,都能夠拿到 Pod 的資訊,不論這個 Pod 是被分配到哪個節點上
  • 另外也可以使用諸如 curl 之類的工具,向任意 Pod IP 地址發出請求,不論這個 Pod 是被分配到哪個節點上,都可以成功通信

以上是整個 k8s 預設的網路架構就能達到的事情。

網路模型

Kubernetes 網路模型遵循的一些核心規範原則,稱 IP-Per-Pod 模型 :

  • 每個 Pod 都擁有一個唯一且獨立的 IP 位址,且不論在 Pod 內部還是外部,IP 和埠資訊都是一致的
  • 只要 Pod 在同一個 cluster 內,即使 Pod 不在同一個 node 節點上,也可以通過單純 Pod IP 的方式直接訪問
  • 任意節點上的 Pod 可以在不藉助 NAT 的情況下與任意節點上的任意 Pod 進行通信
  • 節點上的代理(諸如系統守護進程、kubelet等)可以在不藉助 NAT的 情況下與該節點上的任意Pod進行通信

這個模型可以很好的相容現有的應用架構,類似像有虛擬機,且每個有自己獨立的 IP ,彼此之間可以還可以相互通信。

因為和原始 VM 網路架構類似,可以比較好的相容遷移到Kubernetes集群上,降低成本和風險。


Container Network Interface 歷史簡介

因為並非所有的 Kubernetes 集群都部署在 GCE、AWS、Azure 等有良好的 VPC 的雲端架構上,且 Kubernetes 僅關注容器編排的部分,網路管理並不是它原本分內的。故在私有雲的部署方案也日漸增多情況下,如何保證集群網路可以滿足 IP-Per-Pod 模型要求就成為了一個首要問題。

起初 Kubernetes 通過開發 Kubenet 來實現網路管理功能。 Kubenet 是一個基礎的網路外掛程式實現,本身並不支援任何跨節點之間的網路通信和網路策略功能,且僅適用於 Linux 系統,所以為了解決這個問題一些公司做出一個更優秀的方案 :

  • CoreOs 公司的 CNI(Container Network Interface)
  • Docker 推出 CNM (Container Network Model)

最後 CoreOs 公司的 CNI 擊敗了 Docker 推出 CNM ,並成為了 Kubernetes 首選的網路外掛程式介面規範,現已成為 CNCF 主推的網絡模型。思想为:

  • container Runtime 在創建容器時,先創建好 network namespace ,然後調用 CNI 插件,為這個 netns 配置網路,之後再啟動容器內的進程。


Container Network Interface(CNI)

CNI規範只是一個規範,規定了如何連接容器編排系統和網路外掛程式以完成 Pod 網路管理,例如 Flannel、Calico、Weave 等,都是 CNI 規範的實現方案。 Kubernetes 藉助 CNI 外掛程式體系組合,滿足網路功能,在創建 Pod 的過程中:

  • Scheduler 選定了一個 Node 節點來運行新創建的 Pod
  • 該節點上的 kubelet 收到消息開始創建 Pod ,當涉及到網路部分時,首先會讀取/etc/cni/net.d下 CNI JSON 配置檔,獲得要使用的外掛程式
  • 進入外掛程式的目錄來執行二進位檔,之後 CNI 外掛程式會進入 Pod 的網路空間去設定 Pod 的網路。

參考資料