Kubernetes 中如何使用临时容器进行故障排查
共 3409字,需浏览 7分钟
·
2022-03-06 09:02
容器及其周围的生态系统改变了工程师部署、维护和排查工作负载故障的方式。但是,在 Kubernetes 集群上调试应用程序有时可能会很困难,因为你可能在容器中找不到所需的调试工具。许多工程师使用基于精简、发行版构建无发行版的基础镜像,其中甚至没有包管理器或shell。甚至一些团队使用 scratch 作为基础镜像,并且只添加应用程序运行所需的文件。这种常见做法的一些原因是:
具有较小的攻击区域。 为了获得更快的扫描性能。 减小了镜像大小。 为了有更快的构建和更短CD/CI周期。 减少依赖关系。
临时容器的配置
临时容器与常规容器共享相同的spec。但是,某些字段被禁用,并且某些行为被更改。下面列出了一些重大变化;检查临时容器规范以获取完整列表。
它们不会重新启动。 不允许定义资源。 不允许使用端口。 不允许使用启动、活动和就绪探测。
启动临时容器
首先,检查是否启用了临时容器功能。
kubectl debug -it --image=busybox
如果未启用该功能,您将看到类似下面的消息。
Defaulting debug container name to debugger-wg54p.
error: ephemeral containers are disabled for this cluster (error from server: "the server could not find the requested resource").
将 EphemeralContainers=true 附加到 kubelet、kube-apiserver、kube-controller-manager、kube-proxy、kube-scheduler 参数中的--feature-gates=后, 例如:
...
--feature-gates=RemoveSelfLink=false,EphemeralContainers=true
...
使用临时容器
现在,集群支持临时容器功能,让我们来试试吧。要创建临时容器,使用 kubectl 命令行工具的 debug 子命令。首先,创建一个Deployment
kubectl create deployment nginx-deployment --image=nginx
获取需要debug的Pod的名称
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-66b6c48dd5-frsv9 1/1 Running 6 62d
以下命令将在 pod nginx-deployment-66b6c48dd5-frsv9 中创建一个新的临时容器。临时容器的镜像是busybox。-i 和 -t 参数允许我们附加到新创建的容器。
$ kubectl debug -it pods/nginx-deployment-66b6c48dd5-frsv9 --image=busybox
现在我们可以debug了
/ # ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=112 time=9.797 ms
64 bytes from 8.8.8.8: seq=1 ttl=112 time=9.809 ms
^C
/ # nc --help
BusyBox v1.34.1 (2021-11-11 01:55:05 UTC) multi-call binary.
Usage: nc [OPTIONS] HOST PORT - connect
nc [OPTIONS] -l -p PORT [HOST] [PORT] - listen
...
当使用 kubectl describe pod
$ kubectl describe pods
...
...
Ephemeral Containers:
debugger-thwrn:
Container ID: containerd://eec23aa9ee63d96b82970bb947b29cbacc30685bbc3418ba840dee109f871bf0
Image: busybox
Image ID: docker.io/library/busybox@sha256:e7157b6d7ebbe2cce5eaa8cfe8aa4fa82d173999b9f90a9ec42e57323546c353
Port:
Host Port:
与临时容器共享进程命名空间
进程命名空间共享一直是一个很好的故障排查选项,此功能可用于临时容器。进程命名空间共享不能应用于现有容器,因此必须创建目标容器的副本。--share-processesflag 在与 --copy-to 一起使用时,可实现进程命名空间共享。这些标志将现有的 Pod spec定义复制到新定义中,并在spec中启用了进程命名空间共享。
$ kubectl debug -it --image=busybox --share-processes --copy-to=debug-pod
运行 ps 命令以查看正在运行的进程。正如您所期望的那样,您可以从 busybox 容器中看到 /pause,从 nginx-deployment 容器中看到 nginx 进程。
# ps aux
PID USER TIME COMMAND
1 root 0:00 /pause
6 root 0:00 nginx: master process nginx -g daemon off;
11 101 0:00 nginx: worker process
12 root 0:00 sh
17 root 0:00 ps aux
使用进程命名空间,共享容器文件系统也是可访问的,这对于调试非常有用。您可以使用 /proc/
# ls /proc/6/root/etc/nginx
conf.d koi-utf mime.types nginx.conf uwsgi_params fastcgi_params koi-win modules scgi_params win-utf
在这里,我们可以看到目标容器上的Nginx目录结构和配置文件。
结论
临时容器功能无疑给调试排查问题带来了很大便利,而进程命名空间共享允许高级调试功能。如果你也使用在 Kubernetes 集群中运行的应用程序,那么值得花时间尝试这些功能。不难想象,一些团队甚至使用这些工具自动执行工作流,例如在readiness probes探针失败时自动修复其他容器。
原文:https://tinyurl.com/3658tdzs
文章转载:进击云原生
(版权归原作者所有,侵删)
点击下方“阅读原文”查看更多