资讯详情

超好用的k8s中pod诊断工具:kubectl-debug

微信微信官方账号:运维发展故事,作者:double冬

背景

容器技术的最佳实践之一是尽可能简化容器镜像。然而,这一实践会给调查问题带来麻烦:精简容器中常用的障碍物排除工具普遍缺失,有些容器甚至没有 shell (比如 FROM scratch )。 在这种情况下,我们只能通过日志或宿主机 docker-cli 或 nsenter 调查问题的效率很低K8s环境部署应用后,经常需要进入pod进行排错。除了查看pod logs和describe除了业务,传统的解决方案是pod提前安装基础镜像procps、net-tools、tcpdump、vim等工具。但这既不符合最小化镜像的原则,也不符合最小化镜像的原则Pod安全漏洞风险。

今日推荐一款K8s pod诊断工具,kubectl-debug简单、易用、强大 kubectl 插件, 它可以帮助你方便地进行 Kubernetes 上的 Pod 排障诊断。启动排错工具容器,并将其添加到目标业务容器中pid, network, user 以及 ipc namespace 此时,我们可以直接在新容器中使用 netstat, tcpdump 这些熟悉的工具来解决问题, 业务容器可以最小化, 无需预装任何额外的排障工具。 kubectl-debug 主要包括以下两部分:

  • kubectl-debug:命令行工具

  • debug-agent:部署在K8s的node用于启动关联排错工具容器

工作原理

众所周知,容器本质上是有的 cgroup 资源限制和 namespace 一组隔离过程。因此,我们只需要启动一个过程,并将其添加到目标容器中 namespace 这个过程就可以了 进入容器(注意引号),看到与容器中的过程相同的根文件系统、虚拟网卡和过程空间——这也是 docker exec 和 kubectl exec 等待命令的操作。

现在的情况是,我们不仅要 进入容器也希望带一套工具来帮助调查问题。然后,如果你想有效地管理一套工具集,并且可以跨平台,最好的方法是将工具本身包装在容器镜像中。 接下来,我们只需要通过这个工具镜像启动容器,然后指定各种添加到目标容器中的容器 namespace,自然实现 携带一套工具集进入容器。事实上,使用 docker-cli 此操作可实现:

export TARGET_ID=666666666 # 加入目标容器 network, pid 以及 ipc namespace docker run -it --network=container:$TARGET_ID --pid=container:$TARGET_ID --ipc=container:$TARGET_ID busybox  

这就是 kubectl-debug 的出发点: 用工具容器诊断业务容器 。背后的设计理念和 sidecar 等待模式:每个容器只做一件事。

具体到实现,一个 kubectl debug命令背后的逻辑过程如下:

图片

img

步骤如下:

  1. 插件查询 ApiServer:demo-pod 是否存在,节点是什么?

  2. ApiServer 返回 demo-pod 节点所在

  3. 目标节点创建插件请求 Debug Agent Pod

  4. Kubelet 创建 Debug Agent Pod

  5. 插件发现 Debug Agent 已经 Ready,发起 debug 请求(长连接)

  6. Debug Agent 收到 debug 请求,创建 Debug 加入目标容器的每个容器 Namespace 创建完成后,和 Debug 容器的 tty 建立连接

接下来,客户端可以通过 5,6 这两个连接开始了 debug 操作。操作结束后,Debug Agent 清理 Debug 清理容器和插件 Debug Agent,一次 Debug 完成

安装

github地址:https://github.com/aylei/kubectl-debug

  • Mac 可直接使用 brew 安装
brew install aylei/tap/kubectl-debug  
  • 安装二进制文件
export PLUGIN_VERSION=0.1.1 # linux x86_64 curl -Lo kubectl-debug.tar.gz https://github.com/aylei/kubectl-debug/releases/download/v${PLUGIN_VERSION}/kubectl-debug_${PLUGIN_VERSION}_linux_amd64.tar.gz # macos curl -Lo kubectl-debug.tar.gz https://github.com/aylei/kubectl-debug/releases/download/v${PLUGIN_VERSION}/kubectl-debug_${PLUGIN_VERSION}_darwin_amd64.tar.gz  tar -zxvf kubectl-debug.tar.gz kubectl-debug sudo mv kubectl-debug /usr/local/bin/  

Windows 用户可以在Release 页面选择下载windows加入环境变量使用版本

其中github上有提供debug agent以DaemonSet集群中安装了方式,但是daemonset模式,agent pod所有预先部署node总会占用资源,浪费资源造成排错调试频率低的环境。

