容器销毁后能否提取容器内标准输出的日志?
答案是:不能。
应急响应中经常遇到的一类场景,容器内服务有漏洞,但是出事的容器被销毁重建了,此时应急取证需要提取容器中服务输出的日志,通常输出在容器的标准输出。
模拟docker容器销毁场景
# 启动一个每秒往 stdout 打日志的容器
docker run -d --name log-demo busybox:latest \
sh -c 'i=0; while true; do echo "log line $i $(date +%T)"; i=$((i+1)); sleep 1; done'
# 看 docker logs 读到的 stdout
sleep 3
docker logs log-demo
# docker 这个容器的日志文件落在宿主机哪里
docker inspect -f '{{.LogPath}}' log-demo
# 输出如: /var/lib/docker/containers/<容器ID>/<容器ID>-json.log
我们创建一个只输出日志的容器来模拟。

然后模拟容器被销毁的场景。
# 记下目录,删容器前后对比
CID=$(docker inspect -f '{{.Id}}' log-demo)
DIR=/var/lib/docker/containers/$CID
ls -ld "$DIR" # 删除前:目录在
# 删除容器 = 模拟 Pod/容器销毁
docker rm -f log-demo
# 验证:文件随容器一起消失,docker logs 也读不到
ls -ld "$DIR" # 报「没有那个文件或目录」
docker logs log-demo

模拟k8s pod 销毁的场景
这里使用kind + Pod 场景来模拟复现。
# 创建单节点集群,context 自动设为 kind-logdemo
kind create cluster --name logdemo --wait 60s
# 集群已存在,确认 context
kubectl config get-contexts # 看当前 context
kubectl --context kind-logdemo get nodes
# 创建一个每秒打 stdout 的 Pod
kubectl --context kind-logdemo run log-demo --image=busybox:latest --restart=Never -- \
sh -c 'i=0; while true; do echo "pod log line $i"; i=$((i+1)); sleep 1; done'
kubectl --context kind-logdemo wait --for=condition=Ready pod/log-demo --timeout=60s
sleep 3
kubectl --context kind-logdemo logs log-demo
# 查 Pod 落在哪个节点 + 它的 UID(路径里要用)
kubectl --context kind-logdemo get pod log-demo \
-o jsonpath='{.spec.nodeName}{" uid="}{.metadata.uid}{"\n"}'
# 节点名就是 docker 容器名:logdemo-control-plane
# 进节点看真实日志路径(kind 用 docker 容器模拟节点)
NODE=logdemo-control-plane
# /var/log/pods 下的 Pod 目录
docker exec $NODE sh -c 'ls -la /var/log/pods/ | grep log-demo'
# 真实日志文件:<container>/<重启次数>.log
docker exec $NODE sh -c 'find /var/log/pods/default_log-demo_* -type f'
docker exec $NODE sh -c 'tail -n 3 /var/log/pods/default_log-demo_*/log-demo/0.log'
# CRI 格式:2026-05-29T07:53:42.949Z stdout F pod log line 11
# /var/log/containers 下的软链接(kubectl logs 的实际入口)
docker exec $NODE sh -c 'ls -l /var/log/containers/ | grep log-demo'
docker exec $NODE sh -c 'readlink -f /var/log/containers/log-demo*'

然后再模拟k8s pod被销毁的场景。
# 模拟pod被销毁
kubectl --context kind-logdemo delete pod log-demo --grace-period=5
# 检查pod的日志是否还存在
for i in $(seq 1 12); do
docker exec $NODE sh -c 'ls /var/log/pods/ 2>/dev/null | grep -q log-demo ' \
&& echo "[$((i*5))s] 目录仍在" || { echo "目录已被清理,日志彻底消失"; break; }
sleep 5
done

真实文件由 kubelet 异步 GC,有十几秒延迟,这正是采集器必须实时跟读、不能等 Pod 删了再来收的原因。
用完想删集群:
kind delete cluster --name logdemo
总结
容器pod被销毁时,容器的标准输出日志几乎是实时被删除的,所以在应急场景下遇到类似情况没必要浪费时间获取已销毁的容器日志上。
赞赏
微信赞赏
支付宝赞赏
发表评论