天天看點

Kubernetes 網絡概念及政策控制(葉磊)

本文将主要分享以下 5 方面的内容:

  1. Kubernetes 基本網絡模型;
  2. Netns 探秘;
  3. 主流網絡方案簡介;
  4. Network Policy 的用處;
  5. 思考時間。

Kubernetes 基本網絡模型

本節來介紹一下 Kubernetes 對網絡模型的一些想法。大家知道 Kubernetes 對于網絡具體實作方案,沒有什麼限制,也沒有給出特别好的參考案例。Kubernetes 對一個容器網絡是否合格做出了限制,也就是 Kubernetes 的容器網絡模型。可以把它歸結為約法三章和四大目标。

  • 約法三章的意思是:在評價一個容器網絡或者設計容器網絡的時候,它的準入條件。它需要滿足哪三條? 才能認為它是一個合格的網絡方案。
  • 四大目标意思是在設計這個網絡的拓撲,設計網絡的具體功能的實作的時候,要去想清楚,能不能達成連通性等這幾大名額。

約法三章

先來看下約法三章:

  • 第一條:任意兩個 pod 之間其實是可以直接通信的,無需經過顯式地使用 NAT 來接收資料和位址的轉換;
  • 第二條:node 與 pod 之間是可以直接通信的,無需使用明顯的位址轉換;
  • 第三條:pod 看到自己的 IP 跟别人看見它所用的IP是一樣的,中間不能經過轉換。

後文中會講一下我個人的了解,為什麼 Kubernetes 對容器網絡會有一些看起來武斷的模型和要求。

四大目标

四大目标其實是在設計一個 K8s 的系統為外部世界提供服務的時候,從網絡的角度要想清楚,外部世界如何一步一步連接配接到容器内部的應用?

  • 外部世界和 service 之間是怎麼通信的?就是有一個網際網路或者是公司外部的一個使用者,怎麼用到 service?service 特指 K8s 裡面的服務概念。
  • service 如何與它後端的 pod 通訊?
  • pod 和 pod 之間調用是怎麼做到通信的?
  • 最後就是 pod 内部容器與容器之間的通信?

最終要達到目标,就是外部世界可以連接配接到最裡面,對容器提供服務。

對基本限制的解釋

對基本限制,可以做出這樣一些解讀:因為容器的網絡發展複雜性就在于它其實是寄生在 Host 網絡之上的。從這個角度講,可以把容器網絡方案大體分為 **Underlay/Overlay **兩大派别:

  • Underlay 的标準是它與 Host 網絡是同層的,從外在可見的一個特征就是它是不是使用了 Host 網絡同樣的網段、輸入輸出基礎裝置、容器的 IP 位址是不是需要與 Host 網絡取得協同(來自同一個中心配置設定或統一劃分)。這就是 Underlay;
  • Overlay 不一樣的地方就在于它并不需要從 Host 網絡的 IPM 的管理的元件去申請IP,一般來說,它隻需要跟 Host 網絡不沖突,這個 IP 可以自由配置設定的。
Kubernetes 網絡概念及政策控制(葉磊)

為什麼社群會提出 perPodperIP 這種簡單武斷的模型呢?我個人是覺得這樣為後面的 service 管理一些服務的跟蹤性能監控,帶來了非常多的好處。因為一個 IP 一貫到底,對 case 或者各種不大的事情都會有很大的好處。

Netns 探秘

Netns 究竟實作了什麼

下面簡單講一下,Network Namespace 裡面能網絡實作的核心基礎。狹義上來說 runC 容器技術是不依賴于任何硬體的,它的執行基礎就是它的核心裡面,程序的核心代表就是 task,它如果不需要隔離,那麼用的是主機的空間( namespace),并不需要特别設定的空間隔離資料結構( nsproxy-namespace proxy)。

Kubernetes 網絡概念及政策控制(葉磊)

相反,如果一個獨立的網絡 proxy,或者 mount proxy,裡面就要填上真正的私有資料。它可以看到的資料結構如上圖所示。

