06 - 优雅的在K8S中Debug容器和主机

本文介绍了kubectldebug这款Kubernetes诊断工具,用于在生产环境中简化Pod故障排查。它利用EphemeralContainers特性,在无需更改容器镜像的情况下提供了一套完整的工具集,支持Pod和节点级别的调试,以及自定义debug镜像的构建。
摘要由CSDN通过智能技术生成

点击这里,参考原文。


本文主要介绍一个 K8S 故障排错新手段:kubectl debug

1 kubectl debug 起源

    开发者喜欢在生产部署中使用极致精简的容器镜像,这也是容器技术中的一个最佳实践。这种精简主义有很多好处,而且在大多数情况下运行良好,但是一旦需要在生产中排除一些故障时,这就变得很困难了,因为精简后的容器普遍缺失常用的排障工具,有些甚至连 bash/sh 解释器都没有。


    kubectl debug 是一款 k8s pod 诊断工具,能够帮助进行 Pod 的排障诊断。在 k8s v1.16 ~ v1.22 中是 Alpha 状态,默认关闭。从 k8s v1.23 开始这项功能才逐渐成熟,并成为 Beta 状态,默认开启。


2 kubectl debug 工作原理

    我们知道,容器本质上是带有 cgroup 资源限制和 namespace 隔离的一组进程。因此,我们只要启动一个进程,并且让这个进程加入到目标容器的各种 namespace 中,这个进程就能“进入容器内部”(注意引号),与容器中的进程 “看到” 相同的根文件系统、虚拟网卡、进程空间了 —— 这也正是 docker exec 和 kubectl exec 等命令的运行方式。


    现在的状况是,我们不仅要“进入容器内部”,还希望带一套工具集进去帮忙排查问题。那么,想要高效管理一套工具集,又要可以跨平台,最好的办法就是把工具本身都打包在一个容器镜像当中。接下来,我们只需要通过这个“工具镜像” 启动容器,再指定这个容器加入目标容器的的各种 namespace,自然就实现了 “携带一套工具集进入容器内部”。


3 kubectl debug 怎么用

3.1 开启功能

在 V1.23 及以上版本中,该功能默认开启。针对 1.23 以下的 K8S 版本,需要通过以下方式,手动开启。

第一步:控制面开启 EphemeralContainers featureGate.
进入 master 节点,编辑 /etc/kubernetes/manifests/ 下的 kube-apiserver.yaml,kube-controller-manager.yaml 及 kube-scheduler.yaml,在 command 部分添加 - --feature-gates=EphemeralContainers=true;


第二步:Kubelet 服务开启该功能
在节点上编辑 /var/lib/kubelet/kubeadm-flags.env,添加 --feature-gates=EphemeralContainers=true;或者设置KUBELET_EXTRA_ARGS=“–feature-gates=EphemeralContainers=true”


第三步:重启 Kubelet
systemctl restart kubelet


那么,我们有了Ephemeral Containers能做哪些事情呢?

3.2 使用方式

3.2.1 POD Troubleshooting

最直接简单的就是对一个pod进行调试命令如下:

kubectl debug mypod -it --image=busybox

默认情况下,用户不指定临时容器名称的话,debug容器名称就由kubectl自动生成一个唯一id的名称。如果用户需要自己指定容器名称,则使用:

kubectl debug mypod -c debugger --image=busybox

有了临时容器除了日常debug功能外,我们可以扩展出很多新花样的玩法。比如批量跑某个命名空间下的安全扫描的脚本而不用干扰原容器。

for pod in $(kubectl get -o name pod); 
do
    kubectl debug --image security/pod_scanner -p $pod /sanner.sh
done

3.2.2 POD Troubleshooting by Copy

对于没有开启Ephemeral Containers特性的集群,我们就只能通过复制模式来调试容器。它的原理是复制一个指定pod的新容器,并将debug作为sidecar跟随新容器一起启动(也就是重新创建一个pod,并将debug作为sidecar跟随新容器一起启动)。通过这种方式也能达到曲线救国的目的。此种方式的几个参数还是挺有意思:

–copy-to 指定新pod的名称
–replace=true 是否删除原容器
–same-node=true 是否调度到和原容器一样的node上
–share-processes=true 是否共享容器pid空间

例如,我们就可以启动一个跟需要调试pod一样配置的debug容器如下:

kubectl debug mypod -it 
--container=debug 
--image=busybox 
--copy-to=my-debugger 
--same-node=true 
--share-processes=true 

3.2.3 Node Troubleshooting

对!你没看错!利用Ephemeral Containers还能对Worker节点进行调试。当以节点为目标调用时,kubectl debug 将创建一个带有node名称的pod,并且调度到该节点。同时该容器还具备了hostIPC、hostNetwork和hostPID这些特权模式。不可思议的是Worker节点的根文件系统还被mount到了debug容器下的/host目录下。

直接执行这个命令就能debug主机:

kubectl debug node/mynode -it --image=busybox

3.3 Debug镜像

工欲善其事,必先利其器。不管怎样我们都需要一套工具完善的debug镜像,在处理问题时能够得心应手。虽然网上也有不少debug镜像,不过都还是不如自己构建来的畅快。

这里分享一个Debug镜像的Dockerfile,大家可以根据需要进行修改:

[root@master-01 test]# cat Dockerfile-debug 
FROM golang:alpine as grpcurl
RUN apk update && apk add --virtual build-dependencies git && apk add bash curl jq && go get -u github.com/fullstorydev/grpcurl && go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
FROM alpine:latest
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories && apk update && apk add --no-cache vim bash tcpdump curl wget strace mysql-client iproute2 redis jq iftop tzdata tar nmap bind-tools htop && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN wget -O /usr/bin/httpstat https://github.com/davecheney/httpstat/releases/download/v1.0.0/httpstat-linux-amd64-v1.0.0 && chmod +x /usr/bin/httpstat
COPY --from=grpcurl  /go/bin/grpcurl /usr/bin/grpcurl
ENV TZ=Asia/Shanghai LC_ALL=C.UTF-8 LANG=C.UTF-8 LANGUAGE=C.UTF-8
ENTRYPOINT [ "/bin/bash" ]
  • 18
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值