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)增加临时容器
应用场景:检测、排错时使用

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 调试

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 的启动命令

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 能否启动(环境变量等未改变,从而排查是否是新封装的镜像问题)

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 能够访问,则验证网络通讯问题

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
———————————————————————————————————————————————————————————————————————————
无敌小马爱学习
浙公网安备 33010602011771号