從感官上來看一個隔離的網絡空間,它會擁有自己的網卡或者說是網絡裝置。網卡可能是虛拟的,也可能是實體網卡,它會擁有自己的 IP 位址、IP 表和路由表、擁有自己的協定棧狀态。這裡面特指就是 TCP/Ip協定棧,它會有自己的status,會有自己的 iptables、ipvs。

從整個感官上來講,這就相當于擁有了一個完全獨立的網絡,它與主機網絡是隔離的。當然協定棧的代碼還是公用的,隻是資料結構不相同。

Pod 與 Netns 的關系

Kubernetes 網絡概念及政策控制(葉磊)

這張圖可以清晰表明 pod 裡 Netns 的關系,每個 pod 都有着獨立的網絡空間,pod net container 會共享這個網絡空間。一般 K8s 會推薦選用 Loopback 接口,在 pod net container 之間進行通信,而所有的 container 通過 pod 的 IP 對外提供服務。另外對于主控端上的 Root Netns,可以把它看做一個特殊的網絡空間,隻不過它的 Pid 是1。

主流網絡方案簡介

典型的容器網絡實作方案

接下來簡單介紹一下典型的容器網絡實作方案。容器網絡方案可能是 K8s 裡最為百花齊放的一個領域,它有着各種各樣的實作。容器網絡的複雜性,其實在于它需要跟底層 Iass 層的網絡做協調、需要在性能跟 IP 配置設定的靈活性上做一些選擇,這個方案是多種多樣的。

Kubernetes 網絡概念及政策控制(葉磊)

下面簡單介紹幾個比較主要的方案:分别是 Flannel、Calico、Canal ,最後是 WeaveNet,中間的大多數方案都是采用了跟 Calico 類似的政策路由的方法。

  • **Flannel **是一個比較大一統的方案,它提供了多種的網絡 backend。不同的 backend 實作了不同的拓撲,它可以覆寫多種場景;
  • **Calico **主要是采用了政策路由,節點之間采用 BGP 的協定,去進行路由的同步。它的特點是功能比較豐富,尤其是對 Network Point 支援比較好,大家都知道 Calico 對底層網絡的要求,一般是需要 mac 位址能夠直通,不能跨二層域;
  • 當然也有一些社群的同學會把 Flannel 的優點和 Calico 的優點做一些內建。我們稱之為嫁接型的創新項目 Cilium;
  • 最後講一下 WeaveNet,如果大家在使用中需要對資料做一些加密,可以選擇用 WeaveNet,它的動态方案可以實作比較好的加密。

Flannel 方案

Kubernetes 網絡概念及政策控制(葉磊)

Flannel 方案是目前使用最為普遍的。如上圖所示,可以看到一個典型的容器網方案。它首先要解決的是 container 的包如何到達 Host,這裡采用的是加一個 Bridge 的方式。它的 backend 其實是獨立的,也就是說這個包如何離開 Host,是采用哪種封裝方式,還是不需要封裝,都是可選擇的。

現在來介紹三種主要的 backend:

  • 一種是使用者态的 udp,這種是最早期的實作;
  • 然後是核心的 Vxlan,這兩種都算是 overlay 的方案。Vxlan 的性能會比較好一點,但是它對核心的版本是有要求的,需要核心支援 Vxlan 的特性功能;
  • 如果你的叢集規模不夠大,又處于同一個二層域,也可以選擇采用 host-gw 的方式。這種方式的 backend 基本上是由一段廣播路由規則來啟動的,性能比較高。

Network Policy 的用處

Network Policy 基本概念

下面介紹一下 Network Policy 的概念。

Kubernetes 網絡概念及政策控制(葉磊)

剛才提到了 Kubernetes 網絡的基本模型是需要 pod 之間全互聯,這個将帶來一些問題:可能在一個 K8s 叢集裡,有一些調用鍊之間是不會直接調用的。比如說兩個部門之間,那麼我希望 A 部門不要去探視到 B 部門的服務,這個時候就可以用到政策的概念。

