调试容器化工作负载和 Pod 是每位使用 Kubernetes 的开发人员和 DevOps 工程师的日常任务。通常情况下,我们简单地使用 kubectl logs 或者 kubectl describe pod 便足以找到问题所在,但有时候,一些问题会特别难查。这种情况下,大家可能会尝试使用 kubectl exec,但有时候这样也还不行,因为 Distroless 等容器甚至不允许通过 SSH 进入 shell。那么,如果以上所有方法都失败了,我们要怎么办?

Kubernetes v1.18 版本新增的 kubectl debug 命令,允许调试正在运行的 pod。它会将名为 EphemeralContainer(临时容器)的特殊容器注入到问题 Pod 中,让我们查看并排除故障。

临时容器其实是 Pod 中的子资源,类似普通 container。但与普通容器不同的是,临时容器不用于构建应用程序,而是用于检查。 我们不会在创建 Pod 时定义它们,而使用特殊的 API 将其注入到运的行 Pod 中,来运行命令并检查 Pod 环境。除了这些不同,临时容器还缺少一些基本容器的字段,例如 ports、resources。

开启临时容器功能

虽然临时容器是作为 Kubernetes 核心的 Pod 规范的一部分,但很多人可能还没有听说过。这是因为临时容器处于早期 Alpha 阶段,这意味着默认情况下不启用。Alpha 阶段的资源和功能可能会出现重大变化,或者在 Kubernetes 的某个未来版本中被完全删除。因此,要使用它们必须在 kubelet 中使用 Feature Gate(特性门控)显式启用。

在已经运行的 Kubernetes 集群中开启临时容器功能

编辑 /etc/manifests/kube-apiserver.yaml 文件,添加 EphemeralContainers=true 开启临时容器功能,如果要开启多个特性门控功能用 , 隔开:

- --feature-gates=DynamicKubeletConfig=true,EphemeralContainers=true

在初始化 Kubernetes 集群时开启临时容器功能

如果想在 kubeadm 初始化 Kubernetes 集群时开启临时容器功能,则修改 kubeadm 配置文件:

# init-k8s.yaml
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.20.2
apiServer:extraArgs:feature-gates: EphemeralContainers=true

然后通过 kubeadm init 初始化 Kubernetes 集群:

kubeadm init --config init-k8s.yaml

通过 Pod 副本调试

当故障容器不包括必要的调试工具甚至 shell 时,我们可以使用 --copy-to 指令复制出一个新的 Pod 副本,然后通过 --share-processes 指令使 Pod 中的容器之间共享进程命名空间。进程共享的一个问题是它不能应用于现有的 Pod,因此我们必须创建一个新 Pod。

