Kubernetes 理解筆記之網絡模型及CNI插件


Kubernetes 容器網絡確實是一塊比較複雜的內容,本文是在學習張磊老師《深入剖析 Kubernetes》之後的理解整理,內容主要總結了 Kubernetes 網絡模型和 CNI 插件,後面也介紹了容器跨主機網絡的三種方案。



Kubernetes 網絡模型

1、本地容器間通信原理

爲什麼需要網絡? 本質是爲了連通然後通信。

爲什麼容器之間需要網絡?每一個容器進程被 Network Namespace 隔離,都有一套獨立的“網絡棧”,是無法直接跟其他 Network Namespace 裏的容器進程進行交互的。

容器之間如何通信:(分爲單機與跨主機)

1)單機上容器間通信:【Veth Pair 設備 + 宿主機網橋】

宿主機上創建一個網橋,起虛擬交換機作用,主要功能是根據 MAC 地址學習來將數據包轉發到網橋的不同端口(Port)上。然後利用 Linux 的 Veth Pair 的虛擬設備,將所有容器”連接“到這個網橋上。

在這裏插入圖片描述
注:綠色部分即爲 Veth Pair 設備,都是成對出現,一端在容器內充當默認網卡,另一端在宿主機上並插在了 docker0 這個網橋上。

Veth Pair 設備的特點是:它被創建出來後,總是以兩張虛擬網卡(Veth Peer)的形式成對出現的。並且,從其中一個“網卡”發出的數據包,可以直接出現在與它對應的另一張“網卡”上,哪怕這兩個“網卡”在不同的 Network Namespace 裏。

2)難點在於”容器跨主機通信“:【Overlay Network 覆蓋網絡】

集羣中的容器是分佈在不同主機上的,所以需要一個容器網絡。在已有的宿主機網絡上,再通過軟件構建一個覆蓋在已有宿主機網絡之上的、可以把所有容器連通在一起的虛擬網絡。所以,這種技術就被稱爲:Overlay Network(覆蓋網絡)

在這裏插入圖片描述
實現方式主要有三種:VXLAN、host-gw、UDP。具體內容可看本文最後的補充知識。

2、Kubernetes 網絡模型設計

Kubernetes 網絡模型:

  • 所有容器都可以直接使用 IP 地址與其他容器通信,而無需使用 NAT。
  • 所有宿主機都可以直接使用 IP 地址與所有容器通信,而無需使用 NAT。反之亦然。
  • 容器自己“看到”的自己的 IP 地址,和別人(宿主機或者容器)看到的地址是完全一樣的。

網絡模型架構:

  1. CNI 網橋:Kubernetes 維護一個 cni 網橋,能夠起到虛擬交換機作用的網絡設備,使連接到上面的容器可以通過它在本地進行通信。
  2. Veth Pair:利用 Linux 的 Veth Pair 虛擬設備,使容器“連接”到 cni 網橋上。
  3. CNI 網絡插件 創建了一個特殊的設備(UDP 模式創建的是 TUN 設備,VXLAN 模式創建的則是 VTEP 設備),通過某種方法把不同宿主機上的特殊設備連通,從而達到容器跨主機通信。
    在這裏插入圖片描述

個人理解,網絡模型的核心是一個網絡插件來達到容器跨主機通信,想要使用這個插件自然就需要接口,這就是 CNI 了。

CNI 網絡插件

CNI 設計思想

CNI 網絡插件不僅負責搭建起來一個“覆蓋網絡”實現容器跨主機通信,也需要提供接口在每次 kubelet 創建容器時可以設置容器加入到這個網絡模型中。
Kubernetes 創建一個 Pod 的時候,它第一個創建的一定是 Infra 容器。所以在這一步,kubelet 就可以通過 CRI 創建並啓動 Infra 容器,緊接着執行一個叫作 SetUpPod 的方法。這個方法的作用就是:爲 CNI 插件準備參數,然後調用 CNI 插件爲 Infra 容器配置網絡。

CNI 插件部署實現

安裝 kubernetes-cni 包,提供三類CNI 的基礎可執行文件:

  • 第一類,叫作 Main 插件,它是用來創建具體網絡設備的二進制文件。比如,bridge(網橋設備)、ipvlan、loopback(lo 設備)、macvlan、ptp(Veth Pair 設備),以及 vlan。
  • 第二類,叫作 IPAM(IP Address Management)插件,它是負責分配 IP 地址的二進制文件。比如,dhcp,這個文件會向 DHCP 服務器發起請求;host-local,則會使用預先配置的 IP 地址段來進行分配。
  • 第三類,是由 CNI 社區維護的內置 CNI 插件。用來實現一個給 Kubernetes 用的容器網絡方案,通常需要兩部分工作:
    (1)首先,實現這個網絡方案本身。這一部分需要編寫的,其實就是 flanneld 進程裏的主要邏輯。比如,創建和配置 flannel.1 設備、配置宿主機路由、配置 ARP 和 FDB 表裏的信息等等。
    (2)然後,實現該網絡方案對應的 CNI 插件。這一部分主要需要做的,就是配置 Infra 容器裏面的網絡棧,並把它連接在 CNI 網橋上。

補充:三種容器跨主機通信方案

這裏關注一個核心問題(感覺是容器跨主機通信的核心點):就是容器 IP 與其所在 Node IP的對應,也就是有了容器的 IP 如何知道它是運行在哪個 Node 上的。

解決容器的跨主機通信問題,都是爲了構建覆蓋網絡。Flannel 項目是 CoreOS 公司主推的容器網絡方案,這裏從 Flannel 項目整理三種主流實現方案:

