1. 程式人生 > 其它 >k8s使用臨時容器排查故障

k8s使用臨時容器排查故障

容器及其周圍的生態系統改變了工程師部署、維護和排查工作負載故障的方式。但是,在 Kubernetes 叢集上除錯應用程式有時可能會很困難,因為你可能在容器中找不到所需的除錯工具。許多工程師使用基於精簡、發行版構建無發行版的基礎映象,其中甚至沒有包管理器或shell。甚至一些團隊使用 scratch 作為基礎映象,並且只新增應用程式執行所需的檔案。這種常見做法的一些原因是:

  • 具有較小的攻擊區域。
  • 為了獲得更快的掃描效能。
  • 減小了映象大小。
  • 為了有更快的構建和更短CD/CI週期。
  • 減少依賴關係。

這些精簡的基礎映象不包括用於對應用程式或其依賴項進行故障排查的工具。這是 Kubernetes 臨時容器功能最大用途。臨時容器允許建立包含可能需要的所有除錯工具的容器映象。一旦需要除錯,就可以將臨時容器部署到所選的正在執行的 Pod 中。我們不能將容器新增到已部署的容器;您需要更新spec,並重新建立資源。但是,可以將臨時容器新增到現有 Pod 中,以便對線上問題進行故障排查。本文介紹如何使用臨時容器進行Kubernetes上工作負載的問題排查。

臨時容器的配置

臨時容器與常規容器共享相同的spec。但是,某些欄位被禁用,並且某些行為被更改。下面列出了一些重大變化;檢查臨時容器規範以獲取完整列表。

  • 它們不會重新啟動。
  • 不允許定義資源。
  • 不允許使用埠。
  • 不允許使用啟動、活動和就緒探測。

啟動臨時容器

首先,檢查是否啟用了臨時容器功能。

kubectldebug-it<POD_NAME>--image=busybox

如果未啟用該功能,您將看到類似下面的訊息。

Defaultingdebugcontainernametodebugger-wg54p.
error:ephemeralcontainersaredisabledforthiscluster(errorfromserver:"theservercouldnotfindtherequestedresource").

將 EphemeralContainers=true 附加到 kubelet、kube-apiserver、kube-controller-manager、kube-proxy、kube-scheduler 引數中的--feature-gates=後, 例如:

...
--feature-gates=RemoveSelfLink=false,EphemeralContainers=true
...

使用臨時容器

現在,叢集支援臨時容器功能,讓我們來試試吧。要建立臨時容器,使用 kubectl 命令列工具的 debug 子命令。首先,建立一個Deployment

kubectlcreatedeploymentnginx-deployment--image=nginx

獲取需要debug的Pod的名稱

$kubectlgetpods

NAMEREADYSTATUSRESTARTSAGE
nginx-deployment-66b6c48dd5-frsv91/1Running662d

以下命令將在 pod nginx-deployment-66b6c48dd5-frsv9 中建立一個新的臨時容器。臨時容器的映象是busybox。-i 和 -t 引數允許我們附加到新建立的容器。

$kubectldebug-itpods/nginx-deployment-66b6c48dd5-frsv9--image=busybox

現在我們可以debug了

/#ping8.8.8.8
PING8.8.8.8(8.8.8.8):56databytes
64bytesfrom8.8.8.8:seq=0ttl=112time=9.797ms
64bytesfrom8.8.8.8:seq=1ttl=112time=9.809ms
^C
/#nc--help
BusyBoxv1.34.1(2021-11-1101:55:05UTC)multi-callbinary.

Usage:nc[OPTIONS]HOSTPORT-connect
nc[OPTIONS]-l-pPORT[HOST][PORT]-listen
...

當使用 kubectl describe pod <POD_NAME> 命令時,可以看到一個新欄位 "Ephemeral Containers",此部分包含臨時容器及其屬性。

$kubectldescribepods<POD_NAME>

...
...
EphemeralContainers:
debugger-thwrn:
ContainerID:containerd://eec23aa9ee63d96b82970bb947b29cbacc30685bbc3418ba840dee109f871bf0
Image:busybox
ImageID:docker.io/library/busybox@sha256:e7157b6d7ebbe2cce5eaa8cfe8aa4fa82d173999b9f90a9ec42e57323546c353
Port:<none>
HostPort:<none>

與臨時容器共享程序名稱空間

程序名稱空間共享一直是一個很好的故障排查選項,此功能可用於臨時容器。程序名稱空間共享不能應用於現有容器,因此必須建立目標容器的副本。--share-processesflag 在與 --copy-to 一起使用時,可實現程序名稱空間共享。這些標誌將現有的 Pod spec定義複製到新定義中,並在spec中啟用了程序名稱空間共享。

$kubectldebug-it<POD_NAME>--image=busybox--share-processes--copy-to=debug-pod

執行 ps 命令以檢視正在執行的程序。正如您所期望的那樣,您可以從 busybox 容器中看到 /pause,從 nginx-deployment 容器中看到 nginx 程序。

#psaux

PIDUSERTIMECOMMAND
1root0:00/pause
6root0:00nginx:masterprocessnginx-gdaemonoff;
111010:00nginx:workerprocess
12root0:00sh
17root0:00psaux

使用程序名稱空間,共享容器檔案系統也是可訪問的,這對於除錯非常有用。您可以使用 /proc//root 連結訪問容器。從上面的輸出中,我們知道nginx的PID為6。

#ls/proc/6/root/etc/nginx

conf.dkoi-utfmime.typesnginx.confuwsgi_paramsfastcgi_paramskoi-winmodulesscgi_paramswin-utf

在這裡,我們可以看到目標容器上的Nginx目錄結構和配置檔案。

結論

臨時容器功能無疑給除錯排查問題帶來了很大便利,而程序名稱空間共享允許高階除錯功能。如果你也使用在 Kubernetes 叢集中執行的應用程式,那麼值得花時間嘗試這些功能。不難想象,一些團隊甚至使用這些工具自動執行工作流,例如在readiness probes探針失敗時自動修復其他容器。

原文:https://tinyurl.com/3658tdzs