全景剖析阿里雲容器網路資料鏈路(三):Terway ENIIP

語言: CN / TW / HK

本系列文章由余凱執筆創作,聯合作者:阿里雲容器服務 謝石 對本文亦有貢獻

前言

近幾年,企業基礎設施雲原生化的趨勢越來越強烈,從最開始的 IaaS 化到現在的微服務化,客戶的顆粒度精細化和可觀測性的需求更加強烈。容器網路為了滿足客戶更高效能和更高的密度,也一直在高速的發展和演進中,這必然對客戶對雲原生網路的可觀測性帶來了極高的門檻和挑戰。為了提高雲原生網路的可觀測性,同時便於客戶和前後線同學增加對業務鏈路的可讀性,ACK 產研和 AES 聯合共建,合作開發 ack net-exporter 和雲原生網路資料面可觀測性系列,幫助客戶和前後線同學瞭解雲原生網路架構體系,簡化對雲原生網路的可觀測性的門檻,優化客戶運維和售後同學處理疑難問題的體驗 ,提高雲原生網路的鏈路的穩定性。

鳥瞰容器網路,整個容器網路可以分為三個部分:Pod 網段,Service 網段和Node 網段。這三個網路要實現互聯互通和訪問控制,那麼實現的技術原理是什麼?整個鏈路又是什麼,限制又是什麼呢?Flannel, Terway 有啥區別?不同模式下網路效能如何?這些,需要客戶在下搭建容器之前,就要依據自己的業務場景進行選擇,而搭建完畢後,相關的架構又是無法轉變,所以客戶需要對每種架構特點要有充分了解。比如下圖是個簡圖,Pod 網路既要實現同一個 ECS 的 Pod 間的網路互通和控制,又要實現不同 ECS Pod 間的訪問, Pod 訪問 SVC 的後端可能在同一個ECS 也可能是其他 ECS,這些在不同模式下,資料鏈轉發模式是不同的,從業務側表現結果也是不一樣的。

1.png

本文是[全景剖析容器網路資料鏈路]第三部分,主要介紹 Kubernetes Terway ENIIP 模式下,資料面鏈路的轉轉發鏈路,一是通過了解不同場景下的資料面轉發鏈路,從而探知客戶在不同的場景下訪問結果表現的原因,幫助客戶進一步優化業務架構;另一方面,通過深入瞭解轉發鏈路,從而在遇到容器網路抖動時候,客戶運維以及阿里雲同學可以知道在哪些鏈路點進行部署觀測手動,從而進一步定界問題方向和原因。

系列一:

全景剖析阿里雲容器網路資料鏈路(一)—— Flannel

系列二:

全景剖析阿里雲容器網路資料鏈路(二)—— Terway ENI

系列四:

全景剖析阿里雲容器網路資料鏈路(四)—— Terway IPVLAN+EBPF

系列五:

全景剖析阿里雲容器網路資料鏈路(五)—— Terway ENI-Trunking

系列六:

全景剖析阿里雲容器網路資料鏈路(六)—— ASM Istio

Terway ENIIP模式架構設計

彈性網絡卡 (ENI) 支援配置多個輔助 IP 的功能,單個彈性網絡卡 (ENI) 根據例項規格可以分配 6-20 個輔助 IP,ENI 多 IP 模式就是利用了這個輔助 IP 分配給容器,從而大幅提高了 Pod 部署的規模和密度。

在網路聯通的方式上,Terway 支援選擇 Veth pair 策略路由和ipvlan l兩種方案,Terway 主要考慮了這些:

  1. 在節點上如何把彈性網絡卡 (ENI) 的輔助 IP 的流量都走對應的彈性網絡卡出去,並使用彈性網絡卡本身的 mac 地址而不被丟包 

2.如何相容容器服務目前廣泛的 Centos 7.x 的 3.10 的版本的核心

2.png

Pod 所使用的的 CIDR 網段和節點的 CIDR 是同一個網段

3.png

Pod 內部可以看到是有一張網絡卡的,一個是 eth0,其中 eth0 的 IP 就是 Pod 的 IP,此網絡卡的 MAC 地址和控制檯上的 ENI 的 MAC 地址不一致,同時 ECS 上有多張 ethx 的網絡卡,說明 ENI 附屬網絡卡並不是直接掛在到了 Pod 的網路名稱空間

