在 Kubernetes 環境中,服務(Service)扮演著至關重要的角色,它提供一個穩定的抽象層,讓應用程式能夠存取後端的 Pod。本文將探討 Kubernetes 服務的運作方式,特別是 iptables 在流量管理中所扮演的角色。理解這些底層機制,對於 DevOps/DevSecOps 工程師以及 Kubernetes 叢集管理員來說至關重要。
Kubernetes 服務與 iptables 的關係
在 Kubernetes 中,kube-proxy
是一個核心元件,負責實作服務的負載平衡和流量路由。預設情況下,kube-proxy
使用 iptables 作為其底層的流量管理工具。iptables 是一個使用者空間的程式,它充當 Linux 核心 netfilter 框架的前端。netfilter 則是在網路堆積積疊中處理封包的機制,能夠進行封包過濾、網路位址轉換(NAT)等操作。
簡單來說,kube-proxy
透過設定 iptables 規則,將對服務的請求重新導向到後端的 Pod。這種方式讓服務能夠對外提供一個穩定的 IP 位址和連線埠,而無需關心後端 Pod 的實際位置和數量。
例項解析:使用 Podinfo 佈署服務
為了更具體地說明,我們將使用 Podinfo 這個範例應用程式來佈署一個 Kubernetes 服務。Podinfo 是一個簡單的網頁應用程式,可以用於展示 Kubernetes 的各種功能。
首先,我們需要新增 Podinfo 的 Helm 儲存函式庫行更新:
helm repo add podinfo https://stefanprodan.github.io/podinfo
helm repo update
接著,使用 Helm 佈署 Podinfo 到 Kubernetes 叢集中,並設定副本數量和後端服務:
helm upgrade -i --install --wait frontend --namespace podinfo \
--set replicaCount=2 \
--set backend=http://backend-podinfo:9898/echo \
podinfo/podinfo
這個指令會在 podinfo
名稱空間下佈署兩個 Podinfo 副本,並設定後端服務的位址。
透過以下指令,我們可以檢視 Podinfo 的 Pod 被排程到哪些節點上:
kubectl get po -n podinfo -o wide
此外,我們可以使用以下指令檢視 Kubernetes 為 Podinfo 服務分配的 IP 位址:
kubectl get svc -n podinfo
追蹤 iptables 流量
為了深入瞭解 iptables 如何處理流量,我們可以在一個沒有執行 Podinfo Pod 的節點上,啟用 iptables 的追蹤功能。以下指令會在 iptables 中新增規則,追蹤所有進入 9898 連線埠(Podinfo 服務的連線埠)的流量:
iptables -t raw -A PREROUTING -p tcp --dport 9898 -j TRACE
iptables -t raw -A OUTPUT -p tcp --dport 9898 -j TRACE
請注意,這些規則只會攔截目標連線埠為 9898 的流量,而不會攔截 Podinfo 服務的回傳流量。
接著,可以使用 xtables-monitor
工具來監控 iptables 的追蹤輸出:
xtables-monitor --trace
這個工具會顯示所有符合追蹤規則的封包,以及 iptables 對這些封包所執行的操作。透過分析這些輸出,我們可以清楚地瞭解 Kubernetes 服務的流量是如何被 iptables 重新導向到後端的 Pod。
iptables 規則解析
Kubernetes 服務的 iptables 規則通常會包含以下幾個部分:
- PREROUTING 鏈:用於在封包進入節點時進行處理。Kubernetes 會在這個鏈中新增規則,將對服務 IP 位址和連線埠的請求重新導向到
KUBE-SERVICES
鏈。 - KUBE-SERVICES 鏈:用於選擇後端 Pod。Kubernetes 會在這個鏈中新增規則,根據負載平衡策略選擇一個後端 Pod,並將封包重新導向到
KUBE-SVC-*
鏈。 - KUBE-SVC-* 鏈:用於將封包重新導向到後端 Pod。Kubernetes 會在這個鏈中新增規則,將封包的目標 IP 位址和連線埠修改為後端 Pod 的 IP 位址和連線埠,並將封包傳送到
KUBE-SEP-*
鏈。 - KUBE-SEP-* 鏈:用於執行網路位址轉換(NAT)。Kubernetes 會在這個鏈中新增規則,將封包的來源 IP 位址修改為節點的 IP 位址,確保後端 Pod 能夠正確地回覆請求。
- OUTPUT 鏈:用於在封包離開節點時進行處理。Kubernetes 會在這個鏈中新增規則,處理從節點內部發起的對服務的請求。
其他 kube-proxy 實作方式
雖然 iptables 是 kube-proxy
的預設實作方式,但 Kubernetes 也支援其他的實作方式,例如 IPVS(IP Virtual Server)。IPVS 是一種根據核心的負載平衡器,相比於 iptables,它具有更高的效能和可擴充套件性。
在選擇 kube-proxy
的實作方式時,需要考慮應用程式的需求和環境的限制。如果應用程式需要處理大量的並發請求,或者需要更高的效能,那麼 IPVS 可能是一個更好的選擇。
總結來說,Kubernetes 服務的運作依賴於 kube-proxy
和底層的流量管理工具,例如 iptables 或 IPVS。理解這些底層機制,對於有效地管理和除錯 Kubernetes 網路設定至關重要。透過本文的解析,希望能幫助讀者更深入地瞭解 Kubernetes 服務的運作方式,並能夠在實際應用中更好地利用這些技術。
在 Kubernetes 網路除錯中,理解 iptables
的追蹤日誌(trace logs)至關重要。這些日誌揭示了封包如何在叢集網路中流動,並有助於診斷網路策略、服務連線問題以及其他潛在的網路瓶頸。玄貓(BlackCat)將探討如何解讀這些日誌,以便更有效地管理和維護 Kubernetes 叢集網路。
1. Kubernetes 網路追蹤:日誌解讀與實務應用
1.1 iptables
追蹤日誌的核心要素
iptables
追蹤日誌提供了豐富的資訊,但要有效利用這些資訊,首先需要理解其核心要素。每個日誌條目都包含多個欄位,以下是一些關鍵欄位的解釋:
TRACE
: 指示這是一條追蹤日誌,表示封包正在透過iptables
規則鏈。filter
,mangle
,nat
: 這些是iptables
的不同表,分別用於封包過濾、修改和網路位址轉換(NAT)。PREROUTING
,INPUT
,FORWARD
,OUTPUT
,POSTROUTING
: 這些是iptables
表中的鏈,代表封包在網路堆積積疊中不同的處理階段。SRC
,DST
: 分別代表封包的來源和目標 IP 位址。SPORT
,DPORT
: 分別代表封包的來源和目標埠號。LEN
,TTL
,ID
: 分別代表封包的長度、存活時間和識別碼。SYN
: 指示這是一個 TCP SYN 封包,用於建立新的連線。MARK
:iptables
可以使用標記(mark)來標記封包,以便後續的規則可以根據這些標記來處理封包。JUMP
,CONTINUE
,RETURN
,ACCEPT
: 這些是iptables
規則的目標,JUMP
表示跳轉到另一個鏈,CONTINUE
表示繼續處理下一個規則,RETURN
表示回傳呼叫鏈,ACCEPT
表示接受封包。cali-
,KUBE-
: 這些字首表示規則是由 Calico CNI 或 Kubernetes 服務管理的。
1.2 追蹤日誌的範例分析
以下面的日誌條目為例:
TRACE: 2 0427ffe5 filter:OUTPUT:rule:0x91:JUMP:cali-OUTPUT -4 -t filter -A OUTPUT -m comment --comment "cali:tVnHkvAo15HuiPy0" -j cali-OUTPUT
這個日誌條目表示:
- 封包正在透過
filter
表的OUTPUT
鏈。 - 觸發了規則
0x91
,該規則跳轉到cali-OUTPUT
鏈。 - 該規則由 Calico CNI 管理,並帶有註解
"cali:tVnHkvAo15HuiPy0"
。
透過分析這些資訊,我們可以追蹤封包的路徑,並確定哪些規則正在影響封包的處理。
2. Kubernetes 網路策略的追蹤與驗證
2.1 網路策略與 iptables
規則
在 Kubernetes 中,網路策略用於控制 Pod 之間的流量。當我們定義一個網路策略時,Kubernetes CNI(如 Calico)會將其轉換為 iptables
規則。因此,透過追蹤 iptables
日誌,我們可以驗證網路策略是否按預期工作。
2.2 驗證網路策略的步驟
- 定義網路策略: 首先,定義一個網路策略,例如拒絕所有進出特定 Pod 的流量。
- 觸發流量: 嘗試從另一個 Pod 向受網路策略限制的 Pod 傳送流量。
- 檢查
iptables
日誌: 檢查iptables
日誌,尋找與網路策略相關的規則。這些規則通常帶有cali-
字首,表示由 Calico CNI 管理。 - 分析日誌: 分析日誌,確認封包是否按照網路策略的預期被拒絕或允許。
2.3 案例:拒絕特定 Pod 的流量
假設我們有一個名為 app=nginx
的 Pod,我們想要拒絕所有進出該 Pod 的流量。我們可以建立一個如下的網路策略:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-nginx-traffic
spec:
podSelector:
matchLabels:
app: nginx
ingress:
- from: []
egress:
- to: []
policyTypes:
- Ingress
- Egress
這個網路策略拒絕所有進入和離開 app=nginx
Pod 的流量。當我們嘗試從另一個 Pod 向 app=nginx
Pod 傳送流量時,我們可以在 iptables
日誌中看到類別似以下的規則:
TRACE: 2 0427ffe5 filter:FORWARD:rule:0x1a:DROP -4 -t filter -A FORWARD -i cali+ -o cali+ -m comment --comment "cali:xxxxx" -m conntrack --ctstate NEW -j DROP
這個規則表示所有從 cali+
介面(Calico 管理的介面)進入和離開的流量,如果沒有比對的連線追蹤條目,將會被丟棄。這驗證了我們的網路策略正在按預期工作。
3. 服務連線問題的診斷
3.1 服務與 iptables
規則
在 Kubernetes 中,服務透過 kube-proxy
元件實作。kube-proxy
會根據服務的設定建立 iptables
規則,將流量導向後端的 Pod。當我們遇到服務連線問題時,可以透過追蹤 iptables
日誌來診斷問題。
3.2 診斷服務連線問題的步驟
- 確認服務存在: 首先,確認服務已經正確建立,並且有後端的 Pod。
- 觸發連線: 嘗試從另一個 Pod 連線到該服務。
- 檢查
iptables
日誌: 檢查iptables
日誌,尋找與該服務相關的規則。這些規則通常帶有KUBE-
字首,表示由kube-proxy
管理。 - 分析日誌: 分析日誌,確認流量是否按照預期被導向後端的 Pod。
3.3 案例:服務無法連線
假設我們有一個名為 my-service
的服務,但是我們無法從另一個 Pod 連線到該服務。我們可以檢查 iptables
日誌,尋找與 my-service
相關的規則。如果我們發現以下規則:
TRACE: 2 0427ffe5 filter:KUBE-SERVICES:rule:0x12:DROP -4 -t filter -A KUBE-SERVICES -d 10.96.0.10 --dport 80 -m comment --comment "kubernetes service portals" -j DROP
這個規則表示所有目標為 10.96.0.10:80
(my-service
的 IP 位址和埠號)的流量都會被丟棄。這可能是因為 kube-proxy
沒有正確設定 iptables
規則,或者存在其他的網路策略阻止了流量。
4. 其他網路問題的診斷
4.1 NAT 問題
iptables
的 nat
表用於網路位址轉換(NAT)。當 Pod 需要存取外部網路時,iptables
會將 Pod 的內部 IP 位址轉換為節點的 IP 位址。如果 NAT 設定不正確,可能會導致 Pod 無法存取外部網路。
4.2 網路介面問題
在某些情況下,網路介面設定不正確可能導致網路問題。例如,如果 Pod 的預設路由不正確,可能會導致流量無法正確路由。透過追蹤 iptables
日誌,我們可以確認流量是否正在透過正確的網路介面。
總之,理解 Kubernetes 網路的 iptables
追蹤日誌是除錯網路問題的關鍵技能。透過分析這些日誌,我們可以追蹤封包的路徑,驗證網路策略,診斷服務連線問題,並解決其他潛在的網路瓶頸。玄貓(BlackCat)建議定期檢查和分析 iptables
日誌,以便及早發現和解決網路問題,確保 Kubernetes 叢集的穩定性和可靠性。
深入理解 Kubernetes 網路的 iptables
追蹤日誌對於除錯和最佳化網路設定至關重要。透過分析日誌中的關鍵要素,例如表、鏈、來源/目標 IP 和埠號,以及規則的目標,我們可以有效地追蹤封包在叢集網路中的流動路徑。此外,驗證網路策略、診斷服務連線問題以及識別 NAT 和網路介面設定錯誤,都是透過追蹤日誌可以實作的重要任務。定期檢查和分析 iptables
日誌,有助於及早發現並解決潛在的網路問題,確保 Kubernetes 叢集的穩定性和可靠性。
在網路管理和安全領域,理解網路封包的流動路徑至關重要。Netfilter 是 Linux 核心中的一個框架,允許我們以各種方式操作網路封包。本文將探討如何使用 Netfilter 追蹤網路封包,瞭解封包如何透過不同的鏈(Chain)和 iptables 規則。我們將以實際範例說明,並提供實用的 iptables 指令,幫助讀者掌握封包分析的核心技術。
解讀 Netfilter 追蹤資訊
利用 xtables-monitor
或類別似工具,我們可以追蹤網路封包的流動。追蹤資訊通常包含以下關鍵元素:
- 封包事件(PACKET):指示一個新的封包事件的開始。此行包含有關正在處理的封包、其來源、目的地、長度和其他封包級別的資訊。
PACKET:
行還包含根據當前封包接收者的 IP 位址的外發介面(Outgoing Interface)。 - 追蹤行(TRACE):顯示封包透過不同鏈和 iptables 規則的路徑。每一行
TRACE:
代表封包處理中的一步,顯示在某一時刻封包是根據哪條規則或鏈進行評估的。 - 協定號碼(Protocol Number):
TRACE:
或PACKET:
後面的數字代表協定家族(Address Family)。例如,數字2
通常代表AF_INET
,即 IPv4 流量。 - 識別碼(Identifier):一個唯一識別碼,例如
0427ffe5
,用於將封包與其追蹤記錄關聯起來。 - 表格與鏈(Table:Chain):對於
TRACE
行,此欄位指向處理封包的 iptables 表格和鏈。例如,raw:OUTPUT
參考raw
表格和OUTPUT
鏈。
要輸出特定的 iptables 鏈,可以使用以下指令:
sudo iptables -t raw -L OUTPUT -n --line-numbers
Netfilter 封包處理流程
理解 Netfilter 如何處理封包至關重要。對於從系統發出的封包,其處理順序如下:
- 路由選擇(Routing)
- 原始表格(raw table)的輸出鏈(OUTPUT Chain)
- Mangle 表格的輸出鏈(Mangle OUTPUT Chain)
- NAT 表格的輸出鏈(NAT OUTPUT Chain)
- 過濾器表格的輸出鏈(Filter OUTPUT Chain)
- 路由選擇(Routing)
- Mangle 表格的 POSTROUTING 鏈(Mangle POSTROUTING Chain)
- NAT 表格的 POSTROUTING 鏈(NAT POSTROUTING Chain)
以下簡化圖示展示了封包處理順序:
在本文中,我們將重點放在以下流程:
接下來,我們將以一個具體範例,分析封包 0427ff35
的處理過程。
分析 raw 表格的封包處理
目標表 raw
的主要作用是讓封包能夠繞過 iptables 中的連線追蹤功能(Connection Tracking,conntrack)。在這個流程中,由於連線追蹤功能未被使用,表格的處理速度通常很快。
以下是一個範例:
PACKET: 2 0427ffe5 OUT=enp3s0 SRC=192.168.1.88 DST=10.43.156.98 LEN=60 TOS=0x0 TTL=64 ID=45471DF SPORT=49058 DPORT=9898 SYN
TRACE: 2 0427ffe5 raw:OUTPUT:rule:0x18:CONTINUE -4 -t raw -A OUTPUT -p tcp -m tcp --dport 9898 -j TRACE
TRACE: 2 0427ffe5 raw:OUTPUT:return:
TRACE: 2 0427ffe5 raw:OUTPUT:policy:ACCEPT
第一行是資訊性行,顯示封包已被接收並開始處理。SRC=192.168.1.88
是發起 curl 請求的節點的 IP 位址。第二行是 TRACE
,我們透過 xtables-monitor
攔截了它。第三和第四行顯示,raw
表格處理的最終結果是目標 ACCEPT
。這意味著封包將被傳遞到下一個表格。
可以使用以下 iptables 指令檢視錶格和鏈:
iptables -t raw -L OUTPUT -n --line-numbers
輸出結果可能如下所示:
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
1 cali-OUTPUT all -- 0.0.0.0/0 0.0.0.0/0 /* cali:tVnHkvAo15HuiPy0 */
接著,我們可以檢視 cali-OUTPUT
鏈:
iptables -t raw -L cali-OUTPUT -n --line-numbers
輸出結果可能如下所示:
Chain cali-OUTPUT (1 references)
num target prot opt source destination
1 MARK all -- 0.0.0.0/0 0.0.0.0/0 /* cali:njdnLwYeGqBJyMxW */ MARK and 0xfff0ffff
2 cali-to-host-endpoint all -- 0.0.0.0/0 0.0.0.0/0 /* cali:rz86uTUcEZAfFsh7 */
3 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 /* cali:pN0F5zD0b8yf9W1Z */ mark match 0x10000/0x10000
最後,檢視 cali-to-host-endpoint
鏈:
iptables -t raw -L cali-to-host-endpoint -n --line-numbers
輸出結果可能如下所示:
Chain cali-to-host-endpoint (1 references)
num target prot opt source destination
透過 Netfilter 進行封包追蹤是網路管理和安全中不可或缺的技能。理解 PACKET
和 TRACE
行的含義,熟悉 iptables 指令,可以幫助我們深入瞭解網路封包的流動路徑,從而有效地進行故障排除和安全分析。本文以 raw
表格為例,展示瞭如何分析封包的處理過程。掌握這些技術,有助於提升對網路底層運作的理解,並能更有效地管理和保護網路環境。
在 Kubernetes 叢集中,網路封包的傳輸路徑可能相當複雜,特別是當涉及到不同的網路名稱空間、服務(Service)和 Pod 時。iptables
作為 Linux 核心中的防火牆和 NAT(網路位址轉換,Network Address Translation)工具,在 Kubernetes 網路中扮演著至關重要的角色。本文將探討 Kubernetes 網路中 NAT 表的角色,並透過實際的封包追蹤範例,瞭解封包如何透過 NAT 進行路由和修改。
深入理解 mangle
表:修改封包的幕後功臣
mangle
表主要用於修改封包的 IP 標頭,例如 TTL(生存時間,Time To Live)或 ToS/DSCP 欄位。與 raw
表類別似,mangle
表的處理速度非常快,因為它主要關注封包標頭的修改,而不是封包內容的檢查。
在 Kubernetes 網路中,mangle
表可以被用來調整封包的優先順序或修改 TTL 值,以確保封包在網路中的傳輸效率。例如,可以設定規則,根據封包的來源 IP 位址或目標 IP 位址,調整封包的 DSCP 值,從而影響網路裝置對封包的處理方式。
封包狀態(mangle:OUTPUT
鏈之後)
- 來源 IP 位址(Source IP Address):192.168.1.88
- 來源埠(Source Port):49058
- 目標 IP 位址(Destination IP Address):10.43.156.98
- 目標埠(Destination Port):9898
- 輸出介面(Output Interface):enp3s0
- 標籤(Mark):無
NAT
表:位址轉換的關鍵樞紐
NAT
表在 Kubernetes 網路中負責執行網路位址轉換,它允許叢集內部的 Pod 可以透過服務(Service)對外提供服務,同時也允許叢集外部的流量可以存取叢集內部的服務。NAT
表主要用於修改封包的來源 IP 位址、目標 IP 位址、來源埠和目標埠,從而實作網路位址的轉換。
在 NAT
表中,封包會經過多個鏈的處理,例如 OUTPUT
、cali-OUTPUT
、cali-fip-dnat
和 KUBE-SERVICES
等。這些鏈負責執行不同的網路位址轉換操作,以確保封包可以正確地路由到目標 Pod。
封包追蹤範例:nat:OUTPUT
鏈的深入分析
以下是一個封包追蹤的範例,展示了封包如何透過 nat:OUTPUT
鏈進行處理:
- 封包首先進入
nat:OUTPUT
鏈。 - 接著,封包被轉發到
nat:cali-OUTPUT
鏈,然後再到nat:cali-fip-dnat
鏈。 - 之後,封包回傳到
nat:OUTPUT
鏈,並繼續處理下一條規則,也就是nat:KUBE-SERVICES
鏈。 - 在
nat:KUBE-SERVICES
鏈中,封包會根據目標 IP 位址(10.43.156.98)被轉發到nat:KUBE-SVC-Y4T5L63IYP3YFEBS
鏈。 - 在
nat:KUBE-SVC-Y4T5L63IYP3YFEBS
鏈中,如果封包的來源 IP 位址不屬於 10.42.0.0/16 子網(表示封包不是來自另一個 Pod),則會被轉發到nat:KUBE-MARK-MASQ
鏈,並被標記為 0x4000。 - 最後,封包會被轉發到
nat:KUBE-SEP-OYNVDBAPYJ623W6H
鏈,並透過 DNAT(目標網路位址轉換,Destination Network Address Translation)修改目標 IP 位址和目標埠,將封包轉發到目標 Pod(10.42.54.194:9898)。
KUBE-SERVICES
鏈:服務發現的關鍵
KUBE-SERVICES
鏈是 Kubernetes 網路中非常重要的一個鏈,它負責實作服務發現和負載平衡。當封包到達 KUBE-SERVICES
鏈時,iptables
會根據封包的目標 IP 位址和目標埠,將封包轉發到對應的 KUBE-SVC-
鏈。每個 KUBE-SVC-
鏈都對應一個 Kubernetes 服務(Service),它定義瞭如何將流量路由到後端的 Pod。
透過 KUBE-SERVICES
鏈,Kubernetes 可以實作服務的自動發現和負載平衡,確保應用程式可以高用性和高效能地執行。
在 Kubernetes 網路中,NAT
表扮演著至關重要的角色,它負責執行網路位址轉換、服務發現和負載平衡等功能。透過深入理解 NAT
表的工作原理,我們可以更好地理解 Kubernetes 網路的複雜性,並更好地管理和最佳化 Kubernetes 叢集的網路效能。透過封包追蹤,我們可以更清晰地瞭解封包在 Kubernetes 網路中的傳輸路徑,從而更好地診斷和解決網路問題。
在 Kubernetes 環境中,理解封包如何在叢集內部流動至關重要。本文將探討 Kubernetes 在 iptables 模式下的網路封包追蹤,分析封包如何透過不同的 iptables 鏈進行路由,以及 kube-proxy 如何利用 iptables 規則實作服務的負載平衡。
封包路由:NAT 表的旅程
當封包離開主機時,它首先會經過 NAT 表。NAT 表負責網路位址轉換,允許叢集內部的服務透過單一的對外 IP 位址與外部網路進行通訊。以下將逐步分析封包在 NAT 表中的路由過程。
首先,封包會進入 nat:KUBE-SVC-Y4T5L63IYP3YFEBS
鏈。這個鏈是 kube-proxy 為了實作服務負載平衡而建立的。透過 iptables -t nat -L KUBE-SVC-Y4T5L63IYP3YFEBS -n --line-numbers
指令,我們可以觀察到該鏈的規則:
Chain KUBE-SVC-Y4T5L63IYP3YFEBS (1 references)
num target prot opt source destination
1 KUBE-MARK-MASQ tcp -- !10.42.0.0/16 10.43.156.98 /* podinfo/frontend-podinfo:http cluster IP */
2 KUBE-SEP-6G2GMHWEBXQ5W3DV all -- 0.0.0.0/0 0.0.0.0/0 /* podinfo/frontend-podinfo:http -> 10.42.217.66:9898 */ statistic mode random probability 0.50000000000
3 KUBE-SEP-OYNVDBAPYJ623W6H all -- 0.0.0.0/0 0.0.0.0/0 /* podinfo/frontend-podinfo:http -> 10.42.54.194:9898 */
第二和第三條規則使用統計模式(statistic mode)的隨機機率(random probability)來決定封包的走向。在這個例子中,封包有 50% 的機率被轉發到 nat:KUBE-SEP-6G2GMHWEBXQ5W3DV
鏈,另外 50% 的機率被轉發到 nat:KUBE-SEP-OYNVDBAPYJ623W6H
鏈。這些 SEP 鏈的功能是執行 DNAT(Destination Network Address Translation),將封包的目的 IP 位址從服務位址(例如:10.43.156.98)更改為後端 Pod 的 IP 位址。
以 nat:KUBE-SEP-OYNVDBAPYJ623W6H
鏈為例,它會將封包導向 IP 位址為 10.42.54.194 的 Pod。因此,封包在經過 nat:KUBE-SVC-Y4T5L63IYP3YFEBS
鏈後,會根據隨機機率被轉發到其中一個後端 Pod。
封包狀態追蹤
在經過 NAT 表後,封包的目的 IP 位址已被更改為後端 Pod 的 IP 位址。以下是封包在經過 nat:OUTPUT
鏈後的狀態:
- 來源 IP 位址(IP-адрес отправителя): 192.168.1.88
- 來源連線埠(傳送連線埠): 49058
- 目的 IP 位址(IP-адрес получателя): 10.42.54.194
- 目的連線埠(接收連線埠): 9898
- 輸出介面(Выходной интерфейс): enp3s0
- 標記(Метка): 0x4000/0x4000
Filter 表的流量控制
接著,封包會進入 filter 表。filter 表主要用於過濾流量,根據設定的規則允許或拒絕封包透過。以下是封包在 filter 表中的路由過程:
00: PACKET: 2 0427ffe5 OUT=enp3s0 SRC=192.168.1.88 DST=10.42.54.194 \
LEN=60 TOS=0x0 TTL=64 ID=45471DF SPORT=49058 DPORT=9898 SYN MARK=0x4000
01: TRACE: 2 0427ffe5 filter:OUTPUT:rule:0x91:JUMP:cali-OUTPUT -4 \
-t filter -A OUTPUT -m comment --comment "cali:tVnHkvAo15HuiPy0" \
-j cali-OUTPUT
02: TRACE: 2 0427ffe5 filter:cali-OUTPUT:rule:0x8a:CONTINUE -4 \
-t filter -A cali-OUTPUT -m comment --comment "cali:iC1pSPgbvgQzkUk_" \
-j MARK --set-xmark 0x0/0xf0000
03: TRACE: 2 0427ffe5 filter:cali-OUTPUT:return:
04: TRACE: 2 0427ffe5 filter:OUTPUT:rule:0x17:JUMP:KUBE-PROXY-FIREWALL -4 \
-t filter -A OUTPUT -m conntrack --ctstate NEW -m comment \
--comment "kubernetes load balancer firewall" -j KUBE-PROXY-FIREWALL
05: TRACE: 2 0427ffe5 filter:KUBE-PROXY-FIREWALL:return:
06: TRACE: 2 0427ffe5 filter:OUTPUT:rule:0x12:JUMP:KUBE-SERVICES -4 \
-t filter -A OUTPUT -m conntrack --ctstate NEW -m comment \
--comment "kubernetes service portals" -j KUBE-SERVICES
07: TRACE: 2 0427ffe5 filter:KUBE-SERVICES:return:
08: TRACE: 2 0427ffe5 filter:OUTPUT:rule:0x6:JUMP:KUBE-FIREWALL -4 \
-t filter -A OUTPUT -j KUBE-FIREWALL
09: TRACE: 2 0427ffe5 filter:KUBE-FIREWALL:return:
10: TRACE: 2 0427ffe5 filter:OUTPUT:return:
11: TRACE: 2 0427ffe5 filter:OUTPUT:policy:ACCEPT
從追蹤記錄中可以看到,封包首先從 filter:OUTPUT
鏈轉移到 filter:cali-OUTPUT
鏈,然後經過一系列的鏈,例如 KUBE-PROXY-FIREWALL
、KUBE-SERVICES
和 KUBE-FIREWALL
。這些鏈負責執行 Kubernetes 網路策略和服務代理相關的過濾規則。最後,封包被 filter:OUTPUT
連結受(ACCEPT),允許離開主機。
透過以上的封包追蹤分析,我們可以更深入地理解 Kubernetes 在 iptables 模式下的網路封包路由機制。kube-proxy 利用 iptables 規則實作服務的負載平衡,並透過 NAT 表進行網路位址轉換,使得叢集內部的服務能夠與外部網路進行通訊。理解這些底層機制對於 Kubernetes 網路問題的排查和最佳化至關重要。 在 Kubernetes 環境中,網路的複雜度往往超乎想像。Calico 作為一種流行的 Kubernetes 網路解決方案,透過 iptables 規則來管理網路流量。本文將探討 Kubernetes 叢集中,封包如何透過 Calico 進行網路傳輸,特別是 NAT(網路位址轉換,Network Address Translation)表的轉換過程,以及 Calico 相關的 iptables 規則如何影響封包的流向。
Kubernetes 封包旅程:從服務到 Pod 的網路轉換
當一個封包從 Kubernetes 叢集中的某個節點發出,目標是叢集內部的另一個 Pod 時,它會經歷一系列的網路轉換。這個過程涉及 iptables 規則、NAT 表,以及底層的網路技術,例如 VxLAN(虛擬可擴充套件區域網路,Virtual Extensible LAN)。
mangle 表:封包標頭的修改者
mangle
表的主要功能是修改封包的標頭,例如 TTL(存活時間,Time To Live)和 ToS/DSCP(服務類別/差分服務程式碼點,Type of Service/Differentiated Services Code Point)欄位。雖然 mangle
表通常不做重大的位址轉換,但它在封包的旅程中扮演著重要的角色。
以下是一個封包經過 mangle:POSTROUTING
鏈的追蹤範例:
00: PACKET: 2 0427ffe5 OUT=vxlan.calico SRC=192.168.1.88 DST=10.42.54.194 \
LEN=60 TOS=0x0 TTL=64 ID=45471DF SPORT=49058 DPORT=9898 SYN MARK=0x4000
01: TRACE: 2 0427ffe5 mangle:POSTROUTING:rule:0x15:JUMP:cali-POSTROUTING
-4 \
-t mangle -A POSTROUTING -m comment --comment "cali:O3lYWMrLQYEMJtB5" \
-j cali-POSTROUTING
02: TRACE: 2 0427ffe5 mangle:cali-POSTROUTING:rule:0x12:CONTINUE
-4 \
-t mangle -A cali-POSTROUTING -m comment --comment "cali:nnqPh8lh2VOogSzX" \
-j MARK --set-xmark 0x0/0xf000
03: TRACE: 2 0427ffe5 mangle:cali-POSTROUTING:rule:0x13:JUMP:cali-to-host-endpoint
-4 -t mangle -A cali-POSTROUTING -m comment --comment "cali:nquN8Jw8Tz72pcBW" \
-m conntrack --ctstate DNAT -j cali-to-host-endpoint
04: TRACE: 2 0427ffe5 mangle:cali-to-host-endpoint:return:
05: TRACE: 2 0427ffe5 mangle:cali-POSTROUTING:return:
06: TRACE: 2 0427ffe5 mangle:POSTROUTING:return:
07: TRACE: 2 0427ffe5 mangle:POSTROUTING:policy:ACCEPT
在上述追蹤中,可以看到封包的標籤(MARK)被設定,但由於位元運算的關係,實際上並未改變。
NAT 表:位址轉換的關鍵
NAT
表負責處理封包的來源和目標位址轉換。在 Kubernetes 的情境中,這通常涉及到將服務(Service)的 IP 位址轉換為 Pod 的 IP 位址。
以下是一個封包經過 nat:OUTPUT
鏈的追蹤範例:
00: PACKET: 2 0427ffe5 OUT=enp3s0 SRC=192.168.1.88 DST=10.43.156.98 \
LEN=60 TOS=0x0 TTL=64 ID=45471DF SPORT=49058 DPORT=9898 SYN MARK=0x4000
01: TRACE: 2 0427ffe5 nat:OUTPUT:rule:0xbf:JUMP:cali-OUTPUT
-4 \
-t nat -A OUTPUT -m comment --comment "cali:6fe2Eq4FmL-Kj-oF" -j cali-OUTPUT
02: TRACE: 2 0427ffe5 nat:cali-OUTPUT:rule:0xbc:JUMP:cali-fip-dnat
-4 \
-t nat -A cali-OUTPUT -m comment --comment "cali:s9X_T2wHrQt1tQtq" -j cali-fip-dnat
03: TRACE: 2 0427ffe5 nat:cali-fip-dnat:return:
04: TRACE: 2 0427ffe5 nat:cali-OUTPUT:rule:0xbd:JUMP:cali-k8s-service-dnat
-4 \
-t nat -A cali-OUTPUT -m comment --comment "cali:K-vAwWIQwi4KUbV-" -j cali-k8s-service-dnat
05: TRACE: 2 0427ffe5 nat:cali-k8s-service-dnat:rule:0x1:DNAT
-4 \
-t nat -A cali-k8s-service-dnat -m comment --comment "kubernetes service dnat to pod" \
-j DNAT --to-destination 10.42.54.194:9898
06: TRACE: 2 0427ffe5 nat:cali-k8s-service-dnat:return:
07: TRACE: 2 0427ffe5 nat:cali-OUTPUT:return:
08: TRACE: 2 0427ffe5 nat:OUTPUT:policy:ACCEPT
在這個追蹤中,可以看到封包的目標位址從服務的 IP 位址 10.43.156.98
變更為 Pod 的 IP 位址 10.42.54.194
。這個轉換是透過 cali-k8s-service-dnat
鏈中的 DNAT
規則實作的。
VxLAN:跨節點的網路橋樑
VxLAN 是一種覆寫網路技術,它允許封包在不同的網路節點之間傳輸,而無需修改底層的網路基礎設施。在 Kubernetes 中,Calico 使用 VxLAN 來實作跨節點的 Pod 網路通訊。
當封包的目標 Pod 位於不同的節點上時,封包會被封裝在 VxLAN 標頭中,然後透過底層網路傳輸到目標節點。在目標節點上,VxLAN 標頭會被移除,封包會被傳送到目標 Pod。
Calico iptables 規則的深入解析
Calico 使用 iptables 規則來管理網路流量,這些規則定義了封包如何被處理、轉發和過濾。Calico 的 iptables 規則非常複雜,但它們遵循一套清晰的命名慣例和邏輯結構。
例如,cali-OUTPUT
鏈用於處理從節點發出的封包,而 cali-POSTROUTING
鏈用於處理在路由之後的封包。這些鏈包含了各種規則,用於執行 NAT 轉換、封包過濾和其他網路功能。
理解 Kubernetes 網路的關鍵
理解 Kubernetes 網路的運作方式,對於開發、佈署和維護 Kubernetes 應用程式至關重要。透過深入瞭解 Calico 的 iptables 規則、NAT 轉換和 VxLAN 覆寫網路,我們可以更好地理解 Kubernetes 網路的複雜性,並解決可能出現的網路問題。封包在 Kubernetes 叢集中的旅程,實際上是透過多個網路技術和規則的協同運作來實作的。掌握這些技術細節,將有助於我們更好地管理和最佳化 Kubernetes 網路。
在 Kubernetes 的世界中,網路是至關重要的基礎設施。理解 Kubernetes 網路如何運作,以及如何追蹤網路流量,對於除錯、效能最佳化和安全至關重要。本文將探討 Kubernetes 網路追蹤的核心概念,重點介紹如何使用 iptables 這個強大的工具來監控和分析網路封包。
Kubernetes 網路基礎:簡要回顧
Kubernetes 網路模型旨在提供一個扁平化的網路空間,讓所有 Pod 都能夠直接互相通訊,而無需經過網路位址轉換(NAT, Network Address Translation)。為了實作這一目標,Kubernetes 依賴於容器網路介面(CNI, Container Network Interface)外掛,例如 Calico、Flannel 或 Cilium。這些 CNI 外掛負責設定 Pod 的網路介面、路由規則和防火牆策略。
在這些 CNI 外掛中,Calico 是一個廣泛使用的選擇,它利用 Linux 核心的 iptables 功能來實作精細的網路策略。Iptables 是一個強大的防火牆工具,允許系統管理員定義規則,以控制網路流量的進出。
使用 iptables 追蹤 Kubernetes 網路流量
Iptables 透過表格(Tables)和鏈(Chains)的結構來組織規則。每個表格代表不同類別的網路操作,例如過濾(filter)、NAT 和修改(mangle)。每個鏈則包含一系列規則,這些規則按照順序進行評估。
要使用 iptables 追蹤 Kubernetes 網路流量,首先需要了解 Calico 如何使用 iptables。Calico 會建立自己的 iptables 鏈,並在這些鏈中插入規則,以實作 Kubernetes 網路策略。
以下是一些常用的 iptables 指令,可用於追蹤 Kubernetes 網路流量:
iptables -L
: 列出指定表格中所有鏈的規則。例如,iptables -L -t nat
會列出 NAT 表格中的所有規則。iptables -v -L
: 以詳細模式列出規則,包括封包和位元組計數器。iptables -t nat -A POSTROUTING -o vxlan.calico -j TRACE
: 這個指令會在 NAT 表格的 POSTROUTING 鏈中新增一條規則,將所有透過vxlan.calico
介面的封包導向 TRACE 目標。TRACE 目標會將封包的追蹤資訊記錄到核心日誌中。
實戰範例:追蹤 Pod 到 Service 的流量
假設我們想要追蹤一個 Pod 到 Kubernetes Service 的流量。我們可以按照以下步驟進行:
- 找到 Pod 和 Service 的 IP 位址:使用
kubectl get pods -o wide
和kubectl get svc
指令,找到目標 Pod 和 Service 的 IP 位址。 - 新增 iptables 規則:在執行 Pod 的節點上,使用
iptables -t nat -A POSTROUTING -d <Service IP> -j TRACE
指令,將所有目標位址為 Service IP 的封包導向 TRACE 目標。 - 檢查核心日誌:使用
dmesg
指令檢查核心日誌,尋找包含 “TRACE:” 字樣的訊息。這些訊息會顯示封包經過的 iptables 規則。
深入理解 Calico 的 iptables 規則
Calico 使用大量的 iptables 規則來實作 Kubernetes 網路策略。這些規則可能很複雜,但理解它們對於除錯和最佳化網路至關重要。
Calico 的 iptables 規則通常包含以下元素:
- 鏈名稱:Calico 的鏈名稱通常以
cali-
開頭。 - 比對條件:比對條件用於篩選封包,例如來源和目標 IP 位址、埠號和協定。
- 目標:目標定義瞭如何處理封包,例如 ACCEPT、DROP 或 MASQUERADE。
- 註解:Calico 會在規則中新增註解,以說明規則的目的。
透過分析 Calico 的 iptables 規則,我們可以瞭解 Kubernetes 網路策略的具體實作方式。
網路追蹤的進階技巧
除了使用 iptables,還有其他一些工具和技術可用於追蹤 Kubernetes 網路流量:
- tcpdump: 是一個強大的封包嗅探工具,可以捕捉網路介面上的所有流量。
- Wireshark: 是一個圖形化的封包分析工具,可以分析 tcpdump 捕捉的流量。
- Service Mesh: 例如 Istio,可以提供更精細的網路追蹤和監控功能。
- eBPF: 是一種新型的 Linux 核心技術,允許開發者在核心中執行自定義程式碼,以實作高效的網路追蹤和分析。
Kubernetes 網路追蹤是一個複雜但至關重要的主題。透過理解 Kubernetes 網路模型、iptables 和其他網路追蹤工具,我們可以更好地管理和保護我們的 Kubernetes 叢集。Iptables 提供了一個強大而靈活的工具,讓我們能夠深入瞭解 Kubernetes 網路的底層運作機制。透過實戰範例和進階技巧的學習,我們可以提升 Kubernetes 網路的除錯、效能最佳化和安全防護能力。掌握這些技能,將使我們能夠更好地應對 Kubernetes 網路的挑戰,並構建更可靠、高效和安全的應用程式。