返回部落格

如何排查與檢視 Kubernetes 網路

如何排查與檢視 Kubernetes 網路

Kubernetes 是一款開源工具,在 容器協調 (container orchestration) 中至關重要。Kubernetes 有助於在各種雲端環境甚至本地端伺服器中大規模協調和管理叢集。叢集是一組用於運行容器化應用程式和服務的主機。叢集至少需要兩個節點才能運作 – 一個主節點 (master node) 和一個工作節點 (worker node)。您可以透過增加更多工作節點來擴充您的 Kubernetes 基礎架構。主節點及其工作節點必須能夠透過網路進行通訊,基礎架構才能正常運作。如需了解 Kubernetes 最重要功能的概覽,請參閱我們的教學課程:認識 Kubernetes.

在本教學課程中,我們將向您展示 幾種有助於檢查 Kubernetes 網路並進行疑難排解的工具和技術。

先決條件

  • 您還應該擁有 kubectl 並安裝在本地。根據您的本地環境,請遵循官方文件關於 安裝 Kubernetes 工具 的說明。 kubectl 應配置為連接到您的叢集。我們將在下面的章節中進一步說明。

我們將在本地和 Kubernetes 節點上執行多個指令。讓我們開始吧!

配置本地 kubectl 以連接到遠端 Kubernetes 叢集

首先讓我們安裝 kubectl。我們的本地環境運行的是 Ubuntu,如果您運行的是不同的本地環境,請點擊 此連結。若要安裝 kubectl 工具於使用 apt 套件管理器的 Ubuntu/Debian 本地環境中,請執行以下指令來更新 apt 套件庫並安裝必要的套件:

接下來,執行以下指令下載 Google 雲端公開簽章金鑰:

然後,新增 Kubernetes apt 套件庫:

之後,更新 apt 索引並安裝 kubectl ,請使用以下指令:

然後,驗證 kubectl 是否已安裝,請使用以下指令檢查版本:

如果您剛剛在本地安裝了 kubectl ,以下是輸出結果:

kubectl version

在上面的螢幕截圖中, kubectl 正嘗試連接到本地 Kubernetes 叢集。然而,連接失敗了,因為我們的本地電腦上尚未運行 Kubernetes 叢集。

要連接到遠端 Kubernetes 叢集,您首先需要從遠端叢集下載 Kubernetes 憑證。以下是從主節點複製憑證的指令:

將醒目提示的部分替換為您的 ssh 使用者名稱和主節點的公用 IP。憑證下載完成後,將憑證複製到您的家目錄 (home directory):

就這樣。您的本地 kubectl 應該就能夠連接到您的遠端 Kubernetes 叢集並發布指令。要確認您的本地 kubectl 已連接到遠端叢集,請再次使用 version 指令進行檢查:

以下是輸出結果,顯示連線成功:

kubectl version json

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

kubectl get nodes

獲取 Pod 的 Cluster IP

您可以透過在本地機器上執行 kubectl get pod 指令來獲取 Pod 的 Cluster IP。若要列出更多資訊(例如託管該 Pod 的節點以及 Pod 的 Cluster IP),請在指令中加入 -o wide 旗標:

以下是來自我們 Kubernetes 叢集的輸出。如您所見,在先決條件教學課程中,我們已建立了一個 Nginx 網頁伺服器部署:

kubectl get pod -o wide

IP 欄位顯示個別 Pod 的內部 IP 位址。如果您尋找的 Pod 未出現在清單中,您可能處於不同的命名空間。您可以發送以下指令來列出所有 命名空間:

獲取 Service 的 IP 位址

您也可以獲取叢集上 Service 的 IP 位址。透過加入 --all-namespaces 旗標,您可以獲取在叢集上執行的所有服務:

上述指令的輸出如下。Service IP 位於 cluster-ip 欄位:

kubectl get svc

獲取並存取 Pod 網路命名空間

每個 Kubernetes Pod 都分配有一個網路命名空間。網路命名空間(也稱為 netns)是 Linux 中的原生網路函式庫,用於提供網路裝置之間的隔離。

若要檢查 DNS 解析或一般網路連線,您可以在 Pod 的網路命名空間內執行指令。為此,您首先需要尋找 Pod 中其中一個容器的處理程序 ID(process ID)。您可以在 Docker 中使用 Docker 特定的指令輕鬆完成此操作。第一個指令會列出在節點上執行的容器。登入您的其中一個工作節點並執行以下指令:

docker ps

在輸出中,我們感興趣的是 container ID 或 Names 欄位。請注意我們在先決條件教學課程 如何在 Ubuntu 20.04 上安裝與使用 Kubernetes.

接下來,複製 container ID 或 Name,因為我們將在下一個指令中使用它來尋找處理程序 ID:

將醒目提示的部分替換為您從上一個指令中複製的值。以下是我們獲得的輸出,即處理程序 ID:

docker inspect

現在我們有了處理程序 ID,我們可以使用它在該處理程序的網路命名空間內執行 nsenter 指令:

將醒目提示的部分替換為您在上一個指令中獲得的處理程序 ID。然後在 ip addr 的位置,您可以輸入任何您想在 Pod 網路命名空間內執行的指令。如果您遇到權限不足的錯誤,也可以使用 sudo 來執行它。

