50298634aa4ea0e81b5a463eae52458c.gif

1.1 什么是临时容器?

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

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

  • Pod 资源分配是不可变的,因此 resources 配置是不允许的。

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

与常规容器一样,将临时容器添加到 Pod 后,将不能更改或删除临时容器。

1.2 临时容器的用途

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

1.3 开启特性支持临时容器

需要开启支持临时容器的特性:

修改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

2、使用临时容器

 参考: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:    <none>

    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:    <none>

    Mounts:         <none>

3、kubectl raw更新临时容器

[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:

4、总结

临时容器特别适合包含主容器剥离出来的一些调试工具,在需要的时候临时注入到目标pod中。有个比较尴尬的问题,就是在pod中添加临时容器之后,目前还无法删除,同时如果这时候临时容器已经退出,会导致无法再次attach,也不会被拉起(临时容器不支持probe什么的),相关的issue:https://github.com/kubernetes/kubernetes/issues/84764

5、补充

目前临时容器最大的坑是无法删除,如果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

微信公众号

0c3ab4755f847dfa4abd31dbe2c0eeda.png

作者微信:luckylucky421302

4b0e61873dd9d3d4848aab9ba915ce27.png

精彩文章推荐

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构建企业级监控告警系统

f0ff5d223c640f6e92bb40fbd8f8be39.png

                   点亮,服务器10年不宕机279b70c51e3c3aeeb22cd4496b827a40.gif

01866715c3f3abe57b713286c48953e4.gif 点击阅读 | 了解更多

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