---
# System prepended metadata

title: Debugging using a copy of the Pod
tags: [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-debug` 的 `myapp` 副本，並添加一個新的 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](https://kubernetes.io/docs/tasks/configure-pod-container/share-process-namespace/)。
- `--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](https://kubernetes.io/docs/concepts/security/pod-security-standards/#baseline) 相容的屬性
`restricted` | 一組與 [PodSecurityStandard restricted policy](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted) 相容的屬性
`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](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-capabilities-for-a-container) 的更多細節。

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

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

執行結果 : 

```
{"privileged":true}
```

完成後，清理該 Pod：

```
kubectl delete pod myapp
```

## Ref

- [Debugging using a copy of the Pod - Kubernetes Docs](https://kubernetes.io/docs/tasks/debug/debug-application/debug-running-pod/#debugging-using-a-copy-of-the-pod)
