Kubernetes 是一款開源工具,在 容器協調 (container orchestration) 中至關重要。Kubernetes 有助於在各種雲端環境甚至本地端伺服器中大規模協調和管理叢集。叢集是一組用於運行容器化應用程式和服務的主機。叢集至少需要兩個節點才能運作 – 一個主節點 (master node) 和一個工作節點 (worker node)。您可以透過增加更多工作節點來擴充您的 Kubernetes 基礎架構。主節點及其工作節點必須能夠透過網路進行通訊,基礎架構才能正常運作。如需了解 Kubernetes 最重要功能的概覽,請參閱我們的教學課程:認識 Kubernetes.
在本教學課程中,我們將向您展示 幾種有助於檢查 Kubernetes 網路並進行疑難排解的工具和技術。
先決條件
-
若要跟著本教學課程操作,您應該要有一個 Kubernetes 叢集。我們有一篇教學課程解釋了 如何在 Ubuntu 20.04 上安裝和使用 Kubernetes ,可以引導您設定用於示範的基本叢集。
-
您還應該擁有 kubectl 並安裝在本地。根據您的本地環境,請遵循官方文件關於 安裝 Kubernetes 工具 的說明。 kubectl 應配置為連接到您的叢集。我們將在下面的章節中進一步說明。
我們將在本地和 Kubernetes 節點上執行多個指令。讓我們開始吧!
配置本地 kubectl 以連接到遠端 Kubernetes 叢集
首先讓我們安裝 kubectl。我們的本地環境運行的是 Ubuntu,如果您運行的是不同的本地環境,請點擊 此連結。若要安裝 kubectl 工具於使用 apt 套件管理器的 Ubuntu/Debian 本地環境中,請執行以下指令來更新 apt 套件庫並安裝必要的套件:
|
1 2 |
sudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl |
接下來,執行以下指令下載 Google 雲端公開簽章金鑰:
|
1 |
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg |
然後,新增 Kubernetes apt 套件庫:
|
1 |
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list |
之後,更新 apt 索引並安裝 kubectl ,請使用以下指令:
|
1 2 |
sudo apt-get update sudo apt-get install -y kubectl |
然後,驗證 kubectl 是否已安裝,請使用以下指令檢查版本:
|
1 |
kubectl version |
如果您剛剛在本地安裝了 kubectl ,以下是輸出結果:

在上面的螢幕截圖中, kubectl 正嘗試連接到本地 Kubernetes 叢集。然而,連接失敗了,因為我們的本地電腦上尚未運行 Kubernetes 叢集。
要連接到遠端 Kubernetes 叢集,您首先需要從遠端叢集下載 Kubernetes 憑證。以下是從主節點複製憑證的指令:
|
1 |
scp -r hackins@178.22.66.253:/home/hackins/.kube . |
將醒目提示的部分替換為您的 ssh 使用者名稱和主節點的公用 IP。憑證下載完成後,將憑證複製到您的家目錄 (home directory):
|
1 |
cp -r .kube $HOME/ |
就這樣。您的本地 kubectl 應該就能夠連接到您的遠端 Kubernetes 叢集並發布指令。要確認您的本地 kubectl 已連接到遠端叢集,請再次使用 version 指令進行檢查:
|
1 |
kubectl version --output='json' |
以下是輸出結果,顯示連線成功:

(選填)您可以執行 get nodes 指令,如下所示:

獲取 Pod 的 Cluster IP
您可以透過在本地機器上執行 kubectl get pod 指令來獲取 Pod 的 Cluster IP。若要列出更多資訊(例如託管該 Pod 的節點以及 Pod 的 Cluster IP),請在指令中加入 -o wide 旗標:
|
1 |
kubectl get pod -o wide |
以下是來自我們 Kubernetes 叢集的輸出。如您所見,在先決條件教學課程中,我們已建立了一個 Nginx 網頁伺服器部署:

