作者: Colin Jao 饒康立 – VMware資深技術顧問,主要負責VMware NSX產品線,目前致力於網路虛擬化、分散式安全防護技術與新應用遞送方案的介紹與推廣。

前篇我們討論了AKO (Avi Kubernetes Operator) 在配置時支持的第一種網路架構,透過自動配置Static Route的方式讓前端服務引擎要遞送用戶連線到後端的Service Pod時,能夠將封包送往Pod所在的Worker-Node介面IP。這是一個非常常用的機制,但在企業環境內部署時可能會碰到一個限制:服務引擎必須要能夠與Worker-Node在同一個網段內。如果這個條件無法達成,上述的機制會出問題。

什麼意思呢?請看下列配置圖。

這張圖內,Pod A~D仍然是在不可路由的Kubernetes內部網路。Worker Nodes在10.100.1.0/24這個網路內。與前篇架構不同的,服務引擎 – 負載平衡器是在前面的10.100.2.0/24這個網段,10.100.1.0 / 10.100.2.0兩個網段透過標準路由器可連通。

回憶一下前面如果採用”靜態路由 – ClusterIP機制”,如果在Avi內,要送往後端Pod C: 192.168.102.17這個IP,由AKO取得資訊知道要送往10.100.1.102這個IP。此時,

  • 封包由Avi服務引擎送出目的地是192.168.102.17的封包,透過靜態路由比對要送往10.100.1.102。因為與服務引擎介面在不同網段,封包就送往預設路由,到路由器去。
  • 當這個目的地是192.168.102.17的封包送到路由器上時,路由器沒有這個網段(192.168.102.0/24是Pod Network,不可路由),然後…就往default gateway丟…然後就不知道到哪裡去了。

上面限制常不常見?在企業環境很有可能有這樣的限制,有些IT單位在網路規劃上不希望負載平衡器的網段與Kubernetes Worker-Node的網段在一起,強制要求分開。這種狀態,我們需要採用下面介紹的第二或第三種架構:

2. Pod放置的網段與企業網路間沒有外部路由:採用NodePort模式

同樣請參考最前面的圖。如果我們在AKO內設定要採用NodePort模式,此時當用戶要建一個Ingress到後端的Pod A~D,

  • 後端對應Pod A~D的Service型態應該是Nodeport而不是ClusterIP,比如說每台K8S node上面的31005 port
  • AKO在Avi Controller上配置的Server Pool採用的不是Pod IP,而會是外部的Node Interface IP加上服務port。

什麼意思呢?此時,我們在Server Pool內看到後端的工作負載是

Server1 — 10.100.1.101:31005                  
Server2 — 10.100.1.102:31005

不是Pod的IP,而是Worker Node的實體介面Nodeport (在本例為31005)。這個時候,當用戶連線的封包要往後送,目的地是送往實體網路上的介面 (10.100.1.101 or 10.100.1.102),這邊的介面是可路由的,當然中間的路由機制可以正常將封包送到。而當封包送到比如說Worker-Node-1的31005 port上後,透過K8S標準Nodeport的機制,會透過Kube-Proxy隨機選擇後端的Pod A~D,再把封包往那邊丟。

這個架構堪用,但有下列問題:

  • 服務引擎(負載平衡器)與後端真正的Pod之間有透過Nodeport-Kubeproxy擋在中間。此時網路流很可能不是最佳化的,比如說前端Virtual Service把Traffic送往上圖的Server1: 10.100.1.101:31005,但透過kube-proxy的機制,選到後端的Pod D,此時Traffic又由Server1轉送到Server2
  • Kube-Proxy在中間,服務引擎不知道真正後面Pod的健康狀況,Health Monitor也無法真正連到後端Pod,確認每一個Pod是不是都正常。
  • 連線堅持機制 (Session-Persistent) 也沒法做到。服務引擎只能把連線丟到同一台後端Server (比如說10.100.1.101:31005),但無法強制每次都一定會連到同一個後端的Pod

實務面上這邊的Health Monitor / Session-Persistent做不到的問題其實會滿困擾的,要解決這個問題,需要一個可以跨路由,又可直接連通到Pod,越過Kube-Proxy機制的方案。因此企業在新環境內,也可考慮第三種最新架構:

3. Pod放置的網段與企業網路間沒有外部路由:採用NodePortLocal模式

NodePortLocal是需要與指定CNI連動的方式。如果客戶的Kubernetes環境採用Antrea 0.13之後的版本則可以使用。在NodePortLocal功能啟用下,

  • AKO會自動於Pod內透過annotation機制,以NodePortLocal功能將Pod暴露至外部實體網路
  • AKO會告知Avi Controller各個後端Pod的外部對應IP/Port。
  • 當網路封包到達此Pod外部對應之IP/Port時,Antrea會直接轉送封包至Pod,不會透過Kube-Proxy機制。

在最前頭的圖內,當我們採用NodePortLocal機制時,在Avi Server Pool內看到後端的工作負載會像是下面這樣:

Server1 — Pod-A: 10.100.1.101:32015          
Server2 — Pod-B: 10.100.1.101:32017          
Server3 — Pod-C: 10.100.1.102:31099          
Server4 — Pod-D: 10.100.1.102:32011

此時,

  • Avi服務引擎可以標準路由連接到各個Pod外部暴露的IP/Port
  • 因為Antrea會直接內部繞送封包到Pod,不經由Kube-Proxy機制,因此負載均衡需求的Health Check / 連線堅持等功能都可正常運作。

上述的功能聽起來很完美,既可以避開網路架構問題,應用遞送服務也都可完整運作。但限制是這必須是採用Antrea作為Container Network Interface,且至少要0.13版之後。如果大家是從頭打造原生K8S當然可以自行選擇,但如果是在公有雲或是採用特定廠商的Kubernetes商用版本,就需要確認底層CNI是否是Antrea且支持需求版本了。

下一篇內我們會就AKO與容器底層網路整合討論最後一種方法:路由機制,且針對這幾篇介紹的各種方式的選擇與部署環境做簡單的整理。