一、临时容器ephermeral概述
参考官方文档: https://kubernetes.io/zh/docs/concepts/workloads/pods/ephemeral-containers/
1.1 什么是临时容器
临时容器与其他容器的不同之处在于,它们缺少对资源或执行的保证,并且永远不会自动重启,因此 不适用于构建应用程序。临时容器使用与常规容器相同的 Container.Spec 字段进行描述,但许多字段 是不允许使用的。
1)临时容器没有端口配置,因此像 ports,livenessProbe,readinessProbe 这样的字段是不允 许的。
2)Pod 资源分配是不可变的,因此 resources 配置是不允许的。
临时容器是使用 API 中的一种特殊的 ephemeralcontainers 处理器进行创建的, 而不是直接添加到 pod.spec 段,因此无法使用 kubectl edit 来添加一个临时容器。
[root@master myapp]# kubectl explain pods.spec
ephemeralContainers
1.2 临时容器用途
当由于容器崩溃或容器镜像不包含调试实用程序而导致 kubectl exec 无用时,临时容器对于交互式 故障排查很有用。
1.3 开启特性支持临时容器
需要开启支持临时容器的特性:
修改 kube-apiserver.yaml、kube-scheduler.yaml、kubelet 配置。
# 新增加--feature-gates=EphemeralContainers=true 字段 vim /etc/kubernetes/manifests/kube-apiserver.yaml spec: containers: - command: - kube-apiserver - --advertise-address=192.168.10.10 - --allow-privileged=true - --feature-gates=EphemeralContainers=true - --authorization-mode=Node,RBAC #新增加--feature-gates=EphemeralContainers=true 字段 vim /etc/kubernetes/manifests/kube-scheduler.yaml - command: - kube-scheduler - --authentication-kubeconfig=/etc/kubernetes/scheduler.conf - --authorization-kubeconfig=/etc/kubernetes/scheduler.conf - --bind-address=192.168.10.10 - --kubeconfig=/etc/kubernetes/scheduler.conf - --leader-elect=true - --feature-gates=EphemeralContainers=true # 控制节点和工作节点都需要修改 [root@master myapp]# cat /etc/sysconfig/kubelet KUBELET_EXTRA_ARGS="--feature-gates=EphemeralContainers=true" [root@node1 ~]# cat /etc/sysconfig/kubelet KUBELET_EXTRA_ARGS="--feature-gates=EphemeralContainers=true" # 修改后重启k8s控制节点和工作节点的kubelet systemctl restart kubelet # 查看kube-system名称空间的pod,都是running说明正常 [root@master manifests]# kubectl get pods -n kube-system Ready时启动状态:1/1
二、使用临时容器
参考:https://kubernetes.io/zh/docs/tasks/debug-application-cluster/debug-running-pod/#ephemeral-container
# 创建一个部署tomcat的pod [root@master epherneral]# cat pod-tomcat.yaml apiVersion: v1 kind: Pod metadata: name: tomcat-test namespace: default labels: app: tomcat spec: containers: - name: tomcat-java ports: - containerPort: 8080 image: simonxiong/tomcat-8.5-jre8:v1 imagePullPolicy: IfNotPresent [root@master epherneral]# kubectl apply -f pod-tomcat.yaml pod/tomcat-test created [root@master epherneral]# kubectl get pods NAME READY STATUS RESTARTS AGE tomcat-test 1/1 Running 0 2s # 创建临时容器 [root@master epherneral]# kubectl debug -it tomcat-test --image=busybox:1.28 --target=tomcat-java / # ps -ef | grep java # 查看tomcat-teset是否创建了临时容器 [root@master ~]# kubectl describe pods tomcat-test Ephemeral Containers: debugger-vrjmr: Container ID: docker://c36056b0417eeb94575c4d47e1b3a4e6306287b8000b24aaf413c533e549309c Image: busybox:1.28 # 退出重新再进,发现之前创建的临时容器也不会被删除
三、kubectl raw更新临时容器
[root@master epherneral]# kubectl delete -f pod-tomcat.yaml pod "tomcat-test" deleted [root@master epherneral]# kubectl apply -f pod-tomcat.yaml pod/tomcat-test created [root@master epherneral]# kubectl get pods NAME READY STATUS RESTARTS AGE tomcat-test 1/1 Running 0 4s [root@master epherneral]# cat a.json { "apiVersion": "v1", "kind": "EphemeralContainers", "metadata": { "name": "tomcat-test" }, "ephemeralContainers": [{ "command": [ "sh" ], "image": "busybox", "imagePullPolicy": "IfNotPresent", "name": "debugger", "stdin": true, "tty": true, "targetContainerName": "tomcat-java", "terminationMessagePolicy": "File" }] } [root@master epherneral]# kubectl replace --raw /api/v1/namespaces/default/pods/tomcat-test/ephemeralcontainers -f a.json {"kind":"EphemeralContainers","apiVersion":"v1","metadata":{"name":"tomcat-test","namespace":"default","uid":"839485f1-b95e-4704-afcd-b11adb70a0e6","resourceVersion":"196823",
"creationTimestamp":"2022-09-01T09:54:40Z"},"ephemeralContainers":[{"name":"debugger","image":"busybox","command":["sh"],"resources":{},"terminationMessagePath":"/dev/termination-log",
"terminationMessagePolicy":"File","imagePullPolicy":"IfNotPresent","stdin":true,"tty":true,"targetContainerName":"tomcat-java"}]} 此时,可以直接 attach 到临时容器上去: [root@master epherneral]# kubectl attach -it -c debugger tomcat-test / # ps -ef | grep java 调试完成退出临时容器之后,这个容器会被销毁,无法再次 attach 总结: 临时容器特别适合包含主容器剥离出来的一些调试工具,在需要的时候临时注入到目标 pod 中。有个比较尴尬的问题,就是在 pod 中添加临时容器之后,目前还无法删除,同时如果这时候临时容器已经退出,会导致无法再次 attach,
也不会被拉起(临时容器不支持 probe 什么的),相关的issue: https://github.com/kubernetes/kubernetes/issues/84764
Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 15m default-scheduler Successfully assigned default/tomcat-test to node1 Normal Pulled 15m kubelet Container image "xianchao/tomcat-8.5-jre8:v1" already present on machine Normal Created 15m kubelet Created container tomcat-java Normal Started 15m kubelet Started container tomcat-java Normal Pulled 4m7s kubelet Container image "busybox" already present on machine Normal Created 4m7s kubelet Created container debugger Normal Started 4m7s kubelet Started container debugger
补充:
目前临时容器最大的坑是无法删除,如果 attach 了临时容器,然后退出了容器主进程(和前面示例 中展示的那样),会导致这个容器无法再 attach,也无法重新启动。此时,如果要重复上述步骤再次进 行调试,需要新创建一个临时容器,同时还需要保留老的配置,否则 k8s 会拒绝新的配置:
[root@master epherneral]# cat a.json { "apiVersion": "v1", "kind": "EphemeralContainers", "metadata": { "name": "tomcat-test" }, "ephemeralContainers": [{ "command": [ "sh" ], "image": "busybox", "imagePullPolicy": "IfNotPresent", "name": "debugger", "stdin": true, "tty": true, "targetContainerName": "tomcat-java", "terminationMessagePolicy": "File" }, {"command": [ "sh" ], "image": "busybox", "imagePullPolicy": "IfNotPresent", "name": "debugger1", "stdin": true, "tty": true, "targetContainerName": "tomcat-java", "terminationMessagePolicy": "File" } ] } 配置文件需要做这样的修改,再新增一个临时容器。重新修改后 pod 的状态(describe 结果): [root@master epherneral]# kubectl replace --raw /api/v1/namespaces/default/pods/tomcat-test/ephemeralcontainers -f a.json 看 tomcat-test 详细信息,可以看到新增加了一个 debugger1 临时容器
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了