Kubectl debug 调试容器

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: Kubectl debug 调试容器

调试容器化工作负载和 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

image.png

在初始化 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  COMMAND
    1 root      0:00 /pause
    6 root      0:00 nginx: master process nginx -g daemon off;
   35 101       0:00 nginx: worker process
   36 101       0:00 nginx: worker process
   37 101       0:00 nginx: worker process
   38 101       0:00 nginx: worker process
   39 101       0:00 nginx: worker process
   40 101       0:00 nginx: worker process
   41 101       0:00 nginx: worker process
   42 101       0:00 nginx: worker process
   43 root      0:00 sh
   48 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 命令,可以看到容器崩溃了:image.png此时可以使用 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

参考链接

相关实践学习
通过容器镜像仓库与容器服务快速部署spring-hello应用
本教程主要讲述如何将本地Java代码程序上传并在云端以容器化的构建、传输和运行。
Kubernetes极速入门
Kubernetes(K8S)是Google在2014年发布的一个开源项目,用于自动化容器化应用程序的部署、扩展和管理。Kubernetes通常结合docker容器工作,并且整合多个运行着docker容器的主机集群。 本课程从Kubernetes的简介、功能、架构,集群的概念、工具及部署等各个方面进行了详细的讲解及展示,通过对本课程的学习,可以对Kubernetes有一个较为全面的认识,并初步掌握Kubernetes相关的安装部署及使用技巧。本课程由黑马程序员提供。 &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
目录
相关文章
|
6月前
|
存储 Prometheus 监控
【Docker 专栏】Docker 容器内应用的调试与故障排除
【5月更文挑战第8天】本文探讨了Docker容器内应用的调试与故障排除,强调其重要性。方法包括:通过日志排查、进入容器检查、使用监控工具及检查容器配置。常见问题涉及应用启动失败、性能问题、网络连接和数据存储。案例分析展示了实战场景,注意事项提醒避免不必要的容器修改、备份数据和理解应用架构。掌握这些技能能确保Docker应用的稳定运行和性能优化。
230 7
【Docker 专栏】Docker 容器内应用的调试与故障排除
|
6月前
|
Kubernetes Shell Docker
容器服务ACK常见问题之容器服务ACK kubectl命令写到shell脚本失败如何解决
容器服务ACK(阿里云容器服务 Kubernetes 版)是阿里云提供的一种托管式Kubernetes服务,帮助用户轻松使用Kubernetes进行应用部署、管理和扩展。本汇总收集了容器服务ACK使用中的常见问题及答案,包括集群管理、应用部署、服务访问、网络配置、存储使用、安全保障等方面,旨在帮助用户快速解决使用过程中遇到的难题,提升容器管理和运维效率。
|
运维 监控 Cloud Native
《Docker调试技巧与工具:解决常见容器问题,助力容器应用稳定运行》
《Docker调试技巧与工具:解决常见容器问题,助力容器应用稳定运行》
293 0
|
Kubernetes 芯片 容器
加速你的容器管理!轻松安装kubeadm、kebelet和kubectl!
加速你的容器管理!轻松安装kubeadm、kebelet和kubectl!
138 0
|
弹性计算 Kubernetes Cloud Native
容器实验班开课!30 分钟学会使用 Kubectl 部署 web 服务到 K8s 集群
容器实验班开课!30 分钟学会使用 Kubectl 部署 web 服务到 K8s 集群
容器实验班开课!30 分钟学会使用 Kubectl 部署 web 服务到 K8s 集群
|
JSON Kubernetes 负载均衡
使用 Kubectl 管理 Kubernetes 容器平台
Kubectl 是一个用于操作 Kubernetes 集群的命令行接口,通过利用 Kubectl 的各种命令可以实现各种功能。
299 0
使用 Kubectl 管理 Kubernetes 容器平台
|
Kubernetes 容器 Perl
Linkerd 2.10—使用 Debug Sidecar,注入调试容器来捕获网络数据包
Linkerd 2.10—使用 Debug Sidecar,注入调试容器来捕获网络数据包
219 0
|
5天前
|
Kubernetes Cloud Native Docker
云原生时代的容器化实践:Docker和Kubernetes入门
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术成为企业提升敏捷性和效率的关键。本篇文章将引导读者了解如何利用Docker进行容器化打包及部署,以及Kubernetes集群管理的基础操作,帮助初学者快速入门云原生的世界。通过实际案例分析,我们将深入探讨这些技术在现代IT架构中的应用与影响。
22 2
|
15天前
|
Kubernetes 监控 开发者
掌握容器化:Docker与Kubernetes的最佳实践
【10月更文挑战第26天】本文深入探讨了Docker和Kubernetes的最佳实践,涵盖Dockerfile优化、数据卷管理、网络配置、Pod设计、服务发现与负载均衡、声明式更新等内容。同时介绍了容器化现有应用、自动化部署、监控与日志等开发技巧,以及Docker Compose和Helm等实用工具。旨在帮助开发者提高开发效率和系统稳定性,构建现代、高效、可扩展的应用。
|
11天前
|
关系型数据库 MySQL API