临时容器与其他容器的不同之处在于,它缺少对资源或执行的保证,并且永远不会自动重启,因此不适用于构建应用程序。临时容器使用与常规容器相同的 Container.Spec字段进行描述,但许多字段是不允许使用的。
临时容器没有端口配置,因此像 ports,livenessProbe,readinessProbe 这样的字段是不允许的。
Pod 资源分配是不可变的,因此 resources 配置是不允许的。
临时容器是使用 API 中的一种特殊的 ephemeralcontainers
处理器进行创建的, 而不是直接添加到 pod.spec
段,因此无法使用 kubectledit
来添加一个临时容器。
与常规容器一样,将临时容器添加到 Pod 后,将不能更改或删除临时容器。
当由于容器崩溃或容器镜像不包含调试实用程序而导致 kubectlexec
无用时,临时容器对于交互式故障排查很有用。
需要开启支持临时容器的特性:
修改kube-apiserver.yaml、kube-scheduler.yaml、kubelet配置。
[root@xianchaomaster1]# cat/etc/kubernetes/manifests/kube-apiserver.yaml
apiVersion: v1
kind: Pod
metadata:
annotations:
kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint:192.168.40.180:6443
creationTimestamp: null
labels:
component: kube-apiserver
tier: control-plane
name: kube-apiserver
namespace: kube-system
spec:
containers:
- command:
- kube-apiserver
- --advertise-address=192.168.40.180
………
- --feature-gates=RemoveSelfLink=false
- --feature-gates=EphemeralContainers=true
………
#新增加--feature-gates=EphemeralContainers=true字段
[root@xianchaomaster1]# cat/etc/kubernetes/manifests/kube-scheduler.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
component:kube-scheduler
tier: control-plane
name: kube-scheduler
namespace: kube-system
spec:
containers:
- command:
- kube-scheduler
---authentication-kubeconfig=/etc/kubernetes/scheduler.conf
---authorization-kubeconfig=/etc/kubernetes/scheduler.conf
---bind-address=192.168.40.180
- --kubeconfig=/etc/kubernetes/scheduler.conf
- --leader-elect=true
- --feature-gates=EphemeralContainers=true
#新增加--feature-gates=EphemeralContainers=true字段
[root@xianchaomaster1]# cat /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS="--feature-gates=EphemeralContainers=true"
[root@xianchaonode1 ~]# cat /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS="--feature-gates=EphemeralContainers=true"
#修改之后重启k8s控制节点和工作节点的kubelet
[root@xianchaomaster1]# systemctl restart kubelet
[root@xianchaonode1 ~]# systemctl restart kubelet
#查看kube-system名称空间pod,都是running说明修改正常
[root@xianchaomaster1 test]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-6949477b58-thdxp 1/1 Running 0 22d
calico-node-t9bxc 1/1 Running 0 46d
calico-node-xr4jj 1/1 Running 0 46d
coredns-7f89b7bc75-lb9vn 1/1 Running 0 22d
coredns-7f89b7bc75-w4m6r 1/1 Running 0 22d
etcd-xianchaomaster1 1/1 Running 0 46d
fluentd-elasticsearch-9jbn2 1/1 Running 0 22d
fluentd-elasticsearch-n7cc8 1/1 Running 0 22d
kube-apiserver-xianchaomaster1 1/1 Running 0 64m
kube-controller-manager-xianchaomaster1 1/1 Running 0 46d
kube-proxy-8nfx7 1/1 Running 0 46d
kube-proxy-zwjjx 1/1 Running 0 46d
kube-scheduler-xianchaomaster1 1/1 Running 0 29m
参考:https://kubernetes.io/zh/docs/tasks/debug-application-cluster/debug-running-pod/#ephemeral-container
#创建一个部署tomcat的pod
[root@xianchaonode1 ~]# docker load -i xianchao_tomcat.tar.gz
[root@xianchaomaster1]# 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:xianchao/tomcat-8.5-jre8:v1
imagePullPolicy:IfNotPresent
[root@xianchaomaster1]# kubectl apply -f pod-tomcat.yaml
[root@xianchaomaster1]# kubectl get pods
NAME READY STATUS RESTARTS AGE
tomcat-test 1/1 Running 0 21m
#创建临时容器
[root@xianchaomaster1]# kubectl debug -it tomcat-test--image=busybox:1.28 --target=tomcat-java
Defaulting debug container name to debugger-6m2s8.
If you don't see a command prompt, try pressing enter.
/ #ps -ef | grep tomcat
1 root 0:09/usr/lib/jvm/java-1.8-openjdk/jre/bin/java-Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager-Djdk.tls.ephemeralDHKeySize=2048-Djava.protocol.handler.pkgs=org.apache.catalina.webresources-Dorg.apache.catalina.security.SecurityListener.UMASK=0027-Dignore.endorsed.dirs= -classpath /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar-Dcatalina.base=/usr/local/tomcat -Dcatalina.home=/usr/local/tomcat-Djava.io.tmpdir=/usr/local/tomcat/temp org.apache.catalina.startup.Bootstrapstart
#查看tomcat-test这个pod是否已经有临时容器
[root@xianchaomaster1 test]# kubectl describe pods tomcat-test
Name: tomcat-test
Namespace: default
Containers:
tomcat-java:
Ready: True
Restart Count: 0
Environment:
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-qbgqq(ro)
Ephemeral Containers:
debugger-6m2s8:
State: Terminated
Reason: Completed
Exit Code: 0
Started: Sun, 18 Jul 2021 11:32:34 +0800
Finished: Sun, 18 Jul 2021 11:34:50 +0800
Ready: False
Restart Count: 0
Environment:
Mounts:
[root@xianchaomaster1]# kubectl delete -f pod-tomcat.yaml
[root@xianchaomaster1]# kubectl apply -f pod-tomcat.yaml
[root@xianchaomaster1]# kubectl get pods
NAME READY STATUS RESTARTS AGE
tomcat-test 1/1 Running 0 21m
[root@xianchaomaster1]# 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@xianchaomaster1]# kubectl replace --raw/api/v1/namespaces/default/pods/tomcat-test/ephemeralcontainers -f a.json
#显示如下:
{"kind":"EphemeralContainers","apiVersion":"v1","metadata":{"name":"tomcat-test","namespace":"default","selfLink":"/api/v1/namespaces/default/pods/tomcat-test/ephemeralcontainers","uid":"e058969c-f610-4d58-83e5-28f872f16d54","resourceVersion":"548549","creationTimestamp":"2021-07-18T04:43:43Z"},"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@xianchaomaster1]# kubectl attach -it -c debuggertomcat-test
If you don't see a command prompt, try pressing enter.
/ # ps -ef | grep tomcat
1 root 0:05/usr/lib/jvm/java-1.8-openjdk/jre/bin/java-Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager-Djdk.tls.ephemeralDHKeySize=2048-Djava.protocol.handler.pkgs=org.apache.catalina.webresources-Dorg.apache.catalina.security.SecurityListener.UMASK=0027-Dignore.endorsed.dirs= -classpath /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar-Dcatalina.base=/usr/local/tomcat -Dcatalina.home=/usr/local/tomcat-Djava.io.tmpdir=/usr/local/tomcat/temp org.apache.catalina.startup.Bootstrapstart
/ #exit
调试完成退出临时容器之后,这个容器会被销毁,无法再次attach:
临时容器特别适合包含主容器剥离出来的一些调试工具,在需要的时候临时注入到目标pod中。有个比较尴尬的问题,就是在pod中添加临时容器之后,目前还无法删除,同时如果这时候临时容器已经退出,会导致无法再次attach,也不会被拉起(临时容器不支持probe什么的),相关的issue:https://github.com/kubernetes/kubernetes/issues/84764
目前临时容器最大的坑是无法删除,如果attach了临时容器,然后退出了容器主进程(和前面示例中展示的那样),会导致这个容器无法再attach,也无法重新启动。此时,如果要重复上述步骤再次进行调试,需要新创建一个临时容器,同时还需要保留老的配置,否则k8s会拒绝新的配置:
[root@xianchaomaster1]# 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@xianchaomaster1]# kubectl replace --raw/api/v1/namespaces/default/pods/tomcat-test/ephemeralcontainers -f a.json
看tomcat-test详细信息,可以看到新增加了一个debugger1临时容器
END
作者微信:luckylucky421302
精彩文章推荐
K8s 常见问题
k8s超详细解读
K8s 超详细总结!
K8S 常见面试题总结
k8s控制器Deployment详细介绍:资源清单编写技巧
k8s安装隐患如何优化?从以下维度分享
使用k3s部署轻量Kubernetes集群快速教程
基于Jenkins和k8s构建企业级DevOps容器云平台
k8s原生的CI/CD工具tekton
K8S二次开发-自定义CRD资源
基于Jenkins+git+harbor+Helm+k8s+Istio构建DevOps流水线
基于k8s+Prometheus+Alertmanager+Grafana构建企业级监控告警系统