杨梅冲
每天在想什么呢?

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

 

posted on 2022-09-01 18:15  杨梅冲  阅读(219)  评论(0编辑  收藏  举报