4.png

5.png

6.png

Pod 內有隻有指向 eth0 的預設路由,說明 Pod 訪問任何地址段都是從 eth0 為統一的出入口

7.png

如上圖所示,我們可以容器的網路名稱空間中通過 ip addr 看到一個 eth0@if63 的標誌位,其中 ‘63' 這個將會協助我們在 ECS 的 OS 內找到找到和容器網路名稱空間中的veth pair 相對一個。在 ECS OS 內我們通過 ip addr | grep 63: 可以找到 cali44ae9fbceeb 這個虛擬網絡卡,這個就是 veth pair 在 ECS OS 側相對的那一個。

8.png

ECS OS 內對於資料流量是怎麼判斷去哪個容器呢?通過 OS Linux Routing 我們可以看到,所有目的是 Pod  IP 的流量都會被轉發到 Pod 對應的 calico 虛擬往卡上,到這裡為止,ECS OS 和 Pod 的網路名稱空間已經建立好完整的出入鏈路配置了。

9.png

在 veth pair 中實現了多個 Pod 共享一個 ENI 的方式來提升了 ECS 的 Pod 部署密度,那麼如何知道 Pod 是被分配到哪個 ENI 呢?Terway Pod 是通過 daemonset 的方式部署在每個節點上的,通過下面命令可以看到每個節點上的 Terway Pod。通過 terway-cli show factory 命令可以看到節點上的附屬 ENI 數量、MAC 地址以及每個 ENI 上的 IP

10.png 11.png

故 Terway ENIIP 模式總體可以歸納為:

  • 在網路聯通的方式上,採用選擇 Veth pair 策略路由

  • 一對 veth pair 來聯通宿主機和 pod 的網路空間,pod 的地址是來源於彈性網絡卡的輔助 IP 地址,並且節點上需要配置策略路由來保證輔助 IP 的流量經過它所屬的彈性網絡卡。

  • 同主機上的容器通訊直接通過主機上的路由到同一個主機上別的容器對應的 veth 上

  • 不同主機的容器通訊經過 VPC 的網路進行轉發到對應的機器上,再通過機器上的路由轉發到容器中

  • 容器和其所在的宿主機之間的通訊直接通過連線到宿主機 namespace 的veth pair 和路由打通

  • 容器到其他主機通過 VPC 的網路轉發到對應的機器,其他主機到容器通過 VPC 網路轉發到對應的彈性網絡卡,然後通過路由轉發到容器的 Veth 上

  • 容器到專線和共享服務也都是通過 VPC 的網路轉發

  • 容器到公網的訪問經過 VSwitch 配置的 SNAT 閘道器直接將源 IP 轉換成 EIP 的地址到外部網路

  • 彈性網絡卡 (ENI) 支援配置多個輔助 IP 的功能,單個彈性網絡卡 (ENI) 根據例項規格可以分配 6-20 個輔助 IP,ENI 多 IP 模式就是利用了這個輔助 IP 分配給容器,從而大幅提高了 Pod 部署的規模和密度。

Terway ENIIP 模式容器網路資料鏈路剖析

針對容器網路特點,我們可以將 Terway ENI 模式下的網路鏈路大體分為以 Pod IP 對外提供服務和以 SVC 對外提供服務兩個大的 SOP 場景,進一步細分,可以歸納為 7 個不同的小的 SOP 場景。

12.png

對這 8 個場景的資料鏈路梳理合並,這些場景可以歸納為下面 8 類典型的場景:

TerwayENI 架構下,不同的資料鏈路訪問情況下,可以總結歸納為為 8 類:

  • 訪問 Pod IP, 同節點訪問 Pod

  • 訪問 Pod IP/SVC IP(Cluster or Local),同節點 pod 間互訪(pod 屬於同or不同ENI)

  • 訪問 PodIP ,異節點 pod 間互訪

  • 叢集內非 SVC 後端 pod 所在節點訪問 SVC ClusterIP

  • Cluster 模式,叢集內非 SVC 後端 pod 所在節點訪問 SVC External IP

  • Local 模式,叢集內非 SVC 後端 pod 所在節點訪問 SVC External IP

  • 叢集外訪問 SVC External IP

場景一:訪問 Pod IP,同節點訪問 pod

