31.B站薪享宏福笔记——第十二章(1)临时容器

12 B站薪享宏福笔记——第十二章

                                    —— Kubernetes 中必备的工具组件

12.1 临时容器

             —— 调试小助手

12.1.1 概念

特性状态:Kubernetes v1.25 [stable稳定状态]

临时容器:一种特殊的容器,该容器在现有 Pod 中临时运行,以便完成用户发起的操作,例如故障排查,可以使用临时容器来检查服务,但不能用它来构建应用程序(临时容器临时出现,用于调试、检测,使用容器中的命令而已)

12.1.2 特性

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

  临时容器没有端口配置,因此像 端口ports、存活探测livenessProbe、就绪探测readinessProbe 这样的字段是不允许的

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

临时容器是使用 API 中的一种特殊的 ephemeralcontainers处理器 进行创建的(并非 pod 的标准处理器创建),而不是直接添加到 pod.spec 段,因此无法使用 kubectl edit 来添加一个临时容器,与常规容器一样,将临时容器添加到 Pod 后,将不能更改或删除临时容器

12.1.3 临时容器调试

(1)增加临时容器

应用场景:检测、排错时使用

image

1.demo pod 中运行 以 myapp:v1.0 镜像的 主容器main-c

2.在 demo pod 中增加一个以 busybox:latest 镜像运行的 临时容器debug-c 用于调试或确认同pod内 主容器main-c 运行是否正常

[root@k8s-master01 12.1]# kubectl run demo --image=myapp:v1.0 --restart=Never
pod/demo created
[root@k8s-master01 12.1]# kubectl get pod -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP              NODE         NOMINATED NODE   READINESS GATES
demo   1/1     Running   0          10s   10.244.58.199   k8s-node02   <none>           <none>
# 假设 demo pod 不能对外提供正常的访问
# 正常是使用 kubectl describe pod demo、kubectl logs demo -c demo 进行排查,但有时可能不能查看出问题或因镜像封装,日志不输出到控制台,没办法从 logs 中看到日志
# 指定 -i 或 --interactive 参数,kubectl 将自动进入到临时容器的控制台(即交互)、-t 分配一个 tty 终端入口、demo 当前新增容器所在 Pod 名、基于镜像版本启动的新容器、--target 参数指定原容器的进程命名空间(必需的)
[root@k8s-master01 12.1]# kubectl debug -it demo --image=busybox:latest --target=demo
Targeting container "demo". If you don't see processes from this container it may be because the container runtime doesn't support this feature.
Defaulting debug container name to debugger-s88v4.
If you don't see a command prompt, try pressing enter.
/ # ps -ef  # 可以查看 demo Pod 中容器的进程运行情况
PID   USER     TIME  COMMAND
    1 root      0:00 nginx: master process nginx -g daemon off;
    7 100       0:00 nginx: worker process
   22 root      0:00 sh
   29 root      0:00 ps -ef
/ # wget localhost/index.html && cat index.html && rm -rf index.html  # 本地可以访问 demo Pod 内容器
Connecting to localhost (127.0.0.1:80)
saving to 'index.html'
index.html           100% |*********************************************************************************************************************************************|    65  0:00:00 ETA
'index.html' saved
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
/ # exit
# 临时容器退出不会影响主容器状态且 READY 一直是 1/1
[root@k8s
-master01 12.1]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES demo 1/1 Running 0 21m 10.244.58.199 k8s-node02 <none> <none>
# 消除实验影响
[root@k8s-master01 12.1]# kubectl delete pod demo 
pod "demo" deleted

(2)通过 Pod 副本调试(克隆 Pod)

应用场景:Pod 有问题,但因原 Pod 中有数据或能提供部分功能,可以克隆一个 Pod 调试

image

1.myapp-pod 中运行以 myapp:v1.0 镜像的 主容器main-c

2.基于 myapp-pod 克隆一个  myapp-debug Pod,再在 myapp-debug Pod 中增加一个以 busybox:latest 镜像运行的 临时容器debug-c 用于调试或确认同pod内 主容器main-c 运行是否正常

[root@k8s-master01 12.1]# kubectl run myapp --image=myapp:v1.0 --restart=Never -- sleep 1d 
pod/myapp created
[root@k8s-master01 12.1]# kubectl get pod
NAME    READY   STATUS    RESTARTS   AGE
myapp   1/1     Running   0          6m18s
# 如果没有使用 --container 指定新的容器名,kubectl debug 会自动生成
# 默认情况下,-i 标志是 kubectl debug 附加到新容器上(进入容器),可以通过指定 --attach=false 来防止这种情况(不直接进入,再通过 exec 进入)
# --share-processes 允许在此 pod 中的其他容器中查看该 Pod 内容器的进程,--copy-to 新副本 Pod 的名字
[root@k8s-master01 12.1]# kubectl debug myapp -it --image=busybox:latest --share-processes --copy-to=myapp-debug
Defaulting debug container name to debugger-86cv4.
If you don't see a command prompt, try pressing enter.
/ # ps -ef  # 可以查看 myapp-debug Pod 中容器的进程运行情况 sleep 1d
PID   USER     TIME  COMMAND
    1 65535     0:00 /pause
    7 root      0:00 sleep 1d
   13 root      0:00 sh
   19 root      0:00 ps -ef