基本上它的想法是這樣的:它采用各種選擇器(标簽或 namespace),找到一組 pod,或者找到相當于通訊的兩端,然後通過流的特征描述來決定它們之間是不是可以聯通,可以了解為一個白名單的機制。

在使用 Network Policy 之前,如上圖所示要注意 apiserver 需要打開一下這幾個開關。另一個更重要的是我們選用的網絡插件需要支援 Network Policy 的落地。大家要知道,Network Policy 隻是 K8s 提供的一種對象,并沒有内置元件做落地實施,需要取決于你選擇的容器網絡方案對這個标準的支援與否及完備程度,如果你選擇 Flannel 之類,它并沒有真正去落地這個 Policy,那麼你試了這個也沒有什麼用。

配置執行個體

Kubernetes 網絡概念及政策控制(葉磊)

接下來講一個配置的執行個體,或者說在設計一個 Network Policy 的時候要做哪些事情?我個人覺得需要決定三件事:

  • 第一件事是控制對象,就像這個執行個體裡面 spec 的部分。spec 裡面通過 podSelector 或者 namespace 的 selector,可以選擇做特定的一組 pod 來接受我們的控制;
  • 第二個就是對流向考慮清楚,需要控制入方向還是出方向?還是兩個方向都要控制?
  • 最重要的就是第三部分,如果要對選擇出來的方向加上控制對象來對它流進行描述,具體哪一些 stream 可以放進來,或者放出去?類比這個流特征的五元組,可以通過一些選擇器來決定哪一些可以作為我的遠端,這是對象的選擇;也可以通過 IPBlock 這種機制來得到對哪些 IP 是可以放行的;最後就是哪些協定或哪些端口。其實流特征綜合起來就是一個五元組,會把特定的能夠接受的流選擇出來 。

本節課總結

本節内容到這裡就結束了,我們簡單總結一下:

  • 在 pod 的容器網絡中核心概念就是 IP,IP 就是每個 pod 對外通訊的位址基礎,必須内外一緻,符合 K8s 的模型特征;
  • 那麼在介紹網絡方案的時候,影響容器網絡性能最關鍵的就是拓撲。要能夠了解你的包端到端是怎麼聯通的,中間怎麼從 container 到達 Host,Host 出了 container 是要封裝還是解封裝?還是通過政策路由?最終到達對端是怎麼解出來的?
  • 容器網絡選擇和設計選擇。如果你并不清楚你的外部網絡,或者你需要一個普适性最強的方案,假設說你對 mac 是否直連不太清楚、對外部路由器的路由表能否控制也不太清楚,那麼你可以選擇 Flannel 利用 Vxlan 作為 backend 的這種方案。如果你确信你的網絡是 2 層可直連的,你可以進行選用 Calico 或者 Flannel-Hostgw 作為一個 backend;
  • 最後就是對 Network Policy,在運維和使用的時候,它是一個很強大的工具,可以實作對進出流的精确控制。實作的方法我們也介紹了,要想清楚你要控制誰,然後你的流要怎麼去定義。

思考時間

最後留一些思考,大家可以想一想:

  1. 為什麼接口标準化 CNI 化了,但是容器網絡卻沒有一個很标準的實作,内置在 K8s 裡面?
  2. Network Policy 為什麼沒有一個标準的 controller 或者一個标準的實作,而是交給這個容器網絡的 owner 來提供?
  3. 有沒有可能完全不用網絡裝置來實作容器網絡呢?考慮到現在有 RDMA 等有别于 TCP/IP 的這種方案。
  4. 在運維過程中網絡問題比較多、也比較難排查,那麼值不值得做一個開源工具,讓它可以友好的展示從 container 到 Host 之間、Host 到 Host 之間,或者說封裝及解封裝之間,各個階段的網絡情況,有沒有出現問題,能夠快速的定位。據我所知應該現在是沒有這樣的工具的。

以上就是我對 K8s 容器網絡的基本概念、以及 Network Policy 的一些介紹,謝謝大家的觀看。

繼續閱讀