# 启动普通 Nginx Pod
> kubectl run nginx-app --image=nginx --restart=Never# 启动临时容器,使用 Process Sharing(进程共享)来使用注入的临时容器检查 Pod 的原有容器。
# nginx-app 是普通 Pod 的名字,nginx-app-debug 是用于调试的 Pod 的名字,nginx-container-debug 是用于调试的 Pod 里的容器名,这里可以省略
> kubectl debug -it nginx-app \
--image=busybox --share-processes \
--copy-to=nginx-app-debug \
--container=nginx-container-debug# 在临时容器可以看到 Nginx 容器的进程和文件
/ # ps ax
PID   USER     TIME  COMMAND1 root      0:00 /pause6 root      0:00 nginx: master process nginx -g daemon off;35 101       0:00 nginx: worker process36 101       0:00 nginx: worker process37 101       0:00 nginx: worker process38 101       0:00 nginx: worker process39 101       0:00 nginx: worker process40 101       0:00 nginx: worker process41 101       0:00 nginx: worker process42 101       0:00 nginx: worker process43 root      0:00 sh48 root      0:00 ps ax
/ # cat /proc/6/root/etc/nginx/conf.d/default.conf
server {listen       80;listen  [::]:80;server_name  localhost;#access_log  /var/log/nginx/host.access.log  main;location / {root   /usr/share/nginx/html;index  index.html index.htm;}
......

上面的代码表明,通过进程共享,我们可以看到 Pod 中另一个容器内的所有内容,包括其进程和文件,这对于调试来说非常方便。如果我们从另一个终端列出正在运行的 Pod,我们将看到以下内容:

❯ kubectl get pod
NAME                           READY   STATUS    RESTARTS   AGE
nginx-app                       1/1     Running   0          3m23s
nginx-app-debug                 2/2     Running   0          3m10s

这就是我们在原始应用程序 Pod 上的新调试 Pod。与原始容器相比,它有 2 个容器,因为它还包括临时容器。此外,如果想在任何时候验证 Pod 中是否允许进程共享,那么可以运行:

❯ kubectl get pod some-app-debug -o json  | jq .spec.shareProcessNamespace
true

在创建 Pod 副本时改变 Pod 运行的命令

有时更改容器的命令很有用,例如调试崩溃的容器。为了模拟应用崩溃的场景,使用 kubectl run 命令创建一个立即退出的容器:

kubectl run --image=busybox myapp -- false

使用 kubectl describe pod myapp 命令,可以看到容器崩溃了:

此时可以使用 kubectl debug 命令创建该 Pod 的一个副本, 在该副本中将命令改变为交互式 shell:

# 这里 --container 不能省略
❯ kubectl debug myapp -it --copy-to=myapp-debug --container=myapp -- sh
If you don't see a command prompt, try pressing enter.
/ #

现在就有了一个可以执行类似检查文件系统路径或者手动运行容器命令的交互式 shell。

创建 Pod 副本时更改容器镜像

在某些情况下,你可能想从正常生产容器镜像中把行为异常的 Pod 改变为包含调试版本或者附加应用的镜像。

下面的例子,用 kubectl run 创建一个 Pod:

kubectl run myapp --image=busybox --restart=Never -- sleep 1d

现在可以使用 kubectl debug 创建一个副本 并改变容器镜像为 ubuntu:

kubectl debug myapp --copy-to=myapp-debug --set-image=myapp=ubuntu

–set-image=myapp=ubuntu 指令中 myapp 是容器名,ubuntu 是新的容器镜像。

调试集群节点

kubectl debug 允许通过创建 Pod 来调试节点,该 Pod 将在指定节点上运行,节点的根文件系统安装在 /root 目录中。我们甚至可以用 chroot 访问主机二进制文件,这本质上充当了节点的 SSH 连接:

查看 Kubernetes 集群的节点,我们准备调试 k8s-calico-master 节点。

❯ kubectl get nodes
NAME                STATUS   ROLES    AGE   VERSION
k8s-calico-master   Ready    master   7d    v1.17.3
k8s-calico-node01   Ready    <none>   7d    v1.17.3
k8s-calico-node02   Ready    <none>   7d    v1.17.3

使用 node/… 作为参数显式运行 kubectl debug 以访问我们集群的节点。

❯ kubectl debug node/k8s-calico-master  -it --image=ubuntu

当连接到Pod后,使用 chroot /host 突破 chroot,并完全进入主机。可以获取到节点完全的权限,查看到节点所有的文件,甚至重启节点。

root@k8s-calico-master:/etc# chroot /host# 查看节点文件
sh-4.2# cd /etc/kubernetes/manifests/
sh-4.2# ls
etcd.yaml  kube-apiserver.yaml  kube-controller-manager.yaml  kube-scheduler.yaml

参考链接

  • https://mp.weixin.qq.com/s/uZZvsqDuqM36HB5lVyO9iA
  • https://kubernetes.io/zh/docs/reference/command-line-tools-reference/feature-gates/
  • https://kubernetes.io/zh/docs/concepts/workloads/pods/ephemeral-containers/
  • https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#ephemeralcontainer-v1-core
  • https://kubernetes.io/zh/docs/tasks/configure-pod-container/share-process-namespace/

欢迎关注

Kubectl debug 调试容器相关推荐

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

    1.1 什么是临时容器? 临时容器与其他容器的不同之处在于,它缺少对资源或执行的保证,并且永远不会自动重启,因此不适用于构建应用程序.临时容器使用与常规容器相同的 Container.Spec字段进行 ...

  2. 如何使用 dlv 结合 Goland 进行程序 debug 调试

    如何使用 dlv 结合 Goland 进行程序 debug 调试 相信很多 Golang 的初级玩家不会进行程序的 Debug 定位问题单纯的靠脑子,或者效率很低的不断的添加日志打印,别问我为什么知道 ...

  3. 恕我直言,IDEA 的 Debug 调试,你可能只用了 10%

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 来源:bojiangzhou cnblogs.com/chiang ...

  4. debug调到循环最后_Java入门(7)——循环和debug 调试

    循环: while 循环: 格式: int i = 0; ①    //初始化条件 while(i < 10) { ②  //判断条件 System.out.println(i); ④ //循环 ...

  5. maven的tomcat插件如何进行debug调试

    利用maven来部署工程时,一般采用的是tomcat插件,使项目在tomcat上面运行,那么这个debug调试是如何进行呢? 我们在调试的时候问题: 会提示找不到资源,那么如何进行修改呢,方法两个: ...

  6. 思科交换机Debug调试命令

    下面列出了部分常用的debug 命令,与各协议和功能相关的更具体的debug命令和对其细节的注释,请参见本手册及命令参考手册中的各相关章节.要使用debug功能,需要在特权用户模式下进行配置: 命令 ...

  7. 【Flutter】Flutter 调试 ( 调试回退功能 | Debug 调试中查看变量的方式 | 控制台信息 )

    文章目录 一.调试回退功能 二.Debug 调试中查看变量的方式 三.Debug 控制台信息 四.相关资源 一.调试回退功能 在调试过程中 , 经常错过关键位置的调试 , 如没有进入关键方法进行调试 ...

  8. idea调试怎么跳出循环_使用IDEA的Debug调试功能,查看程序的运行过程

    Debug追踪,使用IDEA的断点调试功能,查看程序的运行过程 知乎视频​www.zhihu.com 1. 在有效代码行,点击行号右边的空白区域,设置断点,程序执行到断点将停止,我们可以手动来运行程序 ...

  9. 【Intellij IDEA系列】IDEA的Debug调试技巧

    以前一直是使用Eclipse进行开发的,突然使用idea进行开发,许多习惯都一时改变不过来,同时对于idea中的许多界面操作和快捷使用起来都特别变扭,这里总结一下debug调试时的一些使用方法. 精简 ...

最新文章

  1. golangsha1解码_golang中几种加密方式的处理
  2. Android 开发第四弹:围住神经猫(简单Demo)
  3. python插件安装包_python 离线安装插件包
  4. Python中strip()、lstrip()、rstrip()用法详解
  5. 微型计算机技术习题,微型计算机技术课后习题一二三章答案
  6. 手把手讲解 Android Hook入门Demo
  7. php数据库备份脚本
  8. 技术沙龙之液晶监视器和显示器
  9. libcareplus支持的补丁类型
  10. scikit-klearn之 1.决策树
  11. 下载eclipse太慢怎么办?
  12. m1电脑推荐使用Google Chrome浏览器
  13. springboot微信点餐系统的设计与实现 毕业设计-附源码221541
  14. DevOps亚马逊AWS相关介绍
  15. 【拜小白opencv】45-二维H-S直方图绘制----calcHist()函数、minMaxLoc()函数
  16. 浙江省中小学信息技术课 9 月换新教材,大数据人工智能占 80%
  17. 首席新媒体黎想教程:线上活动推广执行手册——第二篇
  18. php如何每三位逗号分开,PHP 数字格式化,数字每三位加逗号的简单示例
  19. RBM受限玻尔兹曼机的公式推导及代码实现(matlab)
  20. 职场人怎么提醒自己下班打卡?

热门文章

  1. Vue简明实用教程(13)——Vue的生命周期
  2. Excel文档安全性设置
  3. 基于springboot的课堂考勤签到打卡小程序
  4. 随身理财专家“挖财”推iPad应用,新增帐号对比功能
  5. One-Lin3r:懒人的福音,渗透测试单行化工具
  6. cf四大服务器位置,CF:从最初的42个服务器到现在的四大战区,穿越火线还能火多久?...
  7. 区块链存储优化——从MPT树到KV存储
  8. python是哪种动物_基于Python的动物识别专家系统
  9. 2016-1-21高博活动
  10. lua_pcall 函数详解