/ # cat /etc/hostname 
myapp-debug
/ # exit
# 克隆 pod 后, 再增加临时容器,然后进入 myapp-debug Pod 时 READY 是 2/2, 在退出临时容器,会存在克隆的 Pod ,并且 READY 变成 1/2,克隆 Pod 会长期存在
[root@k8s-master01 12.1]# kubectl get pod -o wide
NAME          READY   STATUS     RESTARTS   AGE   IP              NODE         NOMINATED NODE   READINESS GATES
myapp         1/1     Running    0          21m   10.244.58.253   k8s-node02   <none>           <none>
myapp-debug   1/2     NotReady   0          14m   10.244.85.199   k8s-node01   <none>           <none>
# 消除实验影响
[root@k8s-master01 12.1]# kubectl delete pod --all
pod "myapp" deleted
pod "myapp-debug" deleted

(3)改变 Pod 命令时创建 Pod 副本

应用场景:Pod 启动有问题,可以克隆 Pod ,尝试修改 Pod 的启动命令

image

1.myapp-pod 中运行以 myapp:v1.0 镜像的 主容器main-c,有启动命令,但是 Pod 无法启动

2.基于 myapp-pod 克隆一个  myapp-debug Pod,修改启动命令 /bin/sh,再查看 主容器main-c 能否运行,运行是否正常

# Pod 因为启动命令错误,无法启动
[root@k8s-master01 12.1]# kubectl run --image=myapp:v1.0 myapp -- false
pod/myapp created
[root@k8s-master01 12.1]# kubectl get pod -o wide
NAME    READY   STATUS             RESTARTS     AGE   IP              NODE         NOMINATED NODE   READINESS GATES
myapp   0/1     CrashLoopBackOff   1 (4s ago)   6s    10.244.58.194   k8s-node02   <none>           <none>
# 手动修改 Pod 的启动命令
[root@k8s-master01 12.1]# kubectl debug myapp -it --copy-to=myapp-debug --container=myapp -- /bin/sh
If you don't see a command prompt, try pressing enter.
/ # ps -ef  # 启动命令时的进程
PID   USER     TIME   COMMAND
    1 root       0:00 /bin/sh
    7 root       0:00 ps -ef
/ # exit
Session ended, resume using 'kubectl attach myapp-debug -c myapp -i -t' command when the pod is running
# 修改 Pod 启动命令后,Pod 能正常运行,从而验证是 Pod 启动命令错误的问题
[root@k8s
-master01 12.1]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp 0/1 CrashLoopBackOff 3 (41s ago) 81s 10.244.58.194 k8s-node02 <none> <none> myapp-debug 1/1 Running 1 (3s ago) 32s 10.244.85.224 k8s-node01 <none> <none>
# 消除实验影响
[root@k8s-master01 12.1]# kubectl delete pod --all
pod "myapp" deleted
pod "myapp-debug" deleted

(4)更改容器镜像时拷贝 Pod

应用场景:版本升级后,基于 新版本v2.0 不能启动,查看基于 原版本v1.0 能否启动(环境变量等未改变,从而排查是否是新封装的镜像问题)  

image

1.版本升级,myapp-pod 中运行以 myapp:v2.0 镜像的 主容器main-c,但是新版本 Pod 无法启动

2.基于 myapp-pod 克隆一个  myapp-debug Pod,修改启动镜像为 myapp:v1.0 ,再查看 主容器main-c 能否运行,运行是否正常

# 模拟新版本发布
[root@k8s-master01 12.1]# kubectl run myapp --image=myapp:v2.0 --restart=Never -- sleep 1d
pod/myapp created
# 假设 myapp 启动失败
[root@k8s-master01 12.1]# kubectl get pod -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP              NODE         NOMINATED NODE   READINESS GATES
myapp   1/1     Running   0          5s    10.244.58.251   k8s-node02   <none>           <none>
# 基于原版本 myapp:v1.0 镜像再次启动,看看能否启动成功,--set-image=*=myapp:v1.0 意为将所有镜像替换为 myapp:v1.0
[root@k8s-master01 12.1]# kubectl debug myapp --copy-to=myapp-debug --set-image=*=myapp:v1.0
# 启动命令相同,但基于原版本 myapp:v1.0 镜像启动成功,说明 新版本镜像myapp:v2.0 镜像封装有问题
[root@k8s
-master01 12.1]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp 1/1 Running 0 30s 10.244.58.251 k8s-node02 <none> <none> myapp-debug 1/1 Running 0 5s 10.244.58.197 k8s-node02 <none> <none> [root@k8s-master01 12.1]# kubectl exec -it myapp-debug -- /bin/sh / # ps -ef PID USER TIME COMMAND 1 root 0:00 sleep 1d 7 root 0:00 /bin/sh 14 root 0:00 ps -ef / # exit
# 消除实验影响
[root@k8s-master01 12.1]# kubectl delete pod --all
pod "myapp" deleted
pod "myapp-debug" deleted

