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


相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
Kubernetes 安全 网络协议
【K8S系列】深入解析k8s网络插件—Calico
【K8S系列】深入解析k8s网络插件—Calico
5574 0
|
存储 Kubernetes NoSQL
【K8S系列】深入解析K8S存储
【K8S系列】深入解析K8S存储
1156 0
|
存储 边缘计算 人工智能
边缘计算(Link IoT Edge)介绍|学习笔记
快速学习边缘计算(Link IoT Edge)介绍
1328 0
边缘计算(Link IoT Edge)介绍|学习笔记
|
关系型数据库 MySQL
925. 【mysql】convert 函数
925. 【mysql】convert 函数
590 3
|
人工智能 安全 数据安全/隐私保护
大模型安全撬壳计划(二) 参加大模型安全撬壳计划的一点心得
本文分享了作者在参与LLM及多模模型实践中的经验与心得,涵盖代码编写、多轮对话处理、本地模拟交互、越狱方法等内容,并提供了多个实用代码示例与策略建议。同时总结了对模型评分与文档支持的改进建议,适合对LLM应用与对抗攻击感兴趣的开发者与研究者参考。
1223 0
|
存储 Serverless 数据库
科普文:云计算服务类型IaaS, PaaS, SaaS, BaaS, Faas说明
本文介绍了云计算服务的几种主要类型,包括IaaS(基础设施即服务)、PaaS(平台即服务)、SaaS(软件即服务)、BaaS(后端即服务)和FaaS(函数即服务)。每种服务模式提供了不同的服务层次和功能,从基础设施的提供到应用的开发和运行,再到软件的交付使用,满足了企业和个人用户在不同场景下的需求。文章详细阐述了每种服务模式的特点、优势和缺点,并列举了相应的示例。云计算服务的发展始于21世纪初,随着互联网技术的普及,这些服务模式不断演进,为企业和个人带来了高效、灵活的解决方案。然而,使用这些服务时也需要注意服务的稳定性、数据安全性和成本等问题。
12465 5
|
运维 Kubernetes Shell
【赵渝强老师】K8s中Pod的临时容器
Pod 是 Kubernetes 中的基本调度单位,由一个或多个容器组成,包括业务容器、基础容器、初始化容器和临时容器。临时容器用于故障排查和性能诊断,不适用于构建应用程序。当 Pod 中的容器异常退出或容器镜像不包含调试工具时,临时容器非常有用。文中通过示例展示了如何使用 `kubectl debug` 命令创建临时容器进行调试。
267 1
|
设计模式 IDE Java
谈谈过度设计:因噎废食的陷阱
本文探讨了设计模式在软件开发中的应用和争议,指出设计模式虽有助于应对软件复杂性,但在互联网快速迭代的背景下,可能会导致过度设计,增加理解和修改成本。文章分析了设计模式的缺陷,如开闭原则可能导致不易修改,最小知识原则可能导致理解困难。同时,文章强调了设计模式的重要性,指出它们可以提高代码的可理解性和模块的可维护性,并提出了通过函数式设计模式进行优化的示例。作者认为,设计模式需要随着业务演进而不断演进,同时提倡使用可调试的模块和模式演进来促进系统的成长性。文章最后提醒读者,要根据实际情况选择是否使用设计模式,避免因噎废食。
|
存储 搜索推荐 JavaScript
【毕业设计之java系列】基于springboot学生社团信息管理系统
【毕业设计之java系列】基于springboot学生社团信息管理系统
1019 0
|
SQL 关系型数据库 数据管理
在 Postgres 中使用 Delete Join
【8月更文挑战第11天】
705 0
在 Postgres 中使用 Delete Join