IP 欄位顯示個別 Pod 的內部 IP 位址。如果您尋找的 Pod 未出現在清單中,您可能處於不同的命名空間。您可以發送以下指令來列出所有 命名空間:
|
1 |
kubectl get pod -o wide --all-namespaces |
獲取 Service 的 IP 位址
您也可以獲取叢集上 Service 的 IP 位址。透過加入 --all-namespaces 旗標,您可以獲取在叢集上執行的所有服務:
|
1 |
kubectl get service --all-namespaces |
上述指令的輸出如下。Service IP 位於 cluster-ip 欄位:

獲取並存取 Pod 網路命名空間
每個 Kubernetes Pod 都分配有一個網路命名空間。網路命名空間(也稱為 netns)是 Linux 中的原生網路函式庫,用於提供網路裝置之間的隔離。
若要檢查 DNS 解析或一般網路連線,您可以在 Pod 的網路命名空間內執行指令。為此,您首先需要尋找 Pod 中其中一個容器的處理程序 ID(process ID)。您可以在 Docker 中使用 Docker 特定的指令輕鬆完成此操作。第一個指令會列出在節點上執行的容器。登入您的其中一個工作節點並執行以下指令:
|
1 |
docker ps |

在輸出中,我們感興趣的是 container ID 或 Names 欄位。請注意我們在先決條件教學課程 如何在 Ubuntu 20.04 上安裝與使用 Kubernetes.
接下來,複製 container ID 或 Name,因為我們將在下一個指令中使用它來尋找處理程序 ID:
|
1 |
docker inspect --format '{{ .State.Pid }}' container-id-或-name |
將醒目提示的部分替換為您從上一個指令中複製的值。以下是我們獲得的輸出,即處理程序 ID:

現在我們有了處理程序 ID,我們可以使用它在該處理程序的網路命名空間內執行 nsenter 指令:
|
1 |
sudo nsenter -t container-pid -n ip addr |
將醒目提示的部分替換為您在上一個指令中獲得的處理程序 ID。然後在 ip addr 的位置,您可以輸入任何您想在 Pod 網路命名空間內執行的指令。如果您遇到權限不足的錯誤,也可以使用 sudo 來執行它。
The nsenter 指令允許您執行節點上可用之更廣泛的指令,相較於使用 docker exec ,後者僅限制您使用容器內已安裝的指令。
檢索 Pod 的虛擬乙太網路介面
Pod 上的網路命名空間透過虛擬乙太網路管道與節點的根 netns 進行通訊。在節點端,此管道顯示為一個名稱以 veth 開頭並以唯一識別碼結尾的裝置,例如 veth742f721 或 veth90。而在 Pod 內部,該管道則識別為 eth0.
您可能想知道哪一個 veth 裝置與哪一個 Pod 配對。您可以先列出節點上的所有網路裝置,然後列出 Pod 網路中的所有裝置。若要識別哪一個 veth 裝置與特定 Pod 配對,您可以對照這兩個清單之間的裝置編號。
使用 nsenter 指令在 Pod 的網路命名空間中執行 ip addr 指令。您需要知道其中一個容器的處理程序 ID。為此,請參閱前一節關於 獲取並存取 Pod 網路命名空間.
接下來,在工作節點的終端機上執行以下命令,並適當替換突出顯示的部分:
|
1 |
sudo nsenter -t container-pid -n ip addr |
該命令會輸出 Pod 的介面清單:

請注意 if7 字元,位於 之後eth0@(在上述輸出中)。這代表 Pod 的 eth0 與節點的第 7 個介面配對。接下來,透過執行 ip addr 命令來列出節點預設命名空間內的介面:
|
1 |
ip addr |
該命令列出的介面如下所示:

在輸出中,第 7 個介面是 veth254b50e6@if3 – 與我們正在測試的 Pod 配對的虛擬乙太網路管道。
審查 Iptables 規則
您可以執行命令 iptables-save 以列出節點上的所有 iptables:
|
1 |
iptables-save |
該命令的輸出可能會很長,因此您可以將其儲存到檔案中以便稍後檢查:
|
1 |
iptables-save > iptables.txt |
您也可以使用 less 來對輸出進行分頁:
|
1 |
iptables-save | less |
由於我們只對 Kubernetes NAT 規則感興趣,請加入 -L 標記以指定正確的目標:
|
1 |
sudo iptables -t nat -L KUBE-SERVICES |
以下是輸出:

檢查 IPVS 詳細資訊
Kube-proxy 是在 Kubernetes 叢集中每個節點上執行的網路代理。它可用於設定 IPVS 以處理虛擬 Service IP 到 Pod IP 的轉換。要列出 IP 的轉換表,您可以使用 ipvsadm command. First, you need to install it on your node:
|
1 |
sudo apt install ipvsadm |
現在您可以執行以下命令:
|
1 |
sudo ipvsadm -Ln |
要顯示單個 Service IP,請加入 -t 標記,並指定所需的 IP 位址:
|
1 |
ipvsadm -Ln -t 10.244.1.255 |
查詢叢集 DNS
有幾種方法可以用來偵錯您的叢集 DNS 解析。官方文件 描述了其中一種方法:部署一個包含所有必要工具的偵錯容器,然後使用 kubectl 來執行 nslookup.
或者,您也可以在節點本身使用 dig 和 nsenter 命令來查詢 DNS。首先,您必須在主節點上安裝 dig。對於 Ubuntu,請使用 apt 命令進行安裝:
|
1 |
sudo apt install dnsutils |

回到本機電腦上的終端機,並執行以下命令以尋找 kube-dns 服務的叢集 IP:
|
1 |
kubectl get service -n kube-system kube-dns |
命令輸出:

在 cluster-ip 欄位中包含我們所需的值。現在我們可以使用 nsenter 在容器命名空間中執行 dig 。但是,您需要容器的處理程序 ID (PID) 才能存取其命名空間。請參閱上方的 獲取並存取 Pod 網路命名空間 章節以獲取指引。
一旦您取得 container-id,請在您的主節點上執行以下命令:
|
1 |
sudo nsenter -t 27168 -n dig kubernetes.default.svc.cluster.local @10.96.0.10 |
該 dig 命令會使用叢集 DNS 服務的 IP ( @10.96.0.10) 並查詢該服務的完整網域名稱 service-name.namespace.svc.cluster.local:

有關尋找服務名稱和命名空間的資訊,請參閱 獲取服務的 IP 位址.
審查 Conntrack 連線追蹤
您可以使用 conntrack 命令來檢視目前正在追蹤的所有連線:
|
1 |
sudo conntrack -L |
其輸出類似於螢幕截圖:

加入 -E 標記以持續監控傳入的連線:
|
1 |
sudo conntrack -E |
要檢視追蹤到特定目的地位址的連線,請加入 -d 標記並指定目的地位址:
|
1 |
sudo conntrack -L -d 80.45.6.4 |
有時連線追蹤表會被填滿,導致新的連線被捨棄。這會導致您的節點無法建立可靠連線的問題。如果發生這種情況,您將在系統記錄中的以下位置看到類似以下的訊息: /var/log/syslog:
|
1 |
Mar 07 19:12:11 worker-105 kernel: nf_conntrack: table full, dropping packet. |
系統中存在一個用於追蹤最大連線數的設定。請使用以下指令列出您目前的值:
|
1 |
sysctl net.netfilter.nf_conntrack_max |
其輸出如下:

您可以使用 -w 旗標:
|
1 |
sudo sysctl -w net.netfilter.nf_conntrack_max=231074 |
您可能需要修改您的 /etc/sysctl.conf 檔案以使該值永久生效,並確保在重新啟動後仍能保留。使用 nano 開啟該檔案:
|
1 |
sudo nano /etc/sysctl.conf |
接下來,如果該行已存在,請修改其值;如果不存在,請在檔案末尾新增該行,並指定新值:
|
1 |
net.netfilter.nf_conntrack_max=231074 |
結論
當部署多個容器化服務時,您將從 Kubernetes 中獲益匪淺,因為它為您提供了一個集中管理點。為了確保各個 Kubernetes pod 之間的連線能力,我們向您展示了一些網路檢查指令,您可以使用這些指令來排查 Kubernetes 基礎架構周邊的任何問題。
若要深入了解 Kubernetes、其優勢以及在 Kubernetes 上設定和部署應用程式,請參閱我們的各種 Kubernetes 教學.
祝您運算愉快!
留言
目前尚無留言。成為第一個留言的人吧。