環境

13.png

cn-hongkong.10.0.1.82  節點上存在 nginx-7d6877d777-zp5jg 和 10.0.1.104

核心路由

nginx-7d6877d777-zp5jg IP地址 10.0.1.104  ,該容器在宿主機表現的 PID 是1094736,該容器網路名稱空間有指向容器 eth0 的預設路由

14.png 15.png

該容器 eth0 在 ECS OS 內對應 veth pair 是 calif03b26f9a43

16.png

在 ECS OS 內,有指向 Pod IP,下一跳為 calixxxx 的路由,通過前文可以知道 calixxx 網絡卡是和每個 pod 內的 veth1 組成的 pair,所以,pod 內訪問 SVC 的 CIDR 會有指向 veth1 的路由,不會走預設的 eth0 路由。

故:calixx 網絡卡在這裡的主要作用是用於:

  1. 節點訪問 Pod 

  2. 當節點或者 Pod 訪問 SVC 的 CIDR 時,會走 ECS OS 核心協議棧轉換,走到 calixxx 和 veth1 訪問 pod。

17.png

小結:可以訪問到目的端

nginx-7d6877d777-zp5jg   netns  eth0   可以抓到資料包

18.png

nginx-7d6877d777-zp5jg    calif03b26f9a43  可以抓到資料包

19.png 20.png

資料鏈路轉發示意圖

  • 會經過 calicao 網絡卡,每個非 hostnetwork 的 pod 會和 calicao 網絡卡形成 veth pair,用於和其他 pod 或 node 進行通訊

  • 整個鏈路不會和請求不會經過 pod 所分配的 ENI,直接在 OS 的 ns 中命中 Ip rule 被轉發

  • 整個請求鏈路是 OS -> calixxxxx -> ECS Pod net eth0

  • 整個鏈路會經過兩次核心協議棧:ECS OS 和 Pod

  • 資料鏈路要經過兩次核心協議棧,是 Pod1 協議棧、ECS1 協議棧

場景二:訪問 Pod IP/SVC IP(Cluster or Local),同節點 pod 訪問 pod(pod屬於同or不同ENI)

環境

21.png22.png

cn-hongkong.10.0.1.82  節點上存在 nginx-7d6877d777-zp5jg 和 10.0.1.104

cn-hongkong.10.0.1.82  節點上存在 centos-67756b6dc8-h5wnp 和 10.0.1.91

Service 是 nginx , ClusterIP 是 192.168.2.115  ExternalIP 是 10.0.3.62

核心路由

nginx-7d6877d777-zp5jg IP地址 10.0.1.104  ,該容器在宿主機表現的 PID 是1094736,該容器網路名稱空間有指向容器 eth0 的預設路由

23.png 24.png

該容器 eth0 在 ECS OS 內對應 veth pair 是 calif03b26f9a43

25.png

用上述類似辦法可以發現 centos-67756b6dc8-h5wnp 的 veth pair的 cali44ae9fbceeb,Pod 網路空間只有預設路由。

26.png 27.png

在 ECS OS 內,有指向 Pod IP,下一跳為 calixxxx 的路由,通過前文可以知道 calixxx 網絡卡是和每個 pod 內的 veth1 組成的 pair,所以,pod 內訪問 SVC 的 CIDR 會有指向 veth1 的路由,不會走預設的 eth0 路由。

故:calixx 網絡卡在這裡的主要作用是用於:

  1. 節點訪問 Pod 

  2. 當節點或者 Pod 訪問 SVC 的 CIDR 時,會走 ECS OS 核心協議棧轉換,走到 calixxx和 eth0 訪問 pod。

28.png

說明相關的路由轉發是在 ECS OS 層面進行的,Pod 的 calixx 網絡卡起到了一個橋樑和連通的作用。

源端 ECS 上的 IPVS 規則(如果訪問的是 SVC IP)

如果同節點上訪問的是 SVC 的IP(ClusterIP or ExternalIP),在節點上我們檢視 SVC 的相關 IPVS 轉發規則:

Service 的 ExternalTrafficPolicy 是 Local

SVC nginx CLusterIP是 192.168.2.115, ExternalIP是10.0.3.62, 後端是10.0.1.104 和10.0.3.58

29.png

