Skip to content

antony@notes:~/kubernetes$ cat "Debugging-using-a-copy-of-the-Pod.md"

Debugging using a copy of the Pod

2024-10-26· kubernetes ·Kubernetes

Debugging using a copy of the Pod

有時候,Pod 的設定選項會使某些情況下的排查變得困難。例如,如果 container image 不包含 shell,或者應用程式在啟動時崩潰,就無法使用 kubectl exec 來排查 container。在這些情況下,可以使用 kubectl debug 創建一個 Pod 的副本,並更改設定值以便進行除錯。

Copying a Pod while adding a new container

當您的應用程式正在運行但行為不符合預期時,添加一個新 Container 可能會很有用,因為這樣可以向 Pod 添加額外的除錯工具。

例如,您的應用程式 container images 可能基於 busybox 構建,但您需要一些 busybox 中未包含的除錯工具。您可以使用 kubectl run 模擬這種情況:

$ kubectl run myapp --image=busybox:1.28 --restart=Never -- sleep 1d

運行此命令以創建一個名為 myapp-debugmyapp 副本,並添加一個新的 Ubuntu container 進行除錯:

$ kubectl debug myapp -it --image=ubuntu --share-processes --copy-to=myapp-debug

執行結果 :

Defaulting debug container name to debugger-bzgnv.
If you don't see a command prompt, try pressing enter.
root@myapp-debug:/#
  • 如果沒有使用 --container 標誌選擇 container 名稱,kubectl debug 會自動生成一個 container 名稱。
  • myapp,要排除故障的 Pod 名稱。
  • -i 標誌使 kubectl debug 默認連接到新 container。您可以通過指定 --attach=false 來防止這種情況發生。如果會話被斷開連接,可以使用 kubectl attach 重新連接。
  • -t,為 container 分配一個虛擬終端(TTY),使您能夠與 container交互。
  • --image='', debug container 使用的 Container image.
  • --share-processes 允許這個 Pod 中的 container 查看其他 container 中的 processes。要了解更多有關其工作原理的信息,請參閱 Share Process Namespace between Containers in a Pod
  • --copy-to='',將原始 Pod myapp 複製為一個新的 Pod,名稱為 myapp-debug

使用完畢後,別忘了清理 debugging Pod:

$ kubectl delete pod myapp myapp-debug

Copying a Pod while changing its command

有時候更改 container 的命令是很有用的,例如添加 debugging flag 或應用程式崩潰時。

要模擬應用程式崩潰,使用 kubectl run 創建一個立即退出的 container :

$ kubectl run --image=busybox:1.28 myapp -- false

您可以使用 kubectl describe pod myapp 看到這個 container 正在崩潰:

Containers:
  myapp:
    Image:         busybox:1.28
    ...
    Args:
      false
    State:          Waiting
      Reason:       CrashLoopBackOff
    Last State:     Terminated
      Reason:       Error
      Exit Code:    1

您可以使用 kubectl debug 創建這個 Pod 的副本,並將命令更改為交互式 shell:

$ kubectl debug myapp -it --copy-to=myapp-debug --container=myapp -- sh

執行結果 :

If you don't see a command prompt, try pressing enter.
/ #

現在您有一個交互式的 shell,可以用來執行檢查文件系統路徑或手動執行 container command 等任務。

:::info

  • 若要更改特定 container 預設執行的命令,您必須使用 --container 指定其名稱,否則 kubectl debug 會創建一個新的 container 來執行您指定的命令。
  • -i 標誌使 kubectl debug 默認連接到 container。您可以通過指定 --attach=false 來防止這種情況。如果會話被斷開連接,可以使用 kubectl attach 重新連接。

:::

使用完畢後,別忘了清理 debugging Pod:

$ kubectl delete pod myapp myapp-debug

Copying a Pod while changing container images

在某些情況下,您可能需要將出現異常行為的 Pod 從其正常的 production container images 更改為包含除錯版本或附加工具的映像。

例如,使用 kubectl run 創建一個 Pod:

$ kubectl run myapp --image=busybox:1.28 --restart=Never -- sleep 1d

現在使用 kubectl debug 創建副本並將其 container image 更改為 Ubuntu:

$ kubectl debug myapp --copy-to=myapp-debug --set-image=*=ubuntu

--set-image 的語法使用與 kubectl set image 相同的 container_name=image 語法。*=ubuntu 表示將所有 containers 的 image 更改為 Ubuntu。

完成後,別忘了清理除錯用的 Pod:

$ kubectl delete pod myapp myapp-debug

Debugging Profiles

當使用 kubectl debug 透過除錯 Pod 來對節點進行除錯,或通過 ephemeral container 對 Pod 進行除錯,或者使用 Pod 副本時,可以使用 --profile 標誌對它們套用除錯設定檔。通過套用設定檔,可以設置特定的屬性,如 securityContext,以適應不同的情境。

可用的設定檔如下:

Profile描述
legacy一組與 1.22 行為向後相容的屬性
general為每次除錯過程提供合理的一組通用屬性
baseline一組與 PodSecurityStandard baseline policy 相容的屬性
restricted一組與 PodSecurityStandard restricted policy 相容的屬性
netadmin包含一組網路管理員權限的屬性
sysadmin包含一組系統管理員(root)權限的屬性集

如果您未指定 --profile,則會默認使用 legacy 配置檔,但計劃在不久的將來棄用它。因此,建議使用其他配置檔,例如 general

假設您創建一個 Pod 並對其進行除錯。首先,創建一個名為 myapp 的 Pod 作為示例:

$ kubectl run myapp --image=busybox:1.28 --restart=Never -- sleep 1d

接著,使用 ephemeral container 對該 Pod 進行除錯。如果 ephemeral container 需要具有權限,您可以使用 sysadmin 設定檔:

$ kubectl debug -it myapp --image=busybox:1.28 --target=myapp --profile=sysadmin

執行結果 :

Targeting container "myapp". If you don't see processes from this container it may be because the container runtime doesn't support this feature.
Defaulting debug container name to debugger-zdxhp.
If you don't see a command prompt, try pressing enter.
/ #

在 container 內運行以下命令來檢查 ephemeral container process 的 capabilities :

$ grep Cap /proc/$$/status

執行結果 :

CapInh: 0000000000000000
CapPrm: 000001ffffffffff
CapEff: 000001ffffffffff
CapBnd: 000001ffffffffff
CapAmb: 0000000000000000

這意味著通過應用 sysadmin 設定檔,container process 被授予作為 privileged container 的完整能力。查看有關 capabilities 的更多細節。

您也可以檢查該 ephemeral container 是否被創建為 privileged container:

$ kubectl get pod myapp -o jsonpath='{.spec.ephemeralContainers[0].securityContext}'

執行結果 :

{"privileged":true}

完成後,清理該 Pod:

kubectl delete pod myapp

Ref