直接用kubectl logs查Golang容器日志需确保Pod处于Running或Completed状态;多容器Pod必须指定-c参数;查崩溃前日志用--previous;缓冲问题可能导致fmt.Println日志丢失,建议用log.Printf并配置os.Stdout输出。

直接用 kubectl logs 查容器日志
绝大多数 Golang 应用以单容器 Pod 形式运行,kubectl logs 是最直接的入口。注意:Pod 必须处于 Running 或刚结束的 Completed 状态,否则会报 container "xxx" in pod "yyy" is waiting to start: ContainerCreating 或 pod does not have a running container。
常见实操建议:
- 用
kubectl get pods -n先确认 Pod 名和状态,避免输错名字或查已销毁的 Pod - 如果 Pod 有多个容器(比如 sidecar),必须加
-c指定 Golang 主容器,否则报multiple containers错误 - 加
--tail=100限制行数,防止日志过长卡终端;加-f实时跟踪,但生产环境慎用,可能阻塞连接或压垮 API Server - Golang 默认输出到
stdout,只要没重定向到文件,kubectl logs就能捕获——这点和 Java/Python 应用一致,无需额外配置
查崩溃重启前的日志用 --previous
Golang 程序 panic 后容器退出,新 Pod 启动后旧日志就没了。此时 kubectl logs --previous 是唯一办法,它读取上一个容器实例的标准输出缓存。
关键限制:
- 只对刚重启过的 Pod 有效(Kubernetes 保留上一个容器日志约 1 小时,且节点磁盘未被轮转清理)
- Pod 必须是同一副本控制器(如 Deployment)重建的,手动删 Pod 再创建不算“previous”
- 如果看到
previous terminated container "xxx" in pod "yyy" not found,说明日志已被清理,得去节点上翻/var/log/pods/目录(见下一条)
节点本地日志路径:/var/log/pods//_/
当 kubectl logs 返回空或报错,且应用又没打到远程日志系统时,就得登录对应工作节点查原始文件。路径里的 不是 Pod 名,而是 kubectl get pod -o yaml 输出中的 metadata.uid 字段。
实操要点:
- 先用
kubectl get pod -o wide看 Pod 调度在哪个节点,再 SSH 登录该节点 - 进
/var/log/pods/后用ls -t | head -3找最新创建的目录,Golang 容器日志通常是0.log(CRI-O)或rootfs/var/log/containers/*.log(Docker) - 日志是 JSON 格式,每行含时间戳、流标识(
stdout/stderr)、日志内容,可用jq -r '.log' *.log提取纯文本 - 注意权限:普通用户无法读
/var/log/pods/,需sudo或由运维提供只读账号
为什么 fmt.Println 日志有时不显示?检查 Golang 的输出缓冲
Golang 的 fmt.Println 在容器中默认行缓冲,但若程序异常退出(如 panic 未 recover)或容器被 SIGTERM 强杀,最后一行日志可能滞留在缓冲区未刷出,导致 kubectl logs 看不到。
解决方案:
- 启动时加
os.Stdout.Sync()或用log.SetOutput(os.Stdout)配合log.SetFlags(0)避免额外格式干扰 - 更稳妥的是用
log.Printf替代fmt.Println,它默认调用os.Stdout.Write,且更易统一控制输出行为 - 如果用了第三方日志库(如
zap),确认是否启用了SyncWrite或设置了Flush周期——否则日志可能批量写入,崩溃时丢失
缓冲问题在开发阶段不易复现,上线后偶发丢日志,最容易被忽略。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











