From b2168622352f880fd47b24e27d8730900f0884a4 Mon Sep 17 00:00:00 2001 From: "wei.wang" Date: Sun, 1 May 2022 17:40:54 +0800 Subject: [PATCH] [zh]Update content/zh/docs/concepts/workloads/pods/ephemeral-containers.md [zh]Update content/zh/docs/tasks/debug/debug-application/debug-running-pod.md [zh]Update content/zh/docs/tasks/debug/debug-application/debug-running-pod.md --- .../workloads/pods/ephemeral-containers.md | 4 +- .../debug-application/debug-running-pod.md | 506 ++++++++++++++++++ 2 files changed, 508 insertions(+), 2 deletions(-) create mode 100644 content/zh/docs/tasks/debug/debug-application/debug-running-pod.md diff --git a/content/zh/docs/concepts/workloads/pods/ephemeral-containers.md b/content/zh/docs/concepts/workloads/pods/ephemeral-containers.md index 7ce87f544c..0535b4afe3 100644 --- a/content/zh/docs/concepts/workloads/pods/ephemeral-containers.md +++ b/content/zh/docs/concepts/workloads/pods/ephemeral-containers.md @@ -129,6 +129,6 @@ you can view processes in other containers. {{% heading "whatsnext" %}} -* 了解如何[使用临时调试容器来进行调试](/zh/docs/tasks/debug-application-cluster/debug-running-pod/#ephemeral-container) +* 了解如何[使用临时调试容器来进行调试](/zh/docs/tasks/debug/debug-application/debug-running-pod/#ephemeral-container) diff --git a/content/zh/docs/tasks/debug/debug-application/debug-running-pod.md b/content/zh/docs/tasks/debug/debug-application/debug-running-pod.md new file mode 100644 index 0000000000..e5bee6d8b4 --- /dev/null +++ b/content/zh/docs/tasks/debug/debug-application/debug-running-pod.md @@ -0,0 +1,506 @@ +--- +title: 调试运行中的 Pod +content_type: task +--- + + + +本页解释如何在节点上调试运行中(或崩溃)的 Pod。 + +## {{% heading "prerequisites" %}} + + +* 你的 {{< glossary_tooltip text="Pod" term_id="pod" >}} 应该已经被调度并正在运行中, + 如果你的 Pod 还没有运行,请参阅[应用问题排查](/zh/docs/tasks/debug-application-cluster/debug-application/)。 + +* 对于一些高级调试步骤,你应该知道 Pod 具体运行在哪个节点上,在该节点上有权限去运行一些命令。 + 你不需要任何访问权限就可以使用 `kubectl` 去运行一些标准调试步骤。 + + + + +## 检查 Pod 的日志 {#examine-pod-logs} + +首先,查看受到影响的容器的日志: + +```shell +kubectl logs ${POD_NAME} ${CONTAINER_NAME} +``` + + + +如果你的容器之前崩溃过,你可以通过下面命令访问之前容器的崩溃日志: + +```shell +kubectl logs --previous ${POD_NAME} ${CONTAINER_NAME} +``` + + +## 使用容器 exec 进行调试 {#container-exec} + +如果 {{< glossary_tooltip text="容器镜像" term_id="image" >}} 包含调试程序, +比如从 Linux 和 Windows 操作系统基础镜像构建的镜像,你可以使用 `kubectl exec` 命令 +在特定的容器中运行一些命令: + +```shell +kubectl exec ${POD_NAME} -c ${CONTAINER_NAME} -- ${CMD} ${ARG1} ${ARG2} ... ${ARGN} +``` + + + +{{< note >}} +`-c ${CONTAINER_NAME}` 是可选择的。如果Pod中仅包含一个容器,就可以忽略它。 +{{< /note >}} + + + +例如,要查看正在运行的 Cassandra Pod 中的日志,可以运行: + +```shell +kubectl exec cassandra -- cat /var/log/cassandra/system.log +``` + + + +你可以在 `kubectl exec` 命令后面加上 `-i` 和 `-t` 来运行一个连接到你的终端的 Shell,比如: + +```shell +kubectl exec -it cassandra -- sh +``` + + +若要了解更多内容,可查看[获取正在运行容器的 Shell](/zh/docs/tasks/debug-application-cluster/get-shell-running-container/)。 + + +## 使用临时调试容器来进行调试 {#ephemeral-container} + +{{< feature-state state="beta" for_k8s_version="v1.23" >}} + +当由于容器崩溃或容器镜像不包含调试程序(例如[无发行版镜像](https://github.com/GoogleContainerTools/distroless)等) +而导致 `kubectl exec` 无法运行时,{{< glossary_tooltip text="临时容器" term_id="ephemeral-container" >}}对于排除交互式故障很有用。 + + +## 使用临时容器来调试的例子 {#ephemeral-container-example} + +你可以使用 `kubectl debug` 命令来给正在运行中的 Pod 增加一个临时容器。 +首先,像下例一样创建一个 Pod: + +```shell +kubectl run ephemeral-demo --image=k8s.gcr.io/pause:3.1 --restart=Never +``` + +{{< note >}} +本节示例中使用 `pause` 容器镜像,因为它不包含调试程序,但是这个方法适用于所有容器镜像。 +{{< /note >}} + + +如果你尝试使用 `kubectl exec` 来创建一个 shell,你将会看到一个错误,因为这个容器镜像中没有 shell。 + +```shell +kubectl exec -it ephemeral-demo -- sh +``` + +``` +OCI runtime exec failed: exec failed: container_linux.go:346: starting container process caused "exec: \"sh\": executable file not found in $PATH": unknown +``` + +你可以改为使用 `kubectl debug` 添加调试容器。 +如果你指定 `-i` 或者 `--interactive` 参数,`kubectl` 将自动挂接到临时容器的控制台。 + +```shell +kubectl debug -it ephemeral-demo --image=busybox:1.28 --target=ephemeral-demo +``` + +``` +Defaulting debug container name to debugger-8xzrl. +If you don't see a command prompt, try pressing enter. +/ # +``` + + +此命令添加一个新的 busybox 容器并将其挂接到该容器。`--target` 参数指定另一个容器的进程命名空间。 +这是必需的,因为 `kubectl run` 不能在它创建的 Pod +中启用[共享进程命名空间](/zh/docs/tasks/configure-pod-container/share-process-namespace/)。 + +{{< note >}} +{{< glossary_tooltip text="容器运行时" term_id="container-runtime" >}}必须支持`--target`参数。 +如果不支持,则临时容器可能不会启动,或者可能使用隔离的进程命名空间启动, +以便 `ps` 不显示其他容器内的进程。 +{{< /note >}} + +你可以使用 `kubectl describe` 查看新创建的临时容器的状态: + +```shell +kubectl describe pod ephemeral-demo +``` + +``` +... +Ephemeral Containers: + debugger-8xzrl: + Container ID: docker://b888f9adfd15bd5739fefaa39e1df4dd3c617b9902082b1cfdc29c4028ffb2eb + Image: busybox + Image ID: docker-pullable://busybox@sha256:1828edd60c5efd34b2bf5dd3282ec0cc04d47b2ff9caa0b6d4f07a21d1c08084 + Port: + Host Port: + State: Running + Started: Wed, 12 Feb 2020 14:25:42 +0100 + Ready: False + Restart Count: 0 + Environment: + Mounts: +... +``` + + +完成后,使用 `kubectl delete` 来移除 Pod: + +```shell +kubectl delete pod ephemeral-demo +``` + + +## 通过 Pod 副本调试 + + +有些时候 Pod 的配置参数使得在某些情况下很难执行故障排查。 +例如,在容器镜像中不包含 Shell 或者你的应用程序在启动时崩溃的情况下, +就不能通过运行 `kubectl exec` 来排查容器故障。 +在这些情况下,你可以使用 `kubectl debug` 来创建 Pod 的副本,通过更改配置帮助调试。 + + +### 在添加新的容器时创建 Pod 副本 + + +当应用程序正在运行但其表现不符合预期时,添加新容器可能会帮助你符合预期, +并且你会希望在 Pod 中添加额外的调试工具。 + + +例如,可能你的应用的容器镜像是基于 `busybox` 构造的, +但是你需要 `busybox` 中并不包含的调试工具。 +你可以使用 `kubectl run` 模拟这个场景: + +```shell +kubectl run myapp --image=busybox:1.28 --restart=Never -- sleep 1d +``` + +通过运行以下命令,建立 `myapp` 的一个名为 `myapp-debug` 的副本, +新增了一个用于调试的 Ubuntu 容器, + +```shell +kubectl debug myapp -it --image=ubuntu --share-processes --copy-to=myapp-debug +``` + +``` +Defaulting debug container name to debugger-w7xmf. +If you don't see a command prompt, try pressing enter. +root@myapp-debug:/# +``` + +{{< note >}} +* 如果你没有使用 `--container` 指定新的容器名,`kubectl debug` 会自动生成容器名称。 +* 默认情况下,`-i` 标志使 `kubectl debug` 附加到新容器上。 + 你可以通过指定 `--attach=false` 来防止这种情况。 + 如果你的会话断开连接,你可以使用 `kubectl attach` 重新连接。 +* `--share-processes` 允许在此 Pod 中的其他容器中查看该容器的进程。 + 参阅[在 Pod 中的容器之间共享进程命名空间](/zh/docs/tasks/configure-pod-container/share-process-namespace/), + 获取更多信息。 +{{< /note >}} + + +结束之后,不要忘了清理调试 Pod: + +```shell +kubectl delete pod myapp myapp-debug +``` + + +### 在改变 Pod 命令时创建 Pod 副本 + + +有时更改容器的命令很有用,例如添加调试标志或因为应用崩溃。 + + +为了模拟应用崩溃的场景,使用 `kubectl run` 命令创建一个立即退出的容器: + +``` +kubectl run --image=busybox:1.28 myapp -- false +``` + + +使用 `kubectl describe pod myapp` 命令,你可以看到容器崩溃了: + +``` +Containers: + myapp: + Image: busybox + ... + 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。 + + +{{< note >}} +* 要更改指定容器的命令,你必须用 `--container` 命令指定容器的名字, + 否则 `kubectl debug` 将创建一个新的容器运行你指定的命令。 +* 默认情况下,标志 `-i` 使 `kubectl debug` 附加到容器。 + 你可通过指定 `--attach=false` 来防止这种情况。 + 如果你的断开连接,可以使用 `kubectl attach` 重新连接。 +{{< /note >}} + + +结束之后,不要忘了清理调试 Pod: + +```shell +kubectl delete pod myapp myapp-debug +``` + +### 在更改容器镜像时创建 Pod 副本 + +在某些情况下,你可能想改变行为异常的 Pod, +将其中的正常生产容器镜像更改为包含调试版本或者额外工具的镜像。 + +作为示例,用 `kubectl run` 创建一个 Pod: + +``` +kubectl run myapp --image=busybox:1.28 --restart=Never -- sleep 1d +``` + +现在可以使用 `kubectl debug` 创建一个副本并改变容器镜像为 `ubuntu`: + +``` +kubectl debug myapp --copy-to=myapp-debug --set-image=*=ubuntu +``` + + +`--set-image` 使用与 `kubectl set image` 相同的 `container_name=image` 语法。 +`*=ubuntu` 表示把所有容器的镜像改为 `ubuntu`。 + +```shell +kubectl delete pod myapp myapp-debug +``` + + +## 通过节点上的 Shell 来进行调试 {#node-shell-session} + +如果这些方法都不起作用,你可以找到运行 Pod 的节点,然后在节点上部署一个运行在宿主名字空间的特权 Pod。 + +你可以通过 `kubectl debug` 在节点上创建一个交互式 Shell: + +```shell +kubectl debug node/mynode -it --image=ubuntu +``` + +``` +Creating debugging pod node-debugger-mynode-pdx84 with container debugger on node mynode. +If you don't see a command prompt, try pressing enter. +root@ek8s:/# +``` + + +在节点上创建调试会话时,注意以下要点: +* `kubectl debug` 基于节点的名字自动生成新的 Pod 的名字。 +* 新的调试容器运行在宿主 IPC、宿主网络、宿主 PID 名字空间内。 +* 节点的根文件系统会被挂载在 `/host`。 + +当你完成节点调试时,不要忘记清理调试 Pod: + +```shell +kubectl delete pod node-debugger-mynode-pdx84 +``` \ No newline at end of file