K8s 节点排查缺工具?OPS-DEBUG——集群调试专用 Docker 镜像
前两周排查一个 K8s 集群问题:节点网络异常,Pod 调度异常,CNI 插件疑似出问题。我要做的很简单——进节点抓个包看看。结果 tcpdump 没有,nmap 没有,htop 也没有,连 jq 都没装。集群节点为了安全最小化安装,工具链严重不全。
这种场景在 K8s 运维中太常见了:
- Pod 启动异常,需要进节点排查网络 / 磁盘 / 系统资源
- 集群节点最小化安装,没有多余工具
- 环境离线,无法临时
apt install - 每次排查都要在节点上重复"搭环境"
基于这个痛点,我做了 OPS-DEBUG——一个基于 Debian 12 的 Docker 调试镜像,预装 120+ 高频运维工具。通过 DaemonSet 部署到集群每个节点后,任何时候需要排查问题,直接 kubectl exec 进去就行。
镜像概览
OPS-DEBUG 基于 debian:bookworm 构建,镜像体积 1.48GB,压缩后仅 490MB。

Dockerfile
整个镜像由一份分层清晰的 Dockerfile 构建,按运维场景逐层叠加工具:
# ============================================================
# OPS-DEBUG: 运维调试镜像
# 基础: debian:bookworm
# ============================================================
FROM debian:bookworm
ENV DEBIAN_FRONTEND=noninteractive
# T0 - 核心运行时
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates curl wget git \
openssh-client openssh-server \
jq yq jo \
python3 python3-pip python3-venv \
vim nano bash-completion \
&& rm -rf /var/lib/apt/lists/*
# T1 - 网络诊断
RUN apt-get update && apt-get install -y --no-install-recommends \
tcpdump tshark wireshark-common ngrep nmap \
netcat-openbsd socat httpie dnsutils whois \
mtr traceroute iperf3 iftop nload \
ethtool iproute2 arp-scan net-tools \
conntrack iptables nftables \
inetutils-telnet \
&& rm -rf /var/lib/apt/lists/*
# T2 - 系统诊断
RUN apt-get update && apt-get install -y --no-install-recommends \
procps psmisc sysstat htop atop lsof \
strace dmidecode lshw pciutils usbutils kmod \
smartmontools hdparm linux-perf chrony \
&& rm -rf /var/lib/apt/lists/*
# T3 - 存储与文件系统
RUN apt-get update && apt-get install -y --no-install-recommends \
rsync rclone ncdu tree \
fdisk gdisk parted \
e2fsprogs xfsprogs \
dosfstools ntfs-3g \
mdadm lvm2 \
nfs-common cifs-utils \
&& rm -rf /var/lib/apt/lists/*
# T4 - 专项运维(容器/DB/K8s)
RUN apt-get update && apt-get install -y --no-install-recommends \
docker.io docker-compose tini \
default-mysql-client postgresql-client redis-tools sqlite3 \
etcd-client openssl gnupg cron \
cloud-guest-utils \
&& rm -rf /var/lib/apt/lists/*
RUN curl -fsSL "https://github.com/containerd/nerdctl/releases/download/v2.0.4/nerdctl-2.0.4-linux-amd64.tar.gz" \
| tar xz -C /usr/local/bin/ nerdctl
RUN K8S_VER=$(curl -fsSL https://dl.k8s.io/release/stable.txt) \
&& curl -fsSL "https://dl.k8s.io/release/${K8S_VER}/bin/linux/amd64/kubectl" \
-o /usr/local/bin/kubectl && chmod +x /usr/local/bin/kubectl
RUN curl -fsSL https://get.helm.sh/helm-v3.17.0-linux-amd64.tar.gz \
| tar xz -C /tmp/ && mv /tmp/linux-amd64/helm /usr/local/bin/helm
# T8 - 压测与磁盘 IO
RUN apt-get update && apt-get install -y --no-install-recommends \
iperf3 fio sysbench \
&& rm -rf /var/lib/apt/lists/*
# 文字处理 & 终端增强
RUN apt-get update && apt-get install -y --no-install-recommends \
lnav ripgrep fd-find \
unzip zip p7zip-full tmux screen \
gzip bzip2 xz-utils zstd \
&& rm -rf /var/lib/apt/lists/*
# Python 补充包
RUN pip3 install --no-cache-dir --break-system-packages \
requests httpx paramiko psutil rich click pyyaml flask
WORKDIR /workspace
COPY docs.html /opt/docs/index.html
EXPOSE 80
CMD ["python3", "-m", "http.server", "80", "-d", "/opt/docs"]
部署方式
方式一:DaemonSet——常驻所有节点(推荐)
在每个节点上部署一个调试 Pod,需要排查问题时随时 kubectl exec 进去:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ops-debug
namespace: ops
spec:
selector:
matchLabels:
app: ops-debug
template:
metadata:
labels:
app: ops-debug
spec:
hostNetwork: true
hostPID: true
nodeSelector:
kubernetes.io/os: linux
tolerations:
- operator: Exists
containers:
- name: debug
image: ops-debug:latest
imagePullPolicy: IfNotPresent
command: ["sleep", "infinity"]
securityContext:
privileged: true
volumeMounts:
- name: host-root
mountPath: /host
volumes:
- name: host-root
hostPath:
path: /
# 部署 kubectl apply -f ops-debug-daemonset.yaml # 进入任意节点调试 kubectl exec -it -n ops ops-debug-xxxxx -- bash
关键配置说明:
- hostNetwork: true——共享宿主机网络命名空间,直接抓节点网卡流量
- hostPID: true——能看到宿主机所有进程
- privileged: true——抓包、挂载设备等操作需要
- sleep infinity——保持 Pod 运行,等待 exec 接入
- 挂载 /host——通过
/host访问宿主机文件系统
方式二:Deployment——按需部署到指定节点
如果不想在每个节点都跑一个 Pod,可以用 Deployment + nodeSelector 定位到目标节点:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ops-debug
namespace: ops
spec:
replicas: 1
selector:
matchLabels:
app: ops-debug
template:
metadata:
labels:
app: ops-debug
spec:
hostNetwork: true
hostPID: true
nodeSelector:
kubernetes.io/hostname: node-xxx
tolerations:
- operator: Exists
containers:
- name: debug
image: ops-debug:latest
imagePullPolicy: IfNotPresent
command: ["sleep", "infinity"]
securityContext:
privileged: true
volumeMounts:
- name: host-root
mountPath: /host
volumes:
- name: host-root
hostPath:
path: /
# 部署到指定节点 kubectl apply -f ops-debug-deployment.yaml # 进入调试 kubectl exec -it -n ops ops-debug-xxxxx -- bash # 用完缩容到 0 kubectl scale deployment ops-debug -n ops --replicas=0
补充:容器运行时调试(nerdctl)
大部分场景不需要访问容器运行时,但如果需要 nerdctl ps 查看节点容器,需要额外挂载 containerd 的 socket。在 DaemonSet 中追加以下配置:
# 在 volumeMounts 和 volumes 中追加
spec.template.spec.containers[0].volumeMounts:
- name: containerd-sock
mountPath: /run/containerd/containerd.sock
spec.template.spec.volumes:
- name: containerd-sock
hostPath:
path: /run/containerd/containerd.sock
注意:不同发行版路径可能不同——K3s 是 /run/k3s/containerd/containerd.sock,部分定制系统可能在 /var/run 下。请根据实际集群调整。
K8s 调试实战
节点网络排查
# 抓取 Pod 所在网卡流量 tcpdump -i caliXXX -c 100 -w /workspace/trace.pcap # 排查 DNS 解析 dig +trace +short cluster.local # 查看 conntrack 连接跟踪 conntrack -L | grep <pod-ip> # mtr 路由追踪 mtr -r -c 10 8.8.8.8
节点磁盘 / IO 异常
# 宿主机磁盘 IO(通过 /host 访问宿主机目录) iostat -x 1 # 磁盘性能基准 fio --rw=randrw --bs=4k --size=1G --direct=1 # 宿主机磁盘使用分析 ncdu /host/var/lib/kubelet # SMART 健康检查(直通宿主机设备) smartctl -H /dev/sda
集群操作
# 集群状态 kubectl get nodes -o wide kubectl get pods -A | grep -v Running # 查看异常 Pod 日志 kubectl logs -n <ns> <pod> --tail=100 # 查看集群事件 kubectl get events -A --sort-by='.lastTimestamp' # Helm 发布状态 helm list -A # etcd 健康检查 etcdctl --endpoints=https://127.0.0.1:2379 endpoint health
容器运行时调试(需挂载 containerd socket)
# 查看节点上所有容器 nerdctl ps -a nerdctl images nerdctl logs <container-id> nerdctl exec -it <container-id> sh
镜像分发到私有仓库
对于离线集群,先将镜像推送到私有 registry:
# 打标签并推送 docker tag ops-debug:latest registry.internal/ops/ops-debug:latest docker push registry.internal/ops/ops-debug:latest # 修改 DaemonSet 中的 image 为私有仓库地址 # image: registry.internal/ops/ops-debug:latest
镜像压缩后仅 490MB,对于自建 Harbor 或 Nexus 仓库来说负担很小。
主机层级使用(补充)
如果当前环境没有 K8s,也支持 docker run 直接使用:
# 交互式 docker run -it --rm -v $PWD:/workspace ops-debug:latest # 带网络共享 docker run -it --rm --network host ops-debug:latest
写在最后
做这个镜像的初衷很简单——K8s 集群节点为了安全最小化安装,出问题时才发现缺工具。OPS-DEBUG 通过 DaemonSet 一次部署,让每个 Node 随时可调试。
项目持续维护中,欢迎交流反馈。
本文系作者 @Mr.Lee 原创发布在 维简网。未经许可,禁止转载。