云原生之深入解析Kubernetes中如何使用临时容器进行故障排查

一、背景

  • 容器及其周围的生态系统改变了工程师部署、维护和排查工作负载故障的方式。但是,在 Kubernetes 集群上调试应用程序有时可能会很困难,因为可能在容器中找不到所需的调试工具。许多工程师使用基于精简、发行版构建无发行版的基础镜像,其中甚至没有包管理器或shell,甚至一些团队使用 scratch 作为基础镜像,并且只添加应用程序运行所需的文件。
  • 这种常见做法的一些原因是:
    • 具有较小的攻击区域。
    • 为了获得更快的扫描性能。
    • 减小了镜像大小。
    • 为了有更快的构建和更短 CD/CI 周期。
    • 减少依赖关系。
  • 这些精简的基础镜像不包括用于对应用程序或其依赖项进行故障排查的工具,这是 Kubernetes 临时容器功能最大用途。临时容器允许创建包含可能需要的所有调试工具的容器镜像。一旦需要调试,就可以将临时容器部署到所选的正在运行的 Pod 中。
  • 不能将容器添加到已部署的容器,需要更新 spec,并重新创建资源。但是,可以将临时容器添加到现有 Pod 中,以便对线上问题进行故障排查。

二、 临时容器的配置

  • 临时容器与常规容器共享相同的 spec。但是,某些字段被禁用,并且某些行为被更改。
  • 如下列出了一些重大变化,检查临时容器规范以获取完整列表:
    • 它们不会重新启动。
    • 不允许定义资源。
    • 不允许使用端口。
    • 不允许使用启动、活动和就绪探测。

三、启动临时容器

  • 首先,检查是否启用了临时容器功能:
rust 复制代码
kubectl debug -it <POD_NAME> --image=busybox
  • 如果未启用该功能,将看到类似下面的消息:
rust 复制代码
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=后,例如:
rust 复制代码
...
--feature-gates=RemoveSelfLink=false,EphemeralContainers=true
...

四、使用临时容器

  • 现在,集群支持临时容器功能,要创建临时容器,使用 kubectl 命令行工具的 debug 子命令。首先,创建一个 Deployment:
rust 复制代码
kubectl create deployment nginx-deployment --image=nginx
  • 获取需要 debug 的 Pod 的名称:
rust 复制代码
$ 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 参数允许我们附加到新创建的容器:
rust 复制代码
$ kubectl debug -it pods/nginx-deployment-66b6c48dd5-frsv9 --image=busybox
  • 现在就可以 debug 了:
rust 复制代码
/ # 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 <POD_NAME> 命令时,可以看到一个新字段 "Ephemeral Containers",此部分包含临时容器及其属性:
rust 复制代码
$ kubectl describe pods <POD_NAME>

...
...
Ephemeral Containers:
  debugger-thwrn:
    Container ID:   containerd://eec23aa9ee63d96b82970bb947b29cbacc30685bbc3418ba840dee109f871bf0
    Image:          busybox
    Image ID:       docker.io/library/busybox@sha256:e7157b6d7ebbe2cce5eaa8cfe8aa4fa82d173999b9f90a9ec42e57323546c353
    Port:           <none>
    Host Port:      <none>

五、与临时容器共享进程命名空间

  • 进程命名空间共享一直是一个很好的故障排查选项,此功能可用于临时容器。进程命名空间共享不能应用于现有容器,因此必须创建目标容器的副本。--share-processesflag 在与 --copy-to 一起使用时,可实现进程命名空间共享。这些标志将现有的 Pod spec定义复制到新定义中,并在 spec 中启用了进程命名空间共享:
rust 复制代码
$ kubectl debug -it <POD_NAME> --image=busybox --share-processes --copy-to=debug-pod
  • 运行 ps 命令以查看正在运行的进程,正如所期望的那样,可以从 busybox 容器中看到 /pause,从 nginx-deployment 容器中看到 nginx 进程:
rust 复制代码
# 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//root 链接访问容器。从上面的输出中,可以知道 nginx 的 PID 为 6。
rust 复制代码
# 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 探针失败时自动修复其他容器。
相关推荐
Python私教43 分钟前
ubuntu搭建k8s环境详细教程
linux·ubuntu·kubernetes
运维&陈同学2 小时前
【zookeeper01】消息队列与微服务之zookeeper工作原理
运维·分布式·微服务·zookeeper·云原生·架构·消息队列
O&REO2 小时前
单机部署kubernetes环境下Overleaf-基于MicroK8s的Overleaf应用部署指南
云原生·容器·kubernetes
politeboy2 小时前
k8s启动springboot容器的时候,显示找不到application.yml文件
java·spring boot·kubernetes
运维小文3 小时前
K8S资源限制之LimitRange
云原生·容器·kubernetes·k8s资源限制
登云时刻3 小时前
Kubernetes集群外连接redis集群和使用redis-shake工具迁移数据(二)
redis·容器·kubernetes
wuxingge12 小时前
k8s1.30.0高可用集群部署
云原生·容器·kubernetes
志凌海纳SmartX13 小时前
趋势洞察|AI 能否带动裸金属 K8s 强势崛起?
云原生·容器·kubernetes
锅总13 小时前
nacos与k8s service健康检查详解
云原生·容器·kubernetes
BUG弄潮儿13 小时前
k8s 集群安装
云原生·容器·kubernetes