The nsenter 指令允許您執行節點上可用之更廣泛的指令,相較於使用 docker exec ,後者僅限制您使用容器內已安裝的指令。

檢索 Pod 的虛擬乙太網路介面

Pod 上的網路命名空間透過虛擬乙太網路管道與節點的根 netns 進行通訊。在節點端,此管道顯示為一個名稱以 veth 開頭並以唯一識別碼結尾的裝置,例如 veth742f721veth90。而在 Pod 內部,該管道則識別為 eth0.

您可能想知道哪一個 veth 裝置與哪一個 Pod 配對。您可以先列出節點上的所有網路裝置,然後列出 Pod 網路中的所有裝置。若要識別哪一個 veth 裝置與特定 Pod 配對,您可以對照這兩個清單之間的裝置編號。

使用 nsenter 指令在 Pod 的網路命名空間中執行 ip addr 指令。您需要知道其中一個容器的處理程序 ID。為此,請參閱前一節關於 獲取並存取 Pod 網路命名空間.

接下來,在工作節點的終端機上執行以下命令,並適當替換突出顯示的部分:

該命令會輸出 Pod 的介面清單:

nsenter ip addr

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

該命令列出的介面如下所示:

Kubernetes Networking ip addr

在輸出中,第 7 個介面是 veth254b50e6@if3  – 與我們正在測試的 Pod 配對的虛擬乙太網路管道。

審查 Iptables 規則

您可以執行命令 iptables-save 以列出節點上的所有 iptables:

該命令的輸出可能會很長,因此您可以將其儲存到檔案中以便稍後檢查:

您也可以使用 less 來對輸出進行分頁:

由於我們只對 Kubernetes NAT 規則感興趣,請加入 -L 標記以指定正確的目標:

以下是輸出:

Kubernetes Networking iptables

檢查 IPVS 詳細資訊

Kube-proxy 是在 Kubernetes 叢集中每個節點上執行的網路代理。它可用於設定 IPVS 以處理虛擬 Service IP 到 Pod IP 的轉換。要列出 IP 的轉換表,您可以使用 ipvsadm command. First, you need to install it on your node:

現在您可以執行以下命令:

要顯示單個 Service IP,請加入 -t 標記,並指定所需的 IP 位址:

查詢叢集 DNS

有幾種方法可以用來偵錯您的叢集 DNS 解析。官方文件 描述了其中一種方法:部署一個包含所有必要工具的偵錯容器,然後使用 kubectl 來執行 nslookup.

或者,您也可以在節點本身使用 dignsenter 命令來查詢 DNS。首先,您必須在主節點上安裝 dig。對於 Ubuntu,請使用 apt 命令進行安裝:

Kubernetes Networking install dnsutils

回到本機電腦上的終端機,並執行以下命令以尋找 kube-dns 服務的叢集 IP:

命令輸出:

get kube dns service

cluster-ip 欄位中包含我們所需的值。現在我們可以使用 nsenter 在容器命名空間中執行 dig 。但是,您需要容器的處理程序 ID (PID) 才能存取其命名空間。請參閱上方的 獲取並存取 Pod 網路命名空間 章節以獲取指引。

一旦您取得 container-id,請在您的主節點上執行以下命令:

dig 命令會使用叢集 DNS 服務的 IP ( @10.96.0.10) 並查詢該服務的完整網域名稱 service-name.namespace.svc.cluster.local:

Kubernetes Networking nsenter dig

有關尋找服務名稱和命名空間的資訊,請參閱 獲取服務的 IP 位址.

審查 Conntrack 連線追蹤

您可以使用 conntrack 命令來檢視目前正在追蹤的所有連線:

其輸出類似於螢幕截圖:

Kubernetes Networking conntrac -l

加入 -E 標記以持續監控傳入的連線:

要檢視追蹤到特定目的地位址的連線,請加入 -d 標記並指定目的地位址:

有時連線追蹤表會被填滿,導致新的連線被捨棄。這會導致您的節點無法建立可靠連線的問題。如果發生這種情況,您將在系統記錄中的以下位置看到類似以下的訊息: /var/log/syslog:

系統中存在一個用於追蹤最大連線數的設定。請使用以下指令列出您目前的值:

其輸出如下:

conntrack max

您可以使用 -w 旗標:

您可能需要修改您的 /etc/sysctl.conf 檔案以使該值永久生效,並確保在重新啟動後仍能保留。使用 nano 開啟該檔案:

接下來,如果該行已存在,請修改其值;如果不存在,請在檔案末尾新增該行,並指定新值:

結論

當部署多個容器化服務時,您將從 Kubernetes 中獲益匪淺,因為它為您提供了一個集中管理點。為了確保各個 Kubernetes pod 之間的連線能力,我們向您展示了一些網路檢查指令,您可以使用這些指令來排查 Kubernetes 基礎架構周邊的任何問題。

若要深入了解 Kubernetes、其優勢以及在 Kubernetes 上設定和部署應用程式,請參閱我們的各種 Kubernetes 教學.

祝您運算愉快!

author

Pranay Kapgate

作者 · CloudSigma

Preslav Dobrev 是 CloudSigma 的創意設計師,專注於透過傳統與創新行銷渠道建立一致的企業形象。他擅長將藝術願景與策略行銷相融合,創造具有影響力的品牌敘事。

留言

目前尚無留言。成為第一個留言的人吧。