Ephemeral Container(临时调试容器)允许你在 不修改 Deployment 镜像 的情况下,把一个调试容器“挂”到现有 Pod 上,用来排查线上问题。

它特别适合:

  • 生产镜像极简(distroless/scratch),没有 curl/dig/tcpdump
  • 你需要在 Pod 内部 复现网络/DNS/依赖问题
  • 你希望生产镜像保持干净、安全、可审计

前置条件

  • Ephemeral Containers 从 Kubernetes 1.25 起进入 Stable;更早版本不要照抄本文命令
  • 需要 RBAC 权限:pods/ephemeralcontainers(注意是子资源)

最常用的一条命令

给指定 Pod 加一个临时调试容器:

kubectl debug -n <ns> -it pod/<pod> --image=busybox:1.36 --target=<container-name>

说明:

  • --image 选一个你信任的调试镜像
  • --target 请求加入目标容器的进程命名空间,方便查看进程;容器运行时必须支持该能力,否则可能仍看不到目标进程
  • 如果你只是想做网络/DNS 检查,不一定需要 --target

你能用它做什么(实战场景)

1)DNS 与服务解析

nslookup kubernetes.default.svc.cluster.local
nslookup <svc>.<ns>.svc.cluster.local
cat /etc/resolv.conf

很多“服务突然不可用”的根因其实是:

  • DNS 被 NetworkPolicy egress 拦了
  • CoreDNS 异常
  • 节点网络/CNI 问题导致间歇性解析失败

2)验证 Service 连通性(从 Pod 内)

wget -S -O- http://<service>.<ns>.svc.cluster.local:8080/readyz
nc -vz <service>.<ns>.svc.cluster.local 8080

你想验证的是:在同一 Pod 网络命名空间里,请求到底能不能走通。

3)readiness 失败但 distroless 里没有 curl

临时容器仍受 Pod NetworkPolicy 约束,所以它看到的是应用真实网络边界:

kubectl debug -n <ns> -it pod/<pod> --image=curlimages/curl:8.5.0
curl -sS -i http://127.0.0.1:8080/readyz

如果外部探活失败而 Pod 内部成功,优先看 Service selector、endpoints 和节点网络,而不是先改应用。

4)怀疑 NetworkPolicy 拦住 egress

在 Pod 网络命名空间里验证 DNS 和目标端口:

nslookup <dependency>.<ns>.svc.cluster.local
nc -vz <dependency>.<ns>.svc.cluster.local 5432

同时对比不同 namespace 的结果。如果只有某些 namespace 不通,通常是 label 或 policy 选择器问题。

5)检查环境变量与挂载(尽量只读)

排障时常见的“配置错了”:

  • env 变量缺失/写错
  • ConfigMap/Secret 没挂载成功
  • 文件路径不一致

建议排障动作尽量只读:

  • env
  • ls -la /path
  • cat /etc/hosts

选什么调试镜像更合理

不同任务需要不同工具:

  • BusyBox:够小,适合基础网络与文件检查
  • Alpine:可拓展,但临时安装包可能需要外网访问(不一定允许)
  • 工具箱镜像:带 curl/dig/tcpdump/mtr 等,效率高但体积大、风险也更大

生产建议维护一个“认证过的调试镜像”:

  • 固定 digest(可复现)
  • 定期安全扫描
  • 只包含必要工具

这样排障不会临时“随便拉一个镜像”,降低供应链风险。

理解 --target:什么时候必须用

同一个 Pod 内的容器本来就共享网络命名空间,因此多数 DNS、Service 和回环地址排障不需要 --target。

你更可能需要 --target 的情况:

  • 想看目标容器进程(或在允许情况下 strace)
  • 想对“卡死”的进程做诊断

如果容器运行时不支持 target process namespace,或平台策略不允许相应权限,调试容器可能启动但看不到目标进程;网络与 DNS 检查仍可继续。

