调试 Kubernetes 最简单方法
肉眼品世界
共 14047字,需浏览 29分钟
· 2021-07-30
本文介绍了 Kubectl debug 和临时容器等调试方法。
作者:Martin Heinz 翻译:Bach (K8sMeetup)
校对:星空下的文仔 来源:K8sMeetup社区
kubectl logs
或者 kubectl describe pod
便足以找到问题所在,但有时候,一些问题会特别难查。这种情况下,大家可能会尝试使用 kubectl exec
,但有时候这样也还不行,因为 Distroless 等容器甚至不允许通过 SSH 进入 shell。那么,如果以上所有方法都失败了,我们要怎么办?kubectl debug
。这是不久前添加的一个新命令(v1.18),允许调试正在运行的 pod。它会将名为 EphemeralContainer(临时容器)的特殊容器注入到问题 Pod 中,让我们查看并排除故障。kubectl debug
看起来非常不错,但要使用它需要临时容器,临时容器到底是什么?container
。但与普通容器不同的是,临时容器不用于构建应用程序,而是用于检查。我们不会在创建 Pod 时定义它们,而使用特殊的 API 将其注入到运的行 Pod 中,来运行命令并检查 Pod 环境。除了这些不同,临时容器还缺少一些基本容器的字段,例如 ports
、resources
。kubectl debug
,那么如何启用临时容器的功能门?这取决于集群设置。例如,现在使用kubeadm启动创建集群,那么可以使用以下集群配置来启用临时容器:apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.20.2
apiServer:
extraArgs:
feature-gates: EphemeralContainers=true
# File: config.yaml
# Run: kind create cluster --config ./config.yaml --name kind --image=kindest/node:v1.20.2
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
featureGates:
EphemeralContainers: true
nodes:
- role: control-plane
~ $ kubectl explain pod.spec.ephemeralContainers
KIND: Pod
VERSION: v1
RESOURCE: ephemeralContainers <[]Object>
DESCRIPTION:
List of ephemeral containers run in this pod....
...
kubectl debug
。从简单的例子开始:~ $ kubectl run some-app --image=k8s.gcr.io/pause:3.1 --restart=Never
~ $ kubectl debug -it some-app --image=busybox --target=some-app
Defaulting debug container name to debugger-tfqvh.
If you don't see a command prompt, try pressing enter.
/ #
# From other terminal...
~ $ kubectl describe pod some-app
...
Containers:
some-app:
Container ID: containerd://60cc537eee843cb38a1ba295baaa172db8344eea59de4d75311400436d4a5083
Image: k8s.gcr.io/pause:3.1
Image ID: k8s.gcr.io/pause@sha256:f78411e19d84a252e53bff71a4407a5686c46983a2c2eeed83929b888179acea
...
Ephemeral Containers:
debugger-tfqvh:
Container ID: containerd://12efbbf2e46bb523ae0546b2369801b51a61e1367dda839ce0e02f0e5c1a49d6
Image: busybox
Image ID: docker.io/library/busybox@sha256:ce2360d5189a033012fbad1635e037be86f23b65cfd676b436d0931af390a2ac
Port: <none>
Host Port: <none>
State: Running
Started: Mon, 15 Mar 2021 20:33:51 +0100
Ready: False
Restart Count: 0
Environment: <none>
Mounts: <none>
some-app
的 Pod 来进行“调试”。然后针对这个 Pod 运行 kubectl debug
,指定 busybox
为临时容器的镜像,并作为原始容器的目标。此外,还需要包括 -it
参数,以便我们立即附加到容器获得 shell 会话。kubectl debug
是非常强大的工具,但有时向 Pod 添加一个容器还不足以获取 Pod 的另一个容器中运行的应用程序相关信息。当故障容器不包括必要的调试工具甚至 shell 时,可能就是这种情况。在这种情况下,我们可以使用 Process Sharing(进程共享)来使用注入的临时容器检查 Pod 的原有容器。spec.shareProcessNamespace
设置为 true
,并将一个临时容器注入其中。这样有点麻烦,尤其是需要调试多个 Pod 或容器,亦或者需要重复执行该操作时。幸运的是,kubectl debug
可以使用 --share-processes
做到:~ $ kubectl run some-app --image=nginx --restart=Never
~ $ kubectl debug -it some-app --image=busybox --share-processes --copy-to=some-app-debug
Defaulting debug container name to debugger-tkwst.
If you don't see a command prompt, try pressing enter.
/ # ps ax
PID USER TIME COMMAND
1 root 0:00 /pause
8 root 0:00 nginx: master process nginx -g daemon off;
38 101 0:00 nginx: worker process
39 root 0:00 sh
46 root 0:00 ps ax
~ $ cat /proc/8/root/etc/nginx/conf.d/default.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
...
--share-processes
还包括了 --copy-to=new-pod-name
,这是因为我们需要创建一个新的 Pod,其名称由该 flag 指定。如果我们从另一个终端列出正在运行的 Pod,我们将看到以下内容:# From other terminal:
~ $ kubectl get pods
NAME READY STATUS RESTARTS AGE
some-app 1/1 Running 0 23h
some-app-debug 2/2 Running 0 20s
~ $ kubectl get pod some-app-debug -o json | jq .spec.shareProcessNamespace
true
kubectl debug
:~ $ kubectl run distroless-python --image=martinheinz/distroless-python --restart=Never
~ $ kubectl exec -it distroless-python -- /bin/sh
# id
/bin/sh: 1: id: not found
# ls
/bin/sh: 2: ls: not found
# env
/bin/sh: 3: env: not found
#
...
kubectl debug -it distroless-python --image=praqma/network-multitool --target=distroless-python -- sh
Defaulting debug container name to debugger-rvtd4.
If you don't see a command prompt, try pressing enter.
/ # ping localhost
PING localhost(localhost (::1)) 56 data bytes
64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.025 ms
64 bytes from localhost (::1): icmp_seq=2 ttl=64 time=0.044 ms
64 bytes from localhost (::1): icmp_seq=3 ttl=64 time=0.027 ms
praqma/network-multitool
将临时容器注入到 Pod 中,该镜像包含了 curl
、ping
、telnet
等工具,现在我们可以进行所有必要的故障排除。~ $ kubectl run distroless-python --image=martinheinz/distroless-python --restart=Never
~ $ kubectl debug -it distroless-python --image=busybox --share-processes --copy-to=distroless-python-debug
Defaulting debug container name to debugger-l692h.
If you don't see a command prompt, try pressing enter.
/ # ps ax
PID USER TIME COMMAND
1 root 0:00 /pause
8 root 0:00 /usr/bin/python3.5 sleep.py # Original container is just sleeping forever
14 root 0:00 sh
20 root 0:00 ps ax
/ # cat /proc/8/root/app/sleep.py
import time
print("sleeping for 1 hour")
time.sleep(3600)
kubectl debug
以及 --share-processes --copy-to=...
,它创建了一个新的 Pod,带有额外的临时容器,可以访问所有进程。当我们列出正在运行的进程时,能看到应用程序容器的进程有 PID 8,可以用它来探索文件和环境。为此,我们需要通过 /proc/<PID>/...
目录,这个例子中是 /proc/8/root/app/...
。~ $ kubectl get pods
NAME READY STATUS RESTARTS AGE
crashing-app 0/1 CrashLoopBackOff 1 8s
~ $ kubectl debug crashing-app -it --copy-to=crashing-app-debug --container=crashing-app -- sh
If you don't see a command prompt, try pressing enter.
# id
uid=0(root) gid=0(root) groups=0(root)
#
...
# From another terminal
~ $ kubectl get pods
NAME READY STATUS RESTARTS AGE
crashing-app 0/1 CrashLoopBackOff 3 2m7s
crashing-app-debug 1/1 Running 0 16s
kubectl debug
允许通过创建 Pod 来调试节点,该 Pod 将在指定节点上运行,节点的根文件系统安装在 /root
目录中。我们甚至可以用 chroot
访问主机二进制文件,这本质上充当了节点的 SSH 连接:~ $ kubectl get nodes
NAME STATUS ROLES AGE VERSION
kind-control-plane Ready control-plane,master 25h v1.20.2
~ $ kubectl debug node/kind-control-plane -it --image=ubuntu
Creating debugging pod node-debugger-kind-control-plane-hvljt with container debugger on node kind-control-plane.
If you don't see a command prompt, try pressing enter.
root@kind-control-plane:/# chroot /host
# head kind/kubeadm.conf
apiServer:
certSANs:
- localhost
- 127.0.0.1
extraArgs:
feature-gates: EphemeralContainers=true
runtime-config: ""
apiVersion: kubeadm.k8s.io/v1beta2
clusterName: kind
controlPlaneEndpoint: kind-control-plane:6443
node/...
作为参数显式运行 kubectl debug
以访问我们集群的节点。在那之后,当连接到Pod后,我们使用 chroot /host
突破 chroot
,并完全进入主机。最后,为了验证是否真的可以看到主机上的所有内容,我们了查看一部分的 kubeadm.conf
,最终看到我们在文章开头配置的内容 feature-gates: EphemeralContainers=true
。推荐阅读:
评论
科研上最忌讳的事情有哪些?
点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达编者荐语 科研最忌讳的是与他人作比,对于博士而言,博士与博士的差异,比人和狗都大。整理自丨知乎链接丨https://www.zhihu.com/question/464787797作者:全小酱https://www.zh
小白学视觉
0
堪称最优秀的Docker可视化管理工具——Portainer你真的会用吗?
来源:blog.csdn.net/shark_chili3007/article/details/123366179👉 欢迎加入小哈的星球 ,你将获得: 专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡 / 赠书福利全栈前后端分离博客项目
小哈学Java
0
15种时间序列预测方法总结(包含多种方法代码实现)
向AI转型的程序员都关注了这个号👇👇👇在这篇文章中,我们将深入探讨时间序列预测的基本概念和方法。我们将首先介绍单元预测和多元预测的概念,然后详细介绍各种深度学习和传统机器学习方法如何应用于时间序列预测,包括循环神经网络(RNN)、一维卷积神经网络(1D-CNN)、Transformer、自回归模型(
机器学习AI算法工程
0
什么样的冷却方法适合数据中心运营?
冷却数据中心的最简单方法是安装空气交换器,通过服务器室生成冷空气。但是,如果想要节省资金,至少从长远来看,更好的方法可能是在每个机架上安装空气交换器,并使用它们为单个机架的服务器降温。"后机架冷却",与数据中心中更为传统的空气冷却系统相比,特别是在能源效率方面,其具有一些优势。冷却数据中心的最简单
数据中心运维管理
0
好未来测开一面,挺简单!(0428面试原题解析)
大家好,我是二哥呀。今天继续给大家分享春招面试题《好未来测开一面原题》,附详细答案,我会用通俗易懂+手绘图的方式,让天下所有的面渣都能逆袭 😁二哥的 Java 面试指南内容较长,建议正在冲刺 24 届春招和 25 届暑期实习、秋招的同学先收藏起来,面试的时候大概率会碰到,1、二哥的 Linux 速查
沉默王二
0
聊一聊我最关注的9个CV、SLAM、自动驾驶和AI圈子!
随着计算机视觉(2D/3D)、SLAM、自动驾驶、AI技术的快速迭代更新,可落地的技术也成为人们争先学习的重点。这使得从业者对于最前沿技术的获取能力变得至关重要。微信公众号便是一个非常有效的前沿信息分享平台。这里给大家推荐9个最常打开的计算机视觉、自动驾驶、SLAM、机器学习和AI方向的优质公众号平
3D视觉工坊
0
1000Mbps换算成MB/s是多少?除以8?想简单了!
原文链接:https://post.smzdm.com/p/azoqenzp/在网络传输的时候,往往会用到Mbps这个单位,GbE or 1 GigE 的网卡现在很流行,这个东西被大家叫做“千兆网卡”。同时,大家特别习惯用GB或者MB来描述一个磁盘的大小。这个叫做Gigabyte或者Megabyte
测试开发技术
0
Java与lua互相调用简单教程
来源:网络👉 欢迎加入小哈的星球 ,你将获得: 专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡 / 赠书福利全栈前后端分离博客项目 2.0 版本完结啦, 演示链接:http://116.62.199.48/ ,新项目
小哈学Java
0