將 Kubernetes 的 CNI 從其他元件切換為 Cilium, 已經可以有效地提升網路的效能。但是通過對 Cilium 不同模式的切換/功能的啟用,可以進一步提升 Cilium 的網路效能。具體調優項包括不限於:
CONFIG_PREEMPT_NONE=y
tuned-adm profile network-latency
或 network-throughput
irqbalance
,將網路卡中斷引腳指向特定 CPU在網路/網路卡裝置/OS 等條件滿足的情況下,我們儘可能多地啟用這些調優選項,相關優化項會在後續文章逐一更新。敬請期待。
今天我們來將 Cilium 的 NodePort 實現從 SNAT 改為 DSR 以提升網路效能。
預設情況下,Cilium 的 eBPF NodePort 實現以 SNAT 模式執行。也就是說,當節點外部流量到達時,如果節點確定負載平衡器、NodePort 或具有外部 IP 的服務的後端位於遠端節點,那麼節點就會通過執行 SNAT 將請求重定向到代表自己的遠端後端。這不需要額外更改 MTU。代價是,來自後端的回覆需要額外跳回節點,在那裡執行反向 SNAT 轉換,然後再將封包直接返回給外部使用者端。
範例如下,Cilium 的 eBPF NodePort 實現以 SNAT 模式執行:
$ kubectl -n kube-system exec ds/cilium -- cilium status --verbose
...
KubeProxyReplacement Details:
Status: Strict
Socket LB: Enabled
Socket LB Tracing: Enabled
Socket LB Coverage: Full
Devices: eth0 192.168.2.3 (Direct Routing)
Mode: SNAT
SNAT 模式下,NodePort 後端 pod 在其他節點入向流量:
出向流量:
該設定可通過 loadBalancer.mode
Helm 選項更改為 dsr
,以便讓 Cilium 的 eBPF NodePort 實現在 DSR 模式下執行。在這種模式下,後端直接回復外部使用者端,而不需要額外的跳轉,也就是說,後端通過使用服務 IP/port 作為源來回復。DSR 目前要求 Cilium 以本地路由模式部署,也就是說,它不能在任何一種隧道模式下工作。
DSR 模式流量如下:
DSR 模式的另一個優點是保留了使用者端的源 IP,因此可以在後端節點對其進行策略匹配。而在 SNAT 模式下則無法做到這一點。鑑於一個特定的後端可被多個服務使用,後端需要知道它們需要回復的服務 IP/埠。
請注意,由於 Cilium 特定的 IP 選項可能會被底層網路結構丟棄,因此 DSR 模式在某些公共雲提供商環境中可能無法使用。如果後端位於與處理給定 NodePort 請求的節點相距較遠的節點上,在出現服務連線問題時,首先要檢查 NodePort 請求是否實際到達了包含後端的節點。如果不是,則建議切換回預設 SNAT 模式作為一種解決方法。
此外,在某些實施源/目標 IP 地址檢查的公共雲提供商環境中(如 AWS),必須禁用檢查才能使用 DSR 模式。
在啟用僅 DSR 模式的無 kube proxy 環境中,上述 Helm 範例設定如下:
helm upgrade cilium cilium/cilium --version 1.13.4 \
--namespace kube-system \
--reuse-values \
--set loadBalancer.mode=dsr