重要限制(别把它当成长期方案)

Ephemeral containers 的定位就是“临时排障”,因此:

  • 不是 Pod spec 的一部分,不应该成为“长期修复”
  • 不会被重启(退出就退出了)
  • 不应该对外提供服务端口

正确修复应该回到:

  • 配置/镜像/代码/部署清单
  • GitOps/CI 的流程

安全与流程(最容易被忽视,但最重要)

临时调试容器本质上是“把人带进生产 Pod”:

  • 需要更严格的 RBAC(限制谁能用)
  • 需要审计(谁、什么时候、为什么)
  • 需要流程(事故单/工单编号,排查结论落档)

一个最小 RBAC 思路是把“看 Pod”和“改 ephemeralcontainers 子资源”分开:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: ephemeral-debug
  namespace: app
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list"]
  - apiGroups: [""]
    resources: ["pods/ephemeralcontainers"]
    verbs: ["get", "update"]

如果排障动作可能读取 Secret 环境变量、挂载内容或业务数据,就先和安全团队对齐三件事:

  • 哪些 namespace 允许临时调试;
  • 允许使用哪些认证过的调试镜像;
  • 是否允许节点级调试,以及需要什么审批。

推荐做法:

  1. RBAC 最小化:只给少数 SRE/值班组
  2. 统一调试镜像:防止供应链风险
  3. 只读排障优先:尽量不改线上文件与状态

高风险场景:先复制 Pod,再调试

有时你不想直接触碰生产 Pod,比如需要安装包、重启应用进程、注入更重的诊断工具。如果当前 kubectl 版本和集群策略支持,可以复制一个隔离副本再排查。

kubectl debug -n <ns> -it pod/<pod> \
  --image=ubuntu:24.04 \
  --share-processes \
  --copy-to=<pod>-debug

kubectl delete pod -n <ns> <pod>-debug

复制出的 Pod 可能仍连接真实依赖。先确认 Service selector 不会选中它,并避免执行有副作用的消费者或定时任务。

这类场景的原则很简单:风险越高,越先“复制后调试”,而不是在线上 Pod 里试错。

Bonus:当问题在“节点层”而非 Pod 层

有时候根因在节点或平台:

  • CNI 路由/iptables/eBPF 问题
  • 磁盘压力导致驱逐
  • kubelet/containerd 异常

kubectl debug node/<node> 创建的调试 Pod 默认不一定具备执行 chroot /host 所需的权限。确实需要主机级权限时,显式使用 sysadmin profile,并把它视为特权操作:

kubectl debug node/<node> -it \
  --image=ubuntu:24.04 \
  --profile=sysadmin \
  -- chroot /host

进入后再检查 ip a、ip r、ss -lntp、节点 /etc/resolv.conf 和 CNI 配置。不要为了方便把节点调试权限下放给普通应用账号。

排查结束也要收尾

临时容器可能会保留在 Pod status 里,直到 Pod 被删除。退出终端只是最低要求:

  • 记录执行过的命令、关键输出和结论。
  • 关联工单或事故单,方便复盘。
  • 真正修复走配置、镜像和发布流程,不要把“临时手改”当成方案。

上线前自检

  • 生产镜像保持极简,不打包调试工具
  • 用 ephemeral containers 快速复现 Pod 内真实网络/DNS
  • RBAC 控制 pods/ephemeralcontainers,并审计使用记录
  • 排障只读优先,修复走发布流程而不是“线上手改”

临时容器的三个使用边界

Q: 生产环境能用吗? A: 可以用于排障,但不会自动重启。建议用 RBAC 限制谁可以注入临时容器。

Q: 为什么不能挂载新卷或暴露端口? A: 临时容器设计用于调试,限制变更以避免影响业务。

Q: 怎么查看临时容器日志? A: 用 kubectl logs <pod> -c <ephemeral-container-name>,必要时 kubectl describe pod 查看状态。

参考链接