4、日志采集策略:kubectl logs实时查看、--previous查看崩溃前日志、stern多Pod日志聚合

在 CrashLoop 故障排查中,日志是还原事故现场的第一手证据。Kubernetes 提供了多层次的日志采集手段,从单 Pod 实时流式输出到多 Pod 聚合检索,再到崩溃前日志的追溯。本章将系统讲解三种核心策略的适用场景、命令格式与实战技巧。

4.1 日志采集策略全景

下表对比了三种日志采集方式的核心差异,帮助你在不同故障阶段快速选择正确的工具。

策略 命令/工具 适用场景 关键参数 限制
实时查看 kubectl logs -f 跟踪当前 Pod 运行状态,观察启动日志 -f 持续输出,--tail 控制行数 Pod 重启后日志丢失
崩溃前日志 kubectl logs --previous 查看 CrashLoop 中上一实例的退出日志 --previous 追溯上一容器 仅保留最近一次崩溃的日志
多 Pod 聚合 stern 跨多个 Pod 或 Deployment 实时聚合日志 正则匹配 Pod 名,--tail 回溯行数 需额外安装,不支持 --previous

4.2 实时查看:kubectl logs -f

当 Pod 处于 CrashLoopBackOff 状态时,使用 kubectl logs 可以观察容器启动瞬间的日志输出。这是最直接的诊断手段。

4.2.1 基础用法

# 查看指定 Pod 的日志(默认只显示当前容器实例)
kubectl logs <pod-name> -n <namespace>

# 持续跟踪日志输出(类似 tail -f)
kubectl logs -f <pod-name> -n <namespace>

# 只显示最后 50 行日志
kubectl logs --tail=50 <pod-name> -n <namespace>

4.2.2 多容器 Pod 指定容器

如果 Pod 包含多个容器(如 Sidecar 模式),必须使用 -c 参数指定容器名:

kubectl logs -f <pod-name> -c <container-name> -n <namespace>
实战提示:在 CrashLoop 场景中,Pod 可能频繁重启导致日志流中断。建议先使用 --tail=100 获取最近日志,再配合 -f 观察下一次重启的启动过程。

4.3 崩溃前日志:kubectl logs --previous

CrashLoop 的核心特征是容器反复重启。每次重启后,当前实例的日志会被新进程覆盖。使用 --previous 参数可以查看上一崩溃实例的日志,这是还原崩溃原因的关键手段。

4.3.1 命令格式

# 查看上一崩溃实例的日志
kubectl logs --previous <pod-name> -n <namespace>

# 指定容器(多容器 Pod)
kubectl logs --previous <pod-name> -c <container-name> -n <namespace>

4.3.2 工作原理

Kubernetes 在容器重启时,会将上一容器的日志文件保留在节点文件系统中(通常位于 /var/log/pods/ 目录下)。--previous 参数会读取该历史日志文件,而不是当前运行中的日志流。

注意:--previous 只能查看最近一次崩溃的日志。如果 Pod 已经重启多次,较早的崩溃日志会被覆盖。建议在发现 CrashLoop 后第一时间执行此命令。

4.3.3 典型输出示例

$ kubectl logs --previous my-app-7d4f8b6c9-x2k3j -n production
Error: failed to connect to database at 10.0.1.5:5432
dial tcp 10.0.1.5:5432: connect: connection refused
panic: unable to initialize database connection

goroutine 1 [running]:
main.initDB()
        /app/main.go:45 +0x1a4
...

从上述日志可以快速定位到数据库连接失败是崩溃的直接原因。

4.4 多 Pod 日志聚合:stern

在生产环境中,一个 Deployment 通常运行多个 Pod 副本。CrashLoop 可能只影响部分副本,或者需要对比多个 Pod 的日志来定位问题。此时 stern 工具可以按正则表达式匹配 Pod 名称,实现多 Pod 日志的实时聚合输出。

4.4.1 安装 stern

# macOS
brew install stern

# Linux (下载二进制)
wget https://github.com/stern/stern/releases/download/v1.28.0/stern_1.28.0_linux_amd64.tar.gz
tar xzf stern_1.28.0_linux_amd64.tar.gz
sudo mv stern /usr/local/bin/

4.4.2 常用命令

# 匹配所有名称包含 "my-app" 的 Pod
stern my-app -n production

# 匹配多个命名空间
stern my-app --namespace production --namespace staging

# 回溯最近 200 行日志
stern my-app --tail 200 -n production

# 排除特定 Pod
stern my-app --exclude-pod my-app-7d4f8b6c9-x2k3j -n production

4.4.3 输出格式说明

stern 默认会在每行日志前添加 Pod 名称和容器名称,方便区分来源:

my-app-7d4f8b6c9-x2k3j container-0 2025-01-15T10:23:45Z Starting application...
my-app-7d4f8b6c9-y4l5m container-0 2025-01-15T10:23:46Z Connected to database
my-app-7d4f8b6c9-z6n7o container-0 2025-01-15T10:23:44Z Error: connection refused
最佳实践:在 CrashLoop 排查中,先使用 stern --tail 100 获取所有相关 Pod 的最近日志,快速识别哪些副本处于异常状态;然后针对异常 Pod 使用 kubectl logs --previous 深入分析崩溃原因。

4.5 日志采集策略决策流程

以下 SVG 流程图展示了在 CrashLoop 故障排查中如何根据当前状态选择正确的日志采集策略。

CrashLoop 日志采集策略决策流程 发现 CrashLoop Pod 当前是否处于 Running 状态? 是 kubectl logs -f 实时跟踪 观察启动日志,定位异常 否 kubectl logs --previous 分析崩溃前日志 是否需要对比多个 Pod 日志? 是 stern 多 Pod 聚合日志 否 单 Pod 日志深入分析

4.6 日志采集策略对比总结

下表从更多维度对比三种策略,帮助你在不同场景下做出最优选择。

对比维度 kubectl logs -f kubectl logs --previous stern
安装依赖 无(kubectl 内置) 无(kubectl 内置) 需单独安装
多 Pod 支持 否(单 Pod) 否(单 Pod) 是(正则匹配)
历史日志追溯 仅当前实例 上一崩溃实例 仅当前实例
实时流式输出 是(-f 参数) 否(静态输出) 是(默认持续输出)
输出可读性 纯日志内容 纯日志内容 带 Pod/容器前缀
典型场景 跟踪单 Pod 启动过程 CrashLoop 崩溃原因定位 多副本异常对比

4.7 实战案例:CrashLoop 日志采集三步法

以下是一个完整的 CrashLoop 日志采集流程,结合三种策略快速定位问题。

  1. 第一步:快速扫描
    # 使用 stern 查看所有相关 Pod 的最近日志
    stern my-app --tail 50 -n production

    发现 my-app-7d4f8b6c9-x2k3j 和 my-app-7d4f8b6c9-y4l5m 两个 Pod 频繁报错。

  2. 第二步:追溯崩溃原因
    # 查看崩溃前日志
    kubectl logs --previous my-app-7d4f8b6c9-x2k3j -n production

    日志显示 Failed to connect to Redis at 10.0.1.10:6379,确认是 Redis 连接问题。

  3. 第三步:实时验证修复
    # 修复 Redis 配置后,实时跟踪 Pod 启动
    kubectl logs -f my-app-7d4f8b6c9-x2k3j -n production

    观察到 Connected to Redis successfully,Pod 进入 Running 状态。

核心原则:先聚合(stern)发现异常范围,再追溯(--previous)定位根因,最后实时验证(-f)修复效果。三步循环,高效排查 CrashLoop。