
背景
K8s node 工作节点磁盘告警,发现 /home/application/docker/overlay2 目录占用很大。这个目录存放的是 Docker overlay2 存储驱动的 layer ID(镜像层或容器层的哈希),需要定位是哪个 Pod 产生的。
排查步骤
1. 进入 overlay2 目录
cd /home/application/docker/overlay22. 按大小排序找出大 layer
du -sh * | sort -hr | head -10示例输出:
83G 058fafcef62ef64534f68ab0de17537120b5f437405b2a8c2ba3e02917aebb87
52G a1b2c3d4e5f6...
...3. 根据 layer ID 查找容器 ID
docker inspect $(docker ps -aq) --format='{{.Id}} {{.GraphDriver.Data.UpperDir}}' | grep <layer-id>示例:
docker inspect $(docker ps -aq) --format='{{.Id}} {{.GraphDriver.Data.UpperDir}}' | grep 058fafcef62e输出:
2d0142b1081d354b61c105116ed49fca9749566369bb57a6b96f5ec2519ba6b6 /home/application/docker/overlay2/058fafcef62ef64534f68ab0de17537120b5f437405b2a8c2ba3e02917aebb87/diff- 容器 ID:
2d0142b1081d...
4. 根据容器 ID 查找 Pod 信息
docker inspect <容器id> --format='{{json .Config.Labels}}' | jq .注:需要安装jq命令:yum install jq -y
示例:
docker inspect 2d0142b1081d --format='{{json .Config.Labels}}' | jq .输出:
{
"annotation.io.kubernetes.container.hash": "2897634b",
"annotation.io.kubernetes.container.restartCount": "0",
"annotation.io.kubernetes.container.terminationMessagePath": "/dev/termination-log",
"annotation.io.kubernetes.container.terminationMessagePolicy": "File",
"annotation.io.kubernetes.pod.terminationGracePeriod": "30",
"io.kubernetes.container.logpath": "/var/log/pods/base-uat_srebro-psm-education-d94db986f-sxjd4_943133e5-7684-4705-aa52-3fad0f393249/srebro-psm-education/0.log",
"io.kubernetes.container.name": "srebro-psm-education",
"io.kubernetes.docker.type": "container",
"io.kubernetes.pod.name": "srebro-psm-education-d94db986f-sxjd4",
"io.kubernetes.pod.namespace": "base-uat",
"io.kubernetes.pod.uid": "943133e5-7684-4705-aa52-3fad0f393249",
"io.kubernetes.sandbox.id": "d6a0115bab1f22202bbd0ad5b76f8b4433bb1e884ae57b854d49170f0f5b8b57"
}5. 提取关键信息
| 字段 | 值 | 说明 |
|---|---|---|
io.kubernetes.pod.name | srebro-psm-education-d94db986f-sxjd4 | Pod 名称 |
io.kubernetes.pod.namespace | base-uat | 命名空间 |
io.kubernetes.container.name | srebro-psm-education | 容器名称 |
io.kubernetes.container.logpath | /var/log/pods/... | 容器日志路径 |
快速查看该 Pod
kubectl get pod srebro-psm-education-d94db986f-sxjd4 -n base-uat
# 查看日志
kubectl logs srebro-psm-education-d94db986f-sxjd4 -n base-uat --tail=100
# 进入容器
kubectl exec -it srebro-psm-education-d94db986f-sxjd4 -n base-uat -- /bin/sh一键排查脚本
#!/bin/bash
# find-large-overlay.sh - 查找 overlay2 大文件对应的 Pod
OVERLAY_DIR="/home/application/docker/overlay2"
TOP_N=${1:-10}
echo "=== 查找 overlay2 目录下最大的 ${TOP_N} 个 layer ==="
cd $OVERLAY_DIR || exit 1
du -sh * 2>/dev/null | sort -hr | head -$TOP_N | while read size layer_id; do
echo ""
echo "【Layer】$layer_id"
echo "【大小】$size"
# 查找容器
container_info=$(docker inspect $(docker ps -aq) --format='{{.Id}} {{.GraphDriver.Data.UpperDir}}' 2>/dev/null | grep $layer_id)
if [ -n "$container_info" ]; then
container_id=$(echo $container_info | awk '{print $1}')
echo "【容器ID】${container_id:0:12}"
# 查找 Pod 信息
labels=$(docker inspect $container_id --format='{{json .Config.Labels}}' 2>/dev/null)
if [ -n "$labels" ]; then
pod_name=$(echo $labels | jq -r '.["io.kubernetes.pod.name"] // "N/A"')
namespace=$(echo $labels | jq -r '.["io.kubernetes.pod.namespace"] // "N/A"')
container_name=$(echo $labels | jq -r '.["io.kubernetes.container.name"] // "N/A"')
echo "【Pod】$pod_name"
echo "【命名空间】$namespace"
echo "【容器名】$container_name"
echo "【kubectl命令】kubectl logs $pod_name -n $namespace --tail=50"
fi
else
echo "【状态】未找到运行中的容器(可能是已删除容器的残留)"
fi
echo "----------------------------------------"
done使用方法:
chmod +x find-large-overlay.sh
./find-large-overlay.sh # 默认显示前10个
./find-large-overlay.sh 5 # 显示前5个
常见问题
Q: 为什么 overlay2 目录会占用很大?
| 原因 | 说明 |
|---|---|
| 容器内日志未限制 | 应用写入的日志文件持续增长 |
Q: 如何清理?
# 1. 先定位问题 Pod,修复应用(加日志切割)
# 2. 删除 Pod 重建(会清理对应 layer)
kubectl delete pod <pod-name> -n <namespace>Q: 如何避免?
- 应用日志输出到 stdout,由 kubelet 统一管理
总结
| 步骤 | 命令 | 目的 | |
|---|---|---|---|
| 1 | `du -sh * \ | sort -hr` | 找大 layer |
| 2 | `docker inspect ... \ | grep layer` | 找容器 ID |
| 3 | `docker inspect ... \ | jq .Labels` | 找 Pod 信息 |
核心思路: layer ID → 容器 ID → Pod 标签 → 定位应用
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 运维小弟