cn-hongkong.10.0.1.82

對於 SVC 的 ClusterIP,可以看到 SVC 的後端兩個 Pod 都會被加到 IPVS 的轉發規則

30.png

對於 SVC 的 ExternalIP,可以看到 SVC 的後端,只有該節點的後端 Pod 10.0.1.104才會被加到 IPVS 的轉發規則

31.png

在 LoadBalancer 的 SVC 模式下,如果 ExternalTrafficPolicy 為 Local,對於 ClusterIP 來說,會把所有 SVC 後端 Pod 都會加到該節點的 IPVS 轉發規則;對於 ExternalIP,只會把該節點上的 SVC 後端 Pod 才會加到 IPVS 規則中。如果該節點沒有 SVC 後端 Pod,則該節點上的 Pod 訪問 SVC 的 ExternalIP 將會是失敗。

Service 的 ExternalTrafficPolicy 是 Cluster

SVC nginx1 CLusterIP 是 192.168.2.253, ExternalIP 是10.0.3.63, 後端是10.0.1.104 和10.0.3.58

32.png

cn-hongkong.10.0.1.82

對於 SVC 的 ClusterIP,可以看到 SVC 的後端兩個 Pod 都會被加到 IPVS 的轉發規則

33.png

對於 SVC 的 ExternalIP,可以看到 SVC 的後端兩個 Pod 都會被加到 IPVS 的轉發規則

34.png

在 LoadBalancer 的 SVC 模式下,如果 ExternalTrafficPolicy 為 Cluster,對於 ClusterIP 或 ExternalIP 來說,會把所有 SVC 後端 Pod 都會加到該節點的 IPVS 轉發規則。

小結:可以訪問到目的端

Conntrack 表資訊

Service nginx 的 ExternalTrafficPolicy 是 Local

SVC nginx CLusterIP 是 192.168.2.115, ExternalIP 是10.0.3.62, 後端是 10.0.1.104  和 10.0.3.58

1.如果訪問的是 SVC 的 ClusterIP,通過 conntrack 資訊,可以看到 src 是源端 Pod 10.0.1.91 ,dst 是 SVC ClusterIP 192.168.2.115,dport 是 SVC 中的 port。並且期望是10.0.1.104 來回包給  10.0.1.91  。

35.png

2.如果訪問的是 SVC 的 ExternalIP,通過 conntrack 資訊,可以看到 src 是源端 Pod 10.0.1.91 ,dst 是 SVC ExternalIP 10.0.3.62 ,dport 是 SVC 中的 port。並且期望是10.0.1.104 來回包給  10.0.1.91  。

36.png

Service nginx1 的 ExternalTrafficPolicy 是 Cluster

SVC nginx1 CLusterIP 是 192.168.2.253, ExternalIP 是10.0.3.63, 後端是 10.0.1.104 和 10.0.3.58

1.如果訪問的是 SVC 的 ClusterIP,通過 conntrack 資訊,可以看到 src 是源端 Pod 10.0.1.91 ,dst 是 SVC ClusterIP 192.168.2.253 ,dport 是 SVC 中的 port。並且期望是 10.0.1.104 來回包給  10.0.1.91  。

37.png

2.如果訪問的是 SVC 的 ExternalIP,通過 conntrack 資訊,可以看到 src 是源端 Pod 10.0.1.91 ,dst 是 SVC ExternalIP 10.0.3.63 ,dport 是 SVC 中的 port。並且期望是節點 ECS 的 IP 10.0.1.82  來回包給  10.0.1.91  。

38.png

綜上可以看到 src 變換了多次,故在 Cluster 模式下,會存在丟失真實客戶端IP的情況

39.png