日常用法说明

简单使用

1、kubectl 1.12.0 或更高的版本, 可直接使用

#查看常用命令参数 kubectl debug -h  

kubectl 从 1.12 版本之后开始支持从 PATH 插件自动发现.12 版本之前的 kubectl 这种插件机制不支持,但也可以命令名称 kubectl-debug 直接调用。

假如安装了 debug-agent 的 daemonset, 可以略去 --agentless 加快启动速度,稍后的命令将被删除 --agentless

kubectl debug POD_NAME --daemonset-ns=default --daemonset-name=debug-agent  

其中github上有提供debug agent以DaemonSet集群中安装了方式,但是daemonset模式,agent pod所有预先部署node对于排错调试频率低的环境,总会占用资源,造成资源浪费,部署方式:kubectl apply -f https://raw.githubusercontent.com/aylei/kubectl-debug/master/scripts/agent_daemonset.yml

3、agentless模式,kubectl-debug执行命令后才创建agent pod和排错工具容器,退出后删除工具容器和agent pod。因为每次执行都要重新拉起来agent,启动会比daemon-set模式稍慢-a, --agentless开启agentless模式:

kubectl debug POD_NAME --agentless --port-forward  

4、假如 Node 没有公网 IP 或无法直接访问(防火墙等原因), 请使用 port-forward 模式

kubectl debug POD_NAME --agentless --port-forward  

进阶使用

1、排错init-container

kubectl debug POD_NAME --container=init-pod  

2、假如 Pod 处于 CrashLookBackoff 状态不能连接, 可以复制一个完全相同的 Pod 来进行诊断

kubectl debug POD_NAME --fork  

自定义镜像配置

--image:可定制错误工具容器镜像,改为私有镜像仓库,默认为nicolaka/netshoot:latest --agent-image:在agentless自定义模式下debug-agent镜像,默认为aylei/debug-agent:latest。在daemon-set在模式下,直接将debug-agent daemonset pod template修改为私有仓库镜像即可  

配置文件

~/.kube/debug-config,通过配置文件修改默认参数,免去使用命令时设置flag。

# debug agent listening port(outside container)
default to 10027
agentPort: 10027
whether using agentless mode
default to false
agentless: true
namespace of debug-agent pod, used in agentless mode
default to 'default'
agentPodNamespace: default
prefix of debug-agent pod, used in agentless mode
default to  'debug-agent-pod'
agentPodNamePrefix: debug-agent-pod
image of debug-agent pod, used in agentless mode
default to 'aylei/debug-agent:latest'
agentImage: aylei/debug-agent:latest
daemonset name of the debug-agent, used in port-forward
default to 'debug-agent'
debugAgentDaemonset: debug-agent
daemonset namespace of the debug-agent, used in port-forwad
default to 'default'
debugAgentNamespace: kube-system
whether using port-forward when connecting debug-agent
default false
portForward: true
image of the debug container
default as showed
image: nicolaka/netshoot:latest
start command of the debug container
default ['bash']
command:
- '/bin/bash'
- '-l'

典型案例

使用 查看pod的网络流量

比如查看POD_NAME是kube-flannel-ds-amd64-2xwqp的网络流量:

 ~  kubectl debug kube-flannel-ds-amd64-2xwqp -n kube-system
Agent Pod info: [Name:debug-agent-pod-b14bd868-61a9-11ec-bc72-acbc328370f3, Namespace:default, Image:registry.cn-hangzhou.aliyuncs.com/querycapimages/kubectl-debug-agent:latest, HostPort:10027, ContainerPort:10027]
Waiting for pod debug-agent-pod-b14bd868-61a9-11ec-bc72-acbc328370f3 to run...
Forwarding from 127.0.0.1:10027 -> 10027
Forwarding from [::1]:10027 -> 10027
Handling connection for 10027
                             set container procfs correct false ..
pulling image registry.cn-hangzhou.aliyuncs.com/querycapimages/netshoot:latest, skip TLS false...
latest: Pulling from querycapimages/netshoot
Digest: sha256:f0eba49c9bf66600788d58779e57c2d7334708e12cb292ff8ccc9414c1b6730c
Status: Image is up to date for registry.cn-hangzhou.aliyuncs.com/querycapimages/netshoot:latest
starting debug container...
container created, open tty...
bash-5.0# iftop -i eth0
interface: eth0
IP address is: 172.17.3.3
MAC address is: 52:54:be:83:3a:e4

使用 诊断 DNS 解析

比如查看POD_NAME是kube-flannel-ds-amd64-2xwqp的网络流量:

