Akemi

临时容器ephemeralcontainers

2024/06/18

https://kubernetes.io/zh/docs/concepts/workloads/pods/ephemeral-containers/

调试运行中的 Pod | Kubernetes

临时容器与其他容器的不同之处在于,它们缺少对资源或执行的保证,并且永远不会自动重启,因此不适用于构建应用程序。临时容器使用与常规容器相同的 Container.Spec字段进行描述,但许多字段是不允许使用的。

  • 临时容器没有端口配置,因此像 ports,livenessProbe,readinessProbe 这样的字段是不允许的。
  • Pod 资源分配是不可变的,因此 resources 配置是不允许的。

临时容器是使用 API 中的一种特殊的 ephemeralcontainers 处理器进行创建的, 而不是直接添加到 pod.spec 段,因此无法使用 kubectl edit 来添加一个临时容器。

用途

当由于容器崩溃或容器镜像不包含调试工具而导致 kubectl exec 无用时, 临时容器对于交互式故障排查很有用。

尤其是,Distroless 镜像 允许用户部署最小的容器镜像,从而减少攻击面并减少故障和漏洞的暴露。 由于 distroless 镜像不包含 Shell 或任何的调试工具,因此很难单独使用 kubectl exec 命令进行故障排查。

使用临时容器时, 启用进程名字空间共享很有帮助, 可以查看其他容器中的进程。

使用临时容器

1
2
3
4
5
6
1.修改api-server的参数,开启支持
--feature-gates=EphemeralContainers=true
根据k8s官网特性门控的文档,这个特性在k8s1.26版本已经移除,并且默认为true
我的版本是1.28,所以就不需要进行修改了

否则需要在kube-apiserver.yaml、kube-scheduler.yaml、kubelet添加字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
2.创建一个有问题的pod,我直接用官网的例子了
这镜像是拉取之后传到harbor里的
kubectl run ephemeral-demo --image=192.168.10.130/library/pause:3.1 --restart=Never
kubectl get pods
NAME READY STATUS RESTARTS AGE
ephemeral-demo 1/1 Running 0 17s

此时容器内部是有报错的,无法使用exec进行调试
kubectl exec -it ephemeral-demo -- sh
error: Internal error occurred: error executing command in container:
failed to exec in container: failed to start exec "385c28c52c6c46981cc48c67757e2a6441fb14dd739757a12001247e0162edff": OCI runtime exec failed: exec failed: unable to start container process: exec: "sh": executable file not found in $PATH: unknown

3.通过debug创建临时容器
(1)
kubectl debug -it ephemeral-demo --image=192.168.10.130/library/busybox:1.28 --target=ephemeral-demo
添加一个新的 busybox 容器并将其挂接到该容器
Ephemeral Containers:
debugger-dgfwj:
Container ID: containerd://e4adae36f30c196abb5f589b5412493ce752940ce2b794269a3915112abea685
Image: 192.168.10.130/library/busybox:1.28
Image ID: 192.168.10.130/library/busybox@sha256:74f634b1bc1bd74535d5209589734efbd44a25f4e2
Normal Pulled 2m26s kubelet Container image "192.168.10.130/library/busybox:1.28" already present on machine
Normal Created 2m26s kubelet Created container debugger-dgfwj
Normal Started 2m26s kubelet Started container debugger-dgfwj

/ # ps aux
PID USER TIME COMMAND
1 root 0:00 /pause
7 root 0:00 sh
13 root 0:00 ps aux

(2)创建一个pod的副本
kubectl debug -it myapp --image=ubuntu --share-processes --copy-to=myapp-debug

(3)在这个pod存在的节点上通过shell进行调试
kubectl debug node/mynode -it --image=ubuntu

还有另一种方法通过载入json格式的资源,不过不细研究了
CATALOG
  1. 1. 使用临时容器