資料鏈路轉發示意圖

  • 會經過 calicao 網絡卡,每個非 hostnetwork 的 pod 會和 calicao 網絡卡形成 veth pair,用於和其他 pod 或 node 進行通訊

  • 整個鏈路不會和請求不會經過 pod 所分配的 ENI,直接在 OS 的 ns 中命中 Ip rule 被轉發

  • 整個請求鏈路是 ECS1 Pod1 eth0 -> Pod1 calixxxx -> Pod2 calixxxx -> ECS1 Pod2 eth0

  • 訪問 SVC IP, SVC 會在源端 pod eth0 和 calixxx 網絡卡捕捉到,在目的端 pod 的 eth0 和 calixxx 時捕捉不到

  • 在 LoadBalancer 的 SVC 模式下,如果 ExternalTrafficPolicy 為 Local,對於 ClusterIP 來說,會把所有 SVC 後端 Pod 都會加到該節點的 IPVS 轉發規則;對於 ExternalIP,只會把該節點上的 SVC 後端 Pod 才會加到 IPVS 規則中。

  • 在 LoadBalancer 的 SVC 模式下,如果 ExternalTrafficPolicy 為 Cluster,對於 ClusterIP 或 ExternalIP 來說,會把所有 SVC 後端 Pod 都會加到該節點的 IPVS 轉發規則,同時無法保留 src 地址。

  • 資料鏈路要經過三次核心協議棧,是 Pod1 協議棧、ECS1 協議棧、Pod2 協議棧

場景三:訪問 PodIP ,異節點 pod 間互訪

環境

40.png

cn-hongkong.10.0.1.82  節點上存在 centos-67756b6dc8-h5wnp 和 10.0.1.91

cn-hongkong.10.0.3.49  節點上存在 nginx-7d6877d777-lwrfc 和 10.0.3.58

核心路由

centos-67756b6dc8-h5wnp  IP地址 10.0.1.104  ,該容器在宿主機表現的 PID 是2211426,該容器網路名稱空間有指向容器 eth0 的預設路由

用上述類似辦法可以發現 centos-67756b6dc8-h5wnp 的veth pair的 cali44ae9fbceeb,Pod 網路空間只有預設路由。

41.png 42.png

在 ECS OS 內,有指向 Pod IP,下一跳為 calixxxx 的路由,通過前文可以知道 calixxx 網絡卡是和每個 pod 內的 veth1 組成的 pair,所以,pod 內訪問 SVC 的 CIDR 會有指向 veth1 的路由,不會走預設的 eth0 路由。

故:calixx 網絡卡在這裡的主要作用是用於:

  1. 節點訪問 Pod 

  2. 當節點或者 Pod 訪問 SVC 的 CIDR 時,會走 ECS OS 核心協議棧轉換,走到 calixxx和 eth0 訪問 pod,對於目的為外部地址,則走 Pod 所屬的 ENI 出 ECS 進入到了 VPC。

43.png

小結:可以訪問到目的端

44.png

資料鏈路轉發示意圖

  • 會經過 calicao 網絡卡,每個非 hostnetwork 的 pod 會和 calicao 網絡卡形成 veth pair,用於和其他 pod 或 node 進行通訊

  • 整個鏈路請求會經過 pod 所分配的 ENI,直接在 OS 的 ns中命中 Ip rule 被轉發;

  • 出 ECS 後,根據要訪問的 pod 和該 pod ENI 所屬 vswitch,命中 VPC 路由規則或者直接 VSW 上的二層轉發;

  • 整個請求鏈路是 ECS1 Pod1 eth0-> ECS1 Pod1 calixxxxx-> ECS1 ethx -> vpc route rule(如有) -> ECS2 ethx ->  ECS2 Pod2 calixxxxx  -> ECS2 Pod2 eth0

  • 資料鏈路要經過四次核心協議棧,Pod1 協議棧、ECS1 協議棧、Pod2 協議棧、ECS2 協議棧

場景四:群內非 SVC 後端 pod 所在節點訪問 SVC ClusterIP

環境

45.png 46.png 47.png

cn-hongkong.10.0.3.49  節點上存在 nginx-7d6877d777-h4jtf 和 10.0.3.58cn-hongkong.10.0.1.82  節點上存在 centos-67756b6dc8-h5wnp 和 10.0.1.91Service1 是 nginx , ClusterIP 是 192.168.2.115  ExternalIP 是 10.0.3.62

Service2 是 ngin1 , ClusterIP 是 192.168.2.253  ExternalIP 是 10.0.3.63

核心路由

核心路由部分已經在場景二和場景三小結中詳細說明,這裡不再進行過多闡述

源端 ECS 上的的 IPVS 規則​

根據場景二小結中的源端 ECS 上的 IPVS 規則, 我們可以得到:無論在哪種 SVC 模式下,對於 ClusterIP 來說,會把所有 SVC 後端 Pod 都會加到該節點的 IPVS 轉發規則