1、UDP(方案開銷大)

  • "容器IP與其node對應" 這一核心問題解決
    一臺宿主機上的所有容器,都應該屬於該宿主機被分配的一個“子網”,而這些子網與宿主機的對應關係,保存在 Etcd 當中。也就是說 docker0 網橋的地址範圍必須是 Flannel 爲宿主機分配的子網。
    UDP模式下會運行一個 flanneld 用戶進程處理由容器傳出的 IP 包,可以根據目的容器 IP 的地址,匹配到對應的子網,然後從 Etcd 中找到這個子網對應的宿主機的 IP 地址,完成映射。

  • 另外,會利用 Linux 中的TUN 設備(Tunnel 設備)。它會把收到的 IP 包交給創建這個設備的應用程序,實現操作系統內核和用戶應用程序之間傳遞 IP 包。
    在 Linux 中,TUN 設備是一種工作在三層(Network Layer)的虛擬網絡設備。TUN 設備的功能非常簡單,即:在操作系統內核和用戶應用程序之間傳遞 IP 包。

- 實例:基於 Flannel UDP 模式的跨主通信的基本原理

在這裏插入圖片描述
解釋:

IP 包從容器經過 docker0 出現在宿主機,然後又根據路由表進入 flannel0 設備後,flannel0 會把收到的 IP 包交給創建這個設備的應用程序,所以宿主機上的 flanneld 進程(Flannel 項目在每個宿主機上的主進程)就會收到這個 IP 包。

然後,flanneld 進程在處理由 flannel0 傳入的 IP 包時,就可以根據目的 IP 的地址(比如 100.96.2.3),匹配到對應的子網(比如 100.96.2.0/24),從 Etcd 中找到這個子網對應的宿主機的 IP 地址是 10.168.0.3。

之後 flanneld 進程就可以進行 UDP 封裝通過宿主機的 eth0 網卡發送出去了。到了目的主機flanneld 進程監聽的端口後,再進行解封裝。

- 開銷分析:

在這裏插入圖片描述
如上圖,Flannel UDP 模式僅在發出 IP 包的過程中,就需要經過三次用戶態與內核態之間的數據拷貝,然後Flannel 進行 UDP 封裝(Encapsulation)和解封裝(Decapsulation)的過程,也都是在用戶態完成的。
上下文切換和用戶態操作的代價其實是比較高的,所以造成 Flannel UDP 模式性能不好。

2、VXLAN(主流方案)

VXLAN,即 Virtual Extensible LAN(虛擬可擴展局域網),是 Linux 內核本身就支持的一種網絡虛似化技術。所以說,VXLAN 可以完全在內核態實現上述封裝和解封裝的工作,從而通過與前面相似的“隧道”機制,構建出覆蓋網絡(Overlay Network)。

- 實例:基於 Flannel VXLAN 模式的跨主通信的基本原理

在這裏插入圖片描述
解釋:

圖中每臺宿主機上名叫 flannel.1 的設備,就是 VXLAN 所需的 VTEP 設備,它既有 IP 地址,也有 MAC 地址。

step1:當 container-1 發出請求之後,這個目的地址是 10.1.16.3 的 IP 包,會先出現在 docker0 網橋,然後被路由到本機 flannel.1 設備進行處理。

step2:當有 Node 啓動並加入 Flannel 網絡時,每臺宿主機上的 flanneld 進程會負責維護一些信息:
1)維護路由規則:查到要發往的容器網絡網關IP(也就是目的VTEP的IP地址),10.1.16.0
2)維護ARP表:通過目的網關IP(10.1.16.0)得到“目的 VTEP 設備”的 MAC 地址
3)維護叫做 FDB(Forwarding Database)的轉發數據庫:通過“目的 VTEP 設備”的 MAC 地址查到要發往的目的主機 IP,10.168.0.3。

step3:查到目的主機IP後,封包。Node 1 上的 flannel.1 設備就可以把這個數據幀從 Node 1 的 eth0 網卡發出去。顯然,這個幀會經過宿主機網絡來到 Node 2 的 eth0 網卡。

在這裏插入圖片描述
step4:Node 2 收到數據幀後,內核網絡棧會發現這個數據幀裏有 VXLAN Header,並且 VNI=1。所以 Linux 內核會對它進行拆包,拿到裏面的內部數據幀,然後根據 VNI 的值,把它交給 Node 2 上的 flannel.1 設備。而 flannel.1 設備則會進一步拆包,取出“原始 IP 包”。最終,IP 包就進入到了 container-2 容器的 Network Namespace 裏。

- 容器IP與其node對應的核心問題解決:
每臺宿主機上的 flanneld 進程負責維護一系列信息。核心是叫做 FDB(Forwarding Database)的轉發數據庫,可以通過“目的 VTEP 設備”的 MAC 地址查到要發往的目的主機 IP,而 MAC 地址又可以通過自己維護的 ARP 表查到。

3、host-gw

host-gw 模式的工作原理,其實就是將每個 Flannel 子網(Flannel Subnet,比如:10.244.1.0/24)的“下一跳”,設置成了該子網對應的宿主機的 IP 地址。
利用一些機制來創建路由規則,並維護路由信息。

  • 實例1:Flannel host-gw 示意圖
    在這裏插入圖片描述
  • 實例2:Calico工作原理
    在這裏插入圖片描述

參考:《深入剖析Kubernetes | 極客時間》張磊,Kubernetes容器網絡

發佈了106 篇原創文章 · 獲贊 111 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章