bash-5.0# drill any www.baidu.com
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 3214
;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 5, ADDITIONAL: 3
;; QUESTION SECTION:
;; www.baidu.com. IN ANY

;; ANSWER SECTION:
www.baidu.com. 803 IN CNAME www.a.shifen.com.

;; AUTHORITY SECTION:
baidu.com. 38993 IN NS ns4.baidu.com.
baidu.com. 38993 IN NS ns3.baidu.com.
baidu.com. 38993 IN NS ns7.baidu.com.
baidu.com. 38993 IN NS dns.baidu.com.
baidu.com. 38993 IN NS ns2.baidu.com.

;; ADDITIONAL SECTION:
ns2.baidu.com. 19348 IN A 220.181.33.31
ns3.baidu.com. 23022 IN A 112.80.248.64
ns7.baidu.com. 20697 IN A 180.76.76.92

;; Query time: 1 msec
;; SERVER: 100.64.9.5
;; WHEN: Mon Dec 20 15:37:35 2021
;; MSG SIZE  rcvd: 196

drill 命令详解:https://commandnotfound.cn/linux/1/533/drill-%E5%91%BD%E4%BB%A4

使用 抓包

比如查看POD_NAME是kube-flannel-ds-amd64-2xwqp的网络流量:

bash-5.0# tcpdump -i eth0 -c 1 -Xvv
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
15:39:27.577342 IP (tos 0x0, ttl 63, id 41476, offset 0, flags [DF], proto TCP (6), length 89)
    198.19.116.60.16710 > 172.17.3.3.6443: Flags [P.], cksum 0xf831 (correct), seq 677521811:677521848, ack 1388710574, win 1037, options [nop,nop,TS val 2849535414 ecr 1924260089], length 37
 0x0000:  4500 0059 a204 4000 3f06 b036 c613 743c  E..Y..@.?..6..t<
 0x0010:  ac11 0303 4146 192b 2862 2993 52c6 0aae  ....AF.+(b).R...
 0x0020:  8018 040d f831 0000 0101 080a a9d8 75b6  .....1........u.
 0x0030:  72b1 e0f9 1703 0300 2047 49f1 8fbb 2835  r........GI...(5
 0x0040:  059a 5e82 0746 afaf bd2d 5af3 c797 16b5  ..^..F...-Z.....
 0x0050:  8709 4666 7e61 6f5a 0b                   ..Ff~aoZ.
1 packet captured
18 packets received by filter
0 packets dropped by kernel
bash-5.0# tcpdump -n -vvv -w /tmp/kube-flannel-ds-amd64-2xwqp.pcap
tcpdump: listening on veth19416cac, link-type EN10MB (Ethernet), capture size 262144 bytes
50 packets captured
50 packets received by filter
0 packets dropped by kernel

这里需要注意,如果是想拿到-w抓包保存的文件用wireshark工具分析,则需要去POD_NAME对应的宿主机上拷贝出来进行分析

[root@k8s-demo-master-01-2 ~]# docker ps |grep netshoot
58b918b67b3f        registry.cn-hangzhou.aliyuncs.com/querycapimages/netshoot:latest       "bash"                   15 minutes ago      Up 15 minutes                           unruffled_fermat
[root@k8s-demo-master-01-2 ~]# docker cp 58b918b67b3f:/tmp/kube-flannel-ds-amd64-2xwqp.pcap .
[root@k8s-demo-master-01-2 ~]# ll |grep kube-flannel-ds-amd64-2xwqp.pcap
-rw-r--r--  1 root root 5404 12月 20 23:41 kube-flannel-ds-amd64-2xwqp.pcap

诊断 CrashLoopBackoff

排查 CrashLoopBackoff 是一个很麻烦的问题,Pod 可能会不断重启, kubectl exec 和 kubectl debug 都没法稳定进行排查问题,基本上只能寄希望于 Pod 的日志中打印出了有用的信息。 为了让针对 CrashLoopBackoff 的排查更方便, kubectl-debug 参考 oc debug 命令,添加了一个 --fork 参数。当指定 --fork 时,插件会复制当前的 Pod Spec,做一些小修改, 再创建一个新 Pod:

  • 新 Pod 的所有 Labels 会被删掉,避免 Service 将流量导到 fork 出的 Pod 上

  • 新 Pod 的 ReadinessProbe 和 LivnessProbe 也会被移除,避免 kubelet 杀死 Pod

  • 新 Pod 中目标容器(待排障的容器)的启动命令会被改写,避免新 Pod 继续 Crash

接下来,我们就可以在新 Pod 中尝试复现旧 Pod 中导致 Crash 的问题,示例pod_name为srv-es-driver-7445f6cf48-ff7bq的go服务。为了保证操作的一致性,可以先 chroot 到目标容器的根文件系统中:

 ~  kubectl-debug srv-es-driver-7445f6cf48-ff7bq -n devops --agentless --port-forward
Agent Pod info: [Name:debug-agent-pod-177482f4-61ad-11ec-b297-acbc328370f3, Namespace:default, Image:registry.cn-hangzhou.aliyuncs.com/querycapimages/kubectl-debug-agent:latest, HostPort:10027, ContainerPort:10027]
Waiting for pod debug-agent-pod-177482f4-61ad-11ec-b297-acbc328370f3 to run...
Forwarding from 127.0.0.1:10027 -> 10027
Forwarding from [::1]:10027 -> 10027
Handling connection for 10027
                             set container procfs correct false ..
pulling image registry.cn-hangzhou.aliyuncs.com/querycapimages/netshoot:latest, skip TLS false...
latest: Pulling from querycapimages/netshoot
Digest: sha256:f0eba49c9bf66600788d58779e57c2d7334708e12cb292ff8ccc9414c1b6730c
Status: Image is up to date for registry.cn-hangzhou.aliyuncs.com/querycapimages/netshoot:latest
starting debug container...
container created, open tty...
bash-5.0# ls
bin                        mnt                        sys
dev                        opt                        termshark_2.1.1_linux_x64
etc                        proc                       tmp
home                       root                       usr
lib                        run                        var
lib64                      sbin
media                      srv
bash-5.0# chroot /proc/1/root
root@srv-es-driver-7445f6cf48-ff7bq:/# ls
bin   dev  go  lib media  opt   root  sbin  sys  usr
boot  etc  home  lib64 mnt    proc  run   srv  tmp  var
root@srv-es-driver-7445f6cf48-ff7bq:/# cd /go/bin/
root@srv-es-driver-7445f6cf48-ff7bq:/go/bin# ls
openapi.json  srv-es-driver
root@srv-es-driver-7445f6cf48-ff7bq:/go/bin# ./srv-es-driver
 # 观察执行启动脚本时的信息并根据信息进一步排障

自定义image作为sidercar安装命令行调试

对于没有安装yum,apt-get 的镜像可以挂载 centos或者ubuntu的sidercar镜像, 再进行操作, 如安装 redis 命令, 再使用redis-cli 命令

 ~  kubectl-debug srv-es-driver-7445f6cf48-ff7bq -n devops --agentless --port-forward --image centos
Agent Pod info: [Name:debug-agent-pod-f5077b08-61ad-11ec-8728-acbc328370f3, Namespace:default, Image:registry.cn-hangzhou.aliyuncs.com/querycapimages/kubectl-debug-agent:latest, HostPort:10027, ContainerPort:10027]
Waiting for pod debug-agent-pod-f5077b08-61ad-11ec-8728-acbc328370f3 to run...
Forwarding from 127.0.0.1:10027 -> 10027
Forwarding from [::1]:10027 -> 10027
Handling connection for 10027
                             set container procfs correct false ..
pulling image centos, skip TLS false...
latest: Pulling from library/centos
a1d0c7532777: Pull complete
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
starting debug container...
container created, open tty...
[root@srv-es-driver-7445f6cf48-ff7bq /]# yum install -y redis
 

参考链接:

https://aleiwu.com/post/kubectl-debug-intro/

**:https://www.devopstory.cn**

我是冬子先生,《运维开发故事》公众号团队中的一员,一线运维农民工,云原生实践者,这里不仅有硬核的技术干货,还有我们对技术的思考和感悟,欢迎关注我们的公众号,期待和你一起成长!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WGZyqt0N-1642412583816)(https://mmbiz.qpic.cn/mmbiz_jpg/4XricCQ2YfK6Z3icUoVg98qibov1hRXIu1379ldia74V9fVkg412Gh0MCiaVvgpjzzqibkJGrX1c1RibLZnQbhRWqEGLw/640?wx_fmt=jpeg)]

扫码二维码

关注我,不定期维护优质内容

如果我的文章对你有所帮助,还请帮忙一下,你的支持会激励我输出更高质量的文章,非常感谢!

你还可以把我的公众号设为「」,这样当公众号文章更新时,你会在第一时间收到推送消息,避免错过我的文章更新。

                                          ........................

标签: aoz1014aic集成电路

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台