昨天我們聊了 Kubernetes 網路的基礎運作:Pod 之間怎麼溝通、Service 又是怎麼幫我們解決 Pod IP 會變動的問題、還有外部流量是如何進入到 Pod 裡頭的。今天,我們要把焦點放在一個更進階的解決方案 —— Cilium。
在 EKS 上,大家最常遇到的限制就是 Pod IP 容易不足,或者 overlay 網路下封包繞不回來。這些問題其實和 CNI (Container Network Interface) 的選擇有關,而 Cilium 正是近年來呼聲最高的替代方案。它靠著 eBPF 這個核心技術,重寫了我們對 Kubernetes 網路的理解。
當初我們要把 EKS 與集團的 GitLab 網路做對接時,收到的 VPC CIDR block 相對偏小,導致分配給 Pod 的 IP 數量非常有限。這在微服務架構下很快就會成為瓶頸 —— 一個 Node 可以跑的 Pod 數量直接受限於 VPC IP。Cilium 剛好提供了 cluster-pool IPAM 與 Overlay 模式,可以突破 VPC CIDR 的限制,讓 Pod IP 數量不再被 VPC 綁死,這就是我們一開始決定導入 Cilium 的主要動機。
接下來就讓我們來看看 Cilium 到底是怎麼運作的吧!
eBPF(extended Berkeley Packet Filter)最早只是 Linux 上的封包過濾工具,但現在已經進化成能在 Linux 核心內直接執行小程式 的平台。這代表我們可以在封包流經網路堆疊的過程中,插入一些極小、但非常高效的邏輯,直接決定封包該往哪裡走。
比喻來說,eBPF 就像在作業系統裡安插一群小幫手,他們比任何外部防火牆都快,因為不用把封包送出去繞一圈才能做決定,而是「經過這裡立刻判斷,立刻執行」。
這和傳統的 iptables / kube-proxy 有本質上的差異:
相對地,eBPF 走的是另一條路:
iptables -t nat -L
。因此,eBPF 與其說是 iptables 的加速版,不如說是一個完全不同的網路處理模型,這也是 Cilium 能替代 iptables 和 kube-proxy 的關鍵。
除了 eBPF 之外,Cilium 在某些模式下也會依賴 VXLAN (Virtual Extensible LAN) 來解決跨節點通訊問題。
在 Kubernetes 裡,如果兩個 Pod 剛好不在同一個節點上,它們的封包就必須「跨主機」傳送。問題是:Pod 的 IP 通常不是 VPC 原生能識別的範圍,外部網路設備不知道該怎麼轉送這些 IP。
這時候 VXLAN 就派上用場了。VXLAN 是一種 Overlay 網路技術,會把原本的 Pod 封包「再包一層 UDP 封包」送出去,外部只看到 Node 與 Node 之間的 IP 通訊,而 Node 收到之後會把外層 UDP 解封,再把原始封包送進去給正確的 Pod。
比喻來說,Pod 封包就像一封沒有郵票的信件,如果直接丟到郵局,郵差根本不知道怎麼送;VXLAN 就是幫它裝進一個已經寫好收件地址的大信封(Node 的 IP),這樣郵差只要把信送到那個 Node,就能拆開信封,把內容交給對的 Pod。
而在 Cilium 的 Overlay 模式下,每個節點都會啟動一個 cilium_vxlan
裝置,專門用來封裝與解封 VXLAN 封包。這也是為什麼在 debug 時,如果 VXLAN 的 UDP port(8472)沒開,就會導致節點之間完全無法通訊。
在真實世界裡,封包出去還要能「順利回來」。這時候就需要 SNAT (Source NAT)。它會把 Pod 的來源 IP 換成 Node 的 IP,這樣外部世界在回覆時才知道該找誰。
比喻來說,這就像訂餐時不留私人手機,而是留公司總機號碼,因為這樣外面的人一定能找到你。
而 masquerade 則是 SNAT 的常見實作:Pod 出去的時候戴上 Node 的面具,外面只會看到節點 IP,而不是 Pod 本身的 IP。這能避免很多麻煩,尤其在 overlay 模式下,沒有 masquerade 的話,像 CoreDNS 的 UDP 回應 就可能會直接迷路,最後被丟掉。
Cilium 把 SNAT/masquerade 這件事交給 eBPF 處理,而不是像以前那樣靠 iptables 的 MASQUERADE 規則,效能與可觀察性都更好。
概念聊完,來看看部署時會遇到的一些實務細節。
在每個 Node 上,其實會有一個 /etc/cni/net.d/
資料夾,裡面存放目前 CNI 的設定檔。
10-aws.conflist
。05-cilium.conflist
。EKS 在建立時會自動安裝 VPC CNI。如果你之後再加上 Cilium,兩個檔案會共存,不過 VPC CNI 的會被改成 .bak
,實際上還是由 05-cilium.conflist
生效。
Cilium Pod 不只是「一個網路代理人」這麼簡單,它啟動時會經歷一整套流程:
這也是為什麼你在節點網卡列表裡會看到 cilium_net
、cilium_host
、cilium_vxlan
等虛擬裝置 —— 它們就是 Cilium 初始化時建立的。
Cilium 的 IPAM 設定裡常見兩個參數:
clusterPoolIPv4PodCIDRList
:整體的 IP 範圍,例如 10.0.0.0/8
。clusterPoolIPv4MaskSize
:每個 Node 分配的子網大小,例如 /24
,代表一個 Node 有 256 個 Pod IP 可以用。這樣設計的好處是「集中管理,又能按節點切分」,讓每個 Node 都有一段穩定可用的 IP 範圍。
今天這篇,我們先從 Cilium 的元件與原理 講起,理解 eBPF 為什麼這麼強大、SNAT/masquerade 為什麼是關鍵,接著看到它如何取代傳統的 iptables 和 kube-proxy,並且額外帶來 cilium-envoy、CCNP 這些更進階的能力。
最後,我們也釐清了幾個實作上的觀念,包括 CNI 設定檔的切換方式、Cilium Pod 啟動的流程、以及 Pod IP 資源池的配置。這些細節在後續 debug 時都會很有幫助。
明天(Day 27),就要進到更實戰的部分 —— 我在部署 EKS + Cilium 遇到的坑,包含 VXLAN overlay 不通、CoreDNS timeout、Webhook 失敗等等,會分享踩雷過程與解法。