在 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

這個日誌條目表示:

  1. 封包正在透過 filter 表的 OUTPUT 鏈。
  2. 觸發了規則 0x91,該規則跳轉到 cali-OUTPUT 鏈。
  3. 該規則由 Calico CNI 管理,並帶有註解 "cali:tVnHkvAo15HuiPy0"

透過分析這些資訊,我們可以追蹤封包的路徑,並確定哪些規則正在影響封包的處理。

2. Kubernetes 網路策略的追蹤與驗證

2.1 網路策略與 iptables 規則

在 Kubernetes 中,網路策略用於控制 Pod 之間的流量。當我們定義一個網路策略時,Kubernetes CNI(如 Calico)會將其轉換為 iptables 規則。因此,透過追蹤 iptables 日誌,我們可以驗證網路策略是否按預期工作。

2.2 驗證網路策略的步驟

  1. 定義網路策略: 首先,定義一個網路策略,例如拒絕所有進出特定 Pod 的流量。
  2. 觸發流量: 嘗試從另一個 Pod 向受網路策略限制的 Pod 傳送流量。
  3. 檢查 iptables 日誌: 檢查 iptables 日誌,尋找與網路策略相關的規則。這些規則通常帶有 cali- 字首,表示由 Calico CNI 管理。
  4. 分析日誌: 分析日誌,確認封包是否按照網路策略的預期被拒絕或允許。

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 診斷服務連線問題的步驟

  1. 確認服務存在: 首先,確認服務已經正確建立,並且有後端的 Pod。
  2. 觸發連線: 嘗試從另一個 Pod 連線到該服務。
  3. 檢查 iptables 日誌: 檢查 iptables 日誌,尋找與該服務相關的規則。這些規則通常帶有 KUBE- 字首,表示由 kube-proxy 管理。
  4. 分析日誌: 分析日誌,確認流量是否按照預期被導向後端的 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:80my-service 的 IP 位址和埠號)的流量都會被丟棄。這可能是因為 kube-proxy 沒有正確設定 iptables 規則,或者存在其他的網路策略阻止了流量。

4. 其他網路問題的診斷

4.1 NAT 問題

iptablesnat 表用於網路位址轉換(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 如何處理封包至關重要。對於從系統發出的封包,其處理順序如下:

  1. 路由選擇(Routing)
  2. 原始表格(raw table)的輸出鏈(OUTPUT Chain)
  3. Mangle 表格的輸出鏈(Mangle OUTPUT Chain)
  4. NAT 表格的輸出鏈(NAT OUTPUT Chain)
  5. 過濾器表格的輸出鏈(Filter OUTPUT Chain)
  6. 路由選擇(Routing)
  7. Mangle 表格的 POSTROUTING 鏈(Mangle POSTROUTING Chain)
  8. 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 進行封包追蹤是網路管理和安全中不可或缺的技能。理解 PACKETTRACE 行的含義,熟悉 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 表中,封包會經過多個鏈的處理,例如 OUTPUTcali-OUTPUTcali-fip-dnatKUBE-SERVICES 等。這些鏈負責執行不同的網路位址轉換操作,以確保封包可以正確地路由到目標 Pod。

封包追蹤範例:nat:OUTPUT 鏈的深入分析

以下是一個封包追蹤的範例,展示了封包如何透過 nat:OUTPUT 鏈進行處理:

  1. 封包首先進入 nat:OUTPUT 鏈。
  2. 接著,封包被轉發到 nat:cali-OUTPUT 鏈,然後再到 nat:cali-fip-dnat 鏈。
  3. 之後,封包回傳到 nat:OUTPUT 鏈,並繼續處理下一條規則,也就是 nat:KUBE-SERVICES 鏈。
  4. nat:KUBE-SERVICES 鏈中,封包會根據目標 IP 位址(10.43.156.98)被轉發到 nat:KUBE-SVC-Y4T5L63IYP3YFEBS 鏈。
  5. nat:KUBE-SVC-Y4T5L63IYP3YFEBS 鏈中,如果封包的來源 IP 位址不屬於 10.42.0.0/16 子網(表示封包不是來自另一個 Pod),則會被轉發到 nat:KUBE-MARK-MASQ 鏈,並被標記為 0x4000。
  6. 最後,封包會被轉發到 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-FIREWALLKUBE-SERVICESKUBE-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 的流量。我們可以按照以下步驟進行:

  1. 找到 Pod 和 Service 的 IP 位址:使用 kubectl get pods -o widekubectl get svc 指令,找到目標 Pod 和 Service 的 IP 位址。
  2. 新增 iptables 規則:在執行 Pod 的節點上,使用 iptables -t nat -A POSTROUTING -d <Service IP> -j TRACE 指令,將所有目標位址為 Service IP 的封包導向 TRACE 目標。
  3. 檢查核心日誌:使用 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 網路的挑戰,並構建更可靠、高效和安全的應用程式。