(5)同一节点创建 Pod 调试

应用场景:当网络插件或网络策略出现问题,导致跨节点通信出现问题,验证 服务端Pod 正常,可以在 服务端Pod 同一节点启动 临时容器充当 客户端Pod 对 服务端Pod 访问,若 其他节点Pod 不能访问,而 临时容器客户端Pod 能够访问,则验证网络通讯问题

image

1.myapp-pod 中运行以 myapp:v1.0 镜像的 主容器main-c,其他节点的 Pod 对 myapp-pod 访问不通

2.基于 myapp-pod 所在的节点,启动一个临时容器 node-debug Pod 充当客户端,尝试当同在一台主机节点上 客户端 对 myapp-pod 访问是否成功,如果同一节点成功,则证明有通讯问题

[root@k8s-master01 12.1]# kubectl run myapp --image=myapp:v1.0 --restart=Never -- sleep 1d
pod/myapp created
[root@k8s-master01 12.1]# kubectl get pod -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP              NODE         NOMINATED NODE   READINESS GATES
myapp   1/1     Running   0          6s    10.244.58.203   k8s-node02   <none>           <none>
# kubectl debug 基于节点的名字自动生成新的 Pod 的名字。节点的根文件系统会被挂载在 /host 目录下
# 新的调试容器运行在主机 IPC 名字空间、主机网络名字空间以及主机 PID 名字空间内,Pod 没有特权,因此读取某些进程信息可能会失败,并且 chroot /host 也会失败(权限溢出),如果需要一个特权 Pod ,需要手动创建 [root@k8s-master01 12.1]# kubectl debug node/k8s-node02 -it --image=busybox:latest Creating debugging pod node-debugger-k8s-node02-cqtfs with container debugger on node k8s-node02. If you don't see a command prompt, try pressing enter. / # ls bin dev etc home host lib lib64 proc root sys tmp usr var / # ls /root / # ls /host/root/ # 原节点主机文件被挂载到 /host/root 下 --discovery-token-ca-cert-hash kubernetes-1.29.2-150500.1.1 anaconda-ks.cfg maqingpythonv1.tar.gz apache-11.3.13.tgz myapp.tar.gz busybox.tar.gz myapp_v2.0.tar.gz busybox_v.tar.gz myapp_v3.0.tar.gz calico-images nfs-subdir-external-provisioner.tar ingress-nginx-kube-webhook-certgen-v20231011-8b53cabe0.tar randexitv1.tar.gz k8s.gcr.io_sig-storage_nfs-subdir-external-provisioner_v4.0.2.tar.gz registry.k8s.io-ingress-nginx-controller-v1.9.4.tar / # exit [root@k8s-master01 12.1]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp 1/1 Running 0 11m 10.244.58.203 k8s-node02 <none> <none> node-debugger-k8s-node02-cqtfs 0/1 Completed 0 10m 192.168.66.13 k8s-node02 <none> <none>
# 在 node02 Pod 未退出时,新克隆 master01 终端,可以看到与克隆 pod myapp 在相同节点运行
[root@k8s-master01 ~]# kubectl get pod -o wide
NAME                             READY   STATUS    RESTARTS   AGE     IP              NODE         NOMINATED NODE   READINESS GATES
myapp                            1/1     Running   0          2m53s   10.244.58.203   k8s-node02   <none>           <none>
node-debugger-k8s-node02-cqtfs   1/1     Running   0          2m18s   192.168.66.13   k8s-node02   <none>           <none>
# k8s-node02 主机 /root 下文件,被挂载到 Pod 的 /host/root/ 目录下
[root@k8s-node02 ~]# ls
--discovery-token-ca-cert-hash  busybox_v.tar.gz                                                      kubernetes-1.29.2-150500.1.1  myapp_v3.0.tar.gz
anaconda-ks.cfg                 calico-images                                                         maqingpythonv1.tar.gz         nfs-subdir-external-provisioner.tar
apache-11.3.13.tgz              ingress-nginx-kube-webhook-certgen-v20231011-8b53cabe0.tar            myapp.tar.gz                  randexitv1.tar.gz
busybox.tar.gz                  k8s.gcr.io_sig-storage_nfs-subdir-external-provisioner_v4.0.2.tar.gz  myapp_v2.0.tar.gz             registry.k8s.io-ingress-nginx-controller-v1.9.4.tar
# 消除实验影响
[root@k8s-master01 12.1]# kubectl delete pod --all
pod "myapp" deleted
pod "node-debugger-k8s-node02-cqtfs" deleted

———————————————————————————————————————————————————————————————————————————

                                                                                                                         无敌小马爱学习

posted on 2025-08-05 11:37  马俊南  阅读(70)  评论(0)    收藏  举报