Kubectl debug 调试容器

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 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代码程序上传并在云端以容器化的构建、传输和运行。
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
5月前
|
存储 Prometheus 监控
【Docker 专栏】Docker 容器内应用的调试与故障排除
【5月更文挑战第8天】本文探讨了Docker容器内应用的调试与故障排除,强调其重要性。方法包括:通过日志排查、进入容器检查、使用监控工具及检查容器配置。常见问题涉及应用启动失败、性能问题、网络连接和数据存储。案例分析展示了实战场景,注意事项提醒避免不必要的容器修改、备份数据和理解应用架构。掌握这些技能能确保Docker应用的稳定运行和性能优化。
202 7
【Docker 专栏】Docker 容器内应用的调试与故障排除
|
5月前
|
Kubernetes Shell Docker
容器服务ACK常见问题之容器服务ACK kubectl命令写到shell脚本失败如何解决
容器服务ACK(阿里云容器服务 Kubernetes 版)是阿里云提供的一种托管式Kubernetes服务,帮助用户轻松使用Kubernetes进行应用部署、管理和扩展。本汇总收集了容器服务ACK使用中的常见问题及答案,包括集群管理、应用部署、服务访问、网络配置、存储使用、安全保障等方面,旨在帮助用户快速解决使用过程中遇到的难题,提升容器管理和运维效率。
|
12月前
|
运维 监控 Cloud Native
《Docker调试技巧与工具:解决常见容器问题,助力容器应用稳定运行》
《Docker调试技巧与工具:解决常见容器问题,助力容器应用稳定运行》
271 0
|
12月前
|
Kubernetes 芯片 容器
加速你的容器管理!轻松安装kubeadm、kebelet和kubectl!
加速你的容器管理!轻松安装kubeadm、kebelet和kubectl!
122 0
|
弹性计算 Kubernetes Cloud Native
容器实验班开课!30 分钟学会使用 Kubectl 部署 web 服务到 K8s 集群
容器实验班开课!30 分钟学会使用 Kubectl 部署 web 服务到 K8s 集群
容器实验班开课!30 分钟学会使用 Kubectl 部署 web 服务到 K8s 集群
|
JSON Kubernetes 负载均衡
使用 Kubectl 管理 Kubernetes 容器平台
Kubectl 是一个用于操作 Kubernetes 集群的命令行接口,通过利用 Kubectl 的各种命令可以实现各种功能。
290 0
使用 Kubectl 管理 Kubernetes 容器平台
|
Kubernetes 容器 Perl
Linkerd 2.10—使用 Debug Sidecar,注入调试容器来捕获网络数据包
Linkerd 2.10—使用 Debug Sidecar,注入调试容器来捕获网络数据包
212 0
|
19天前
|
Linux iOS开发 Docker
Docker:容器化技术的领航者 —— 从基础到实践的全面解析
在云计算与微服务架构日益盛行的今天,Docker作为容器化技术的佼佼者,正引领着一场软件开发与部署的革命。它不仅极大地提升了应用部署的灵活性与效率,还为持续集成/持续部署(CI/CD)提供了强有力的支撑。
201 69
|
7天前
|
Kubernetes Cloud Native 持续交付
云原生之旅:Docker容器化与Kubernetes集群管理
【9月更文挑战第33天】在数字化转型的浪潮中,云原生技术如同一艘航船,带领企业乘风破浪。本篇文章将作为你的航海指南,从Docker容器化的基础讲起,直至Kubernetes集群的高级管理,我们将一起探索云原生的奥秘。你将学习到如何封装应用、实现环境隔离,以及如何在Kubernetes集群中部署、监控和扩展你的服务。让我们启航,驶向灵活、可伸缩的云原生未来。
|
10天前
|
Kubernetes Cloud Native Docker
云原生时代的容器化实践:Docker与Kubernetes入门
【9月更文挑战第30天】在云计算的浪潮中,云原生技术正以前所未有的速度重塑着软件开发和运维领域。本文将通过深入浅出的方式,带你了解云原生的核心组件——Docker容器和Kubernetes集群,并探索它们如何助力现代应用的构建、部署和管理。从Docker的基本命令到Kubernetes的资源调度,我们将一起开启云原生技术的奇妙之旅。