小結:可以訪問到目的端

Conntrack 表資訊

Service nginx 的 ExternalTrafficPolicy 是 Local

SVC nginx CLusterIP 是 192.168.2.115, ExternalIP 是 10.0.3.62, 後端是 10.0.1.104 和 10.0.3.58

cn-hongkong.10.0.1.82

48.png

源端 ECS 上 src 是源端 Pod 10.0.1.91 ,dst 是 SVC ClusterIP 192.168.2.115,dport 是 SVC 中的 port。並且期望是 10.0.3.58 來回包給  10.0.1.91 。

cn-hongkong.10.0.3.49

49.png

目的端 ECS 上 src 是源端 Pod 10.0.1.91 ,dst 是 pod 的 IP 10.0.3.58,dport 是 pod 的 port。並且期望此 pod 來回包給 10.0.1.91 。

Service nginx1 的 ExternalTrafficPolicy 是 Cluster

SVC nginx1 CLusterIP 是 192.168.2.253, ExternalIP 是 10.0.3.63, 後端是 10.0.1.104 和 10.0.3.58

cn-hongkong.10.0.1.82

50.png

源端 ECS 上 src 是源端 Pod 10.0.1.91 ,dst 是 SVC ClusterIP 192.168.2.115,dport 是 SVC 中的 port。並且期望是 10.0.3.58 來回包給  10.0.1.91 。

cn-hongkong.10.0.3.49

51.png

目的端 ECS 上 src 是源端 Pod 10.0.1.91 ,dst 是 pod 的 IP 10.0.3.58,dport 是 pod的 port。並且期望此 pod 來回包給 10.0.1.91 。

對於 ClusterIP 來說,源端 ECS 會把所有 SVC 後端 Pod 都會加到該節點的 IPVS 轉發規則,目的端 ECS 是捕獲不到任何 SVC ClusterIP 資訊的,只能捕獲到源端 Pod 的 IP,所以回包的時候會回到源端 Pod 的附屬網絡卡上。

52.png

資料鏈路轉發示意圖

  • 會經過 calicao 網絡卡,每個非 hostnetwork 的 pod 會和 calicao 網絡卡形成 veth pair,用於和其他 pod 或 node 進行通訊

  • 整個鏈路請求會經過 pod 所分配的 ENI,直接在 OS 的 ns 中命中 Ip rule 被轉發;

  • 出 ECS 後,根據要訪問的 pod 和該 pod ENI 所屬 vswitch,命中 VPC 路由規則或者直接 VSW 上的二層轉發;

  • 整個請求鏈路是

去方向

ECS1 Pod1 eth0  -> ECS1 Pod1 calixxxxxx -> ECS1 主網絡卡 eth0  -> vpc route rule(如有) -> ECS2 附屬網絡卡ethx -> ECS2  Pod2 calixxxxx -> ECS2 Pod2 eth0

回方向

ECS2 Pod2 eth0  -> ECS2  Pod2 calixxxxx ->  ECS2 附屬網絡卡ethx -> vpc route rule(如有) ->  ECS1 附屬網絡卡 eth1  -> ECS1 Pod1 calixxxxxx  -> ECS1 Pod1 eth0

  • 對於 ClusterIP 來說,源端 ECS 會把所有 SVC 後端 Pod 都會加到該節點的 IPVS 轉發規則,目的端 ECS 是捕獲不到任何 SVC ClusterIP 資訊的,只能捕獲到源端 Pod 的 IP,所以回包的時候會回到源端 Pod 的附屬網絡卡上。

  • 資料鏈路要經過四次核心協議棧,Pod1 協議棧、ECS1 協議棧、Pod2 協議棧、ECS2 協議棧

場景五:Cluster 模式,叢集內非 SVC 後端 pod 所在節點訪問 SVC External IP

環境

53.png 54.png

cn-hongkong.10.0.3.49  節點上存在 nginx-7d6877d777-h4jtf 和 10.0.3.58cn-hongkong.10.0.1.82  節點上存在 centos-67756b6dc8-h5wnp 和 10.0.1.91

Service2 是 ngin1 , ClusterIP 是 192.168.2.253  ExternalIP 是 10.0.3.63

核心路由

