k8s开启临时容ephemeral器进行debug调试

简介: k8s开启临时容ephemeral器进行debug调试

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临时容器


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
Android开发
GB28181设备控制和TeleBoot远程启动命令探究
源设备向目标设备发送设备控制命令,控制命令的类型包括球机/云台控制、远程启动、录像控制、 报警布防/撤防、报警复位、强制关键帧、拉框放大、拉框缩小、看守位控制、设备配置等。
168 0
|
3月前
|
Shell Docker 容器
10-19|使用date命令: 你可以在容器内使用date命令来设置时间,但为了防止这个更改影响宿主机,你不能以特权模式运行容器。我没有加特权模式的时候,使用此命令告诉我没权限啊
10-19|使用date命令: 你可以在容器内使用date命令来设置时间,但为了防止这个更改影响宿主机,你不能以特权模式运行容器。我没有加特权模式的时候,使用此命令告诉我没权限啊
|
5月前
|
安全 应用服务中间件 开发工具
Ngnix全局块的user指令,403权限不足
Ngnix全局块的user指令,403权限不足
|
安全 容器
win10删除文件时权限不够(你需要来自Administrators 的权限才能对此文件进行更改,无法枚举容器的对象,访问被拒绝)
win10删除文件时权限不够(你需要来自Administrators 的权限才能对此文件进行更改,无法枚举容器的对象,访问被拒绝)
6826 0
win10删除文件时权限不够(你需要来自Administrators 的权限才能对此文件进行更改,无法枚举容器的对象,访问被拒绝)
|
7月前
|
Unix Linux C语言
【进程OI】重定向的本质&&用户级缓冲区
【进程OI】重定向的本质&&用户级缓冲区
|
7月前
|
监控 Linux Shell
Linux脚本的作用是监控IP登录失败次数
Linux脚本的作用是监控IP登录失败次数
82 1
|
Java 测试技术 Docker
java实现线上环境远程debug调试
java实现线上环境远程debug调试
418 0
|
测试技术 应用服务中间件 nginx
nginx实现的测试环境请求复制到本地,并进行debug调试
nginx实现的测试环境请求复制到本地,并进行debug调试
228 0
|
SQL 安全 Shell
[永久开源] vulntarget-b_打靶记录(上)
[永久开源] vulntarget-b_打靶记录
301 0
|
物联网 Linux 开发者
Exec 之后进程保留的属性|学习笔记
快速学习 Exec 之后进程保留的属性
下一篇
DataWorks