脚本如下,新建一个find_pod_by_snapshot.sh文件,并且给予执行权限
#!/usr/bin/env bash
# 用法:
# ./find_pod_by_snapshot.sh 11285
# ./find_pod_by_snapshot.sh /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/11285/fs
# 仅依赖:bash、grep、sed、kubectl
set -euo pipefail
ROOT="${CONTAINERD_SNAP_ROOT:-/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots}"
ARG="${1:?Usage: $0 <snapshot-id | upperdir-path>}"
# 解析 upperdir
if [[ "$ARG" = /* ]]; then
UP="$ARG"
else
UP="$ROOT/$ARG/fs"
fi
echo "Upperdir: $UP"
# 1) 找容器ID(可能多个)
mapfile -t CIDS < <(
grep -R -- "$UP" /proc/*/mountinfo 2>/dev/null \
| sed -nE 's#.*/k8s\.io/([0-9a-f]{64})/rootfs.*#\1#p' \
| sort -u
)
if ((${#CIDS[@]}==0)); then
echo "⚠️ 未在本机找到使用该 upperdir 的容器挂载;容器可能已退出,或这不是运行节点。"
exit 4
fi
printf '找到 %d 个容器:\n' "${#CIDS[@]}"; printf ' - %s\n' "${CIDS[@]}"
# 2) 选择 kubeconfig(优先环境变量,其次常见路径)
KCFG="${KUBECONFIG:-}"
if [[ -z "${KCFG}" ]]; then
for f in "$HOME/.kube/config" "/root/.kube/config" "/etc/kubernetes/kubelet.conf" "/var/lib/kubelet/kubeconfig" "/etc/rancher/k3s/k3s.yaml" "/var/lib/rancher/k3s/agent/kubelet.kubeconfig"; do
[[ -r "$f" ]] && { KCFG="$f"; break; }
done
fi
command -v kubectl >/dev/null 2>&1 || { echo "❌ 未找到 kubectl"; exit 5; }
[[ -n "$KCFG" ]] || { echo "❌ 未找到可读的 kubeconfig"; exit 6; }
export KUBECONFIG="$KCFG"
echo "使用 kubeconfig: $KUBECONFIG"
# 3) 拉一次全集群容器ID清单 → 写入临时文件(避免 subshell/赋值坑)
JSONPATH='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{range .status.initContainerStatuses[*]}{.name}{"\t"}{.containerID}{"\n"}{end}{range .status.containerStatuses[*]}{.name}{"\t"}{.containerID}{"\n"}{end}{range .status.ephemeralContainerStatuses[*]}{.name}{"\t"}{.containerID}{"\n"}{end}{end}'
TMP=$(mktemp)
trap 'rm -f "$TMP"' EXIT
kubectl get pods -A -o jsonpath="$JSONPATH" > "$TMP"
# Debug:看看 kubectl 实际返回了多少行
LINES=$(wc -l < "$TMP" || echo 0)
echo "kubectl 返回 $LINES 行可匹配记录"
echo
echo "映射结果:"
echo "NAMESPACE/POD [CONTAINER] containerID"
echo "----------------------------------------"
# 4) 对每个 CID 直接 grep 命中(先全长,再 12 位前缀)
for CID in "${CIDS[@]}"; do
if grep -Fq "$CID" "$TMP"; then
grep -F "$CID" "$TMP" | while IFS=$'\t' read -r ns pod ctr contid; do
[[ -z "${ns:-}" || -z "${pod:-}" || -z "${ctr:-}" ]] && continue
printf "%s/%s [%s] %s\n" "$ns" "$pod" "$ctr" "$contid"
done
else
SHORT="${CID:0:12}"
if grep -Fq "$SHORT" "$TMP"; then
grep -F "$SHORT" "$TMP" | while IFS=$'\t' read -r ns pod ctr contid; do
[[ -z "${ns:-}" || -z "${pod:-}" || -z "${ctr:-}" ]] && continue
printf "%s/%s [%s] %s\n" "$ns" "$pod" "$ctr" "$contid"
done
else
echo "(集群侧未匹配到) containerd://$CID"
fi
fi
done