核心路由部分已經在場景二和場景三小結中詳細說明,這裡不再進行過多闡述

源端 ECS 上的的 IPVS 規則

根據場景二小結中的源端 ECS 上的 IPVS 規則, 我們可以得到:ExternalTrafficPolicy 為 Cluster 模式下,對於 ExternalIP 來說,會把所有 SVC 後端 Pod 都會加到該節點的 IPVS 轉發規則

小結:可以訪問到目的端

Conntrack 表資訊

Service nginx1 的 ExternalTrafficPolicy 是 Cluster

SVC nginx1 CLusterIP是 192.168.2.253, ExternalIP 是10.0.3.63, 後端是 10.0.1.104 和 10.0.3.58

cn-hongkong.10.0.1.82

55.png

源端 ECS 上 src 是源端 Pod 10.0.1.91 ,dst 是 SVC ExternalIP 10.0.3.63,dport 是 SVC 中的 port。並且期望是 10.0.3.58 來回包給源端 ECS 的地址 10.0.1.82。

cn-hongkong.10.0.3.49

56.png

目的端 ECS 上 src 是源端 Pod 所在的 ECS 地址 10.0.1.82 ,dst 是 pod 的 IP  10.0.3.58,dport 是 pod 的 port。並且期望此 pod 來回包給源端 ECS 的地址10.0.1.82。

在 ExternalTrafficPolicy 為 Cluster 下,對於 ExternalIP 來說,源端 ECS 會把所有 SVC 後端 Pod 都會加到該節點的 IPVS 轉發規則,目的端 ECS 是捕獲不到任何 SVC  ExternalIP 資訊的,只能捕獲到源端 Pod 所在的 ECS 的 IP,所以回包的時候會回到源端 Pod 所在的 ECS 的主網絡卡上,這一點明顯和場景四小結中訪問 CusterIP 有很明顯區別 。

57.png

資料鏈路轉發示意圖

  • 會經過 calicao 網絡卡,每個非 hostnetwork 的 pod 會和 calicao 網絡卡形成 veth pair,用於和其他 pod 或 node 進行通訊

  • 整個鏈路請求會經過 pod 所分配的 ENI,直接在 OS 的 ns 中命中 Ip rule 被轉發;

  • 出 ECS 後,根據要訪問的 pod 和該 pod ENI 所屬 vswitch,命中 VPC 路由規則或者直接 VSW 上的二層轉發;

  • 整個請求鏈路是 ECS1 Pod1 eth0 -> ECS1 Pod1 calixxxx -> ECS1 主網絡卡ENI eth0 -> vpc route rule(如有) -> ECS2 附屬網絡卡ethx  -> ECS2 Pod2 calixxx ->  ECS2 Pod2 eth0

  • 在 ExternalTrafficPolicy 為 Cluster 下,對於 ExternalIP 來說,源端 ECS 會把所有 SVC 後端 Pod 都會加到該節點的 IPVS 轉發規則,目的端 ECS 是捕獲不到任何 SVC ExternalIP 資訊的,只能捕獲到源端 Pod 所在的 ECS 的 IP,所以回包的時候會回到源端 Pod 所在的 ECS 的主網絡卡 。

  • 資料鏈路要經過四次核心協議棧,Pod1 協議棧、ECS1 協議棧、Pod2 協議棧、ECS2 協議棧

場景六:Local 模式,叢集內非 SVC 後端 pod 所在節點訪問 SVC External IP

環境

58.png 59.png

cn-hongkong.10.0.3.49  節點上存在 nginx-7d6877d777-h4jtf 和 10.0.3.58

cn-hongkong.10.0.1.82  節點上存在 centos-67756b6dc8-h5wnp 和 10.0.1.91

Service1 是 nginx , ClusterIP是 192.168.2.115  ExternalIP是 10.0.3.62

核心路由

核心路由部分已經在場景二和場景三小結中詳細說明,這裡不再進行過多闡述

源端 ECS 上的的 IPVS 規則

Service 的 ExternalTrafficPolicy 是 Local

SVC nginx CLusterIP是 192.168.2.115, ExternalIP 是 10.0.3.62, 後端是 10.0.1.104 和 10.0.3.58

60.png

cn-hongkong.10.0.1.82

對於 SVC 的 ExternalIP,可以看到 SVC 的後端,無任何轉發規則

61.png

根據場景二小結中的源端 ECS 上的 IPVS 規則, 我們可以得到:ExternalTrafficPolicy 為 Local 模式下,對於 ExternalIP 來說,只會把本節點上的 SVC 的後端 Pod 加到節點上的 IPVS 轉發規則,如果該節點沒有 SVC 後端,則不會有任何可以轉發的規則。

小結:不可以訪問到目的端

Conntrack 表資訊

Service 的 ExternalTrafficPolicy 是 Local

SVC nginx1 CLusterIP 是 192.168.2.253, ExternalIP 是10.0.3.63, 後端是 10.0.1.104 和 10.0.3.58

cn-hongkong.10.0.1.82 無任何 conntrack 記錄表生成

62.png 63.png

資料鏈路轉發示意圖

  • 會經過 calicao 網絡卡,每個非 hostnetwork 的 pod 會和 calicao 網絡卡形成 veth pair,用於和其他 pod 或 node 進行通訊

  • 整個鏈路請求不會經過 pod 所分配的 ENI,直接在 OS 的 ns 中命中 Ip rule 被轉發;

  • 整個請求鏈路是 ECS1 Pod1 eth0  -> ECS1 Pod1 calixxxx -> ECS host 空間 ipvs/iptables 規則,無後端轉發 ep 終止鏈路。

  • ExternalTrafficPolicy 為 Local 模式下,對於 ExternalIP 來說,只會把本節點上的 SVC 的後端 Pod 加到節點上的 IPVS 轉發規則,如果該節點沒有 SVC 後端,則不會有任何可以轉發的規則。

場景七:叢集外訪問 SVC External IP

環境

64.png65.png

cn-hongkong.10.0.3.49  節點上存在 nginx-7d6877d777-h4jtf 和 10.0.3.58cn-hongkong.10.0.1.47  節點上存在 nginx-7d6877d777-kxwdb 和 10.0.1.29

Service1 是 nginx , ClusterIP是 192.168.2.115  ExternalIP是 10.0.3.62

SLB 相關配置

在 SLB 控制檯,可以看到 lb-j6cw3daxxukxln8xccive虛擬伺服器組的後端伺服器組是兩個後端 nginx pod的 ENI eni-j6c4qxbpnkg5o7uog5kr 和 eni-j6c6r7m3849fodxdf5l7

66.png

從叢集外部角度看,SLB 的後端虛擬伺服器組是 SVC 的後端 Pod 所屬的兩個 ENI 網絡卡,內網的 IP 地址就是 Pod 的地址

小結:可以訪問到目的端

67.png

資料鏈路轉發示意圖

  • 資料鏈路:client ->  SLB  -> Pod ENI + Pod Port  ->  ECS1 Pod1 eth0

  • 資料鏈路要經過二次核心協議棧,Pod1 協議棧和 ECS 協議棧

總結

本篇文章主要聚焦 ACK 在 Terway ENIIP 模式下,不同 SOP 場景下的資料鏈路轉發路徑。伴隨著客戶對效能的極致追求的需求,在 Terway ENIIP 模式下,一共可以分為 7 個 SOP 場景,並對這七個場景的轉發鏈路,技術實現原理,雲產品配置等一一梳理並總結,這對我們遇到 Terway ENIIP 架構下的鏈路抖動、最優化配置,鏈路原理等提供了初步指引方向。在 Terway ENIIP 模式下,利用 veth pair 來聯通宿主機和 pod 的網路空間,pod 的地址是來源於彈性網絡卡的輔助 IP 地址,並且節點上需要配置策略路由來保證輔助 IP 的流量經過它所屬的彈性網絡卡,通過此種方式可以實現 ENI 多 Pod 共享,大大提升了 Pod 的部署密度,但是 veth pair 必然會利用 ECS 的核心協議棧進行轉發,此架構下效能必然不如 ENI 模式,ACK 產研為了提升效能,結合核心的 ebpf 和 ipvlan 技術,開發了 Terway ebpf + ipvlan 架構。下一系列我們將進入到 Terway ENIIP 模式的全景解析——《ACK全景剖析阿里雲容器網路資料鏈路(四)—— Terway IPVLAN+EBPF》。

點選此處檢視阿里雲容器服務