LabHub
学习 学习路径 课程

Docker 基础

用日志把原因收窄

在 LabHub 中继续学习

本实验在真正的 VM 中运行

这个环境不是 Pod,而是由 KubeVirt 启动的虚拟机。Linux 内核独立运行,systemd 真正管理服务,docker 也不是模拟工具,而是真正的 Docker 引擎。通过 docker run 启动的容器会成为实际进程,docker execdocker logs 也都能照常工作。

过去,这个实验在 Pod 中运行;由于该环境放弃了所有内核权限,启动容器的所有步骤都无法进行。现在已经没有受阻的步骤。

有两点需要了解。

目标

分别诊断仍在运行和已经停止的容器,掌握按照日志、退出码、状态字段这三项逐步缩小原因范围的顺序。

为什么重要

容器诊断之所以困难,不是因为没有信息,而是因为不知道按什么顺序查看。一旦有了顺序,大多数问题都能在 3 分钟内解决。首先查看日志,是因为它记录了应用自己留下的最后一句话;接着查看退出码,是因为当日志为空(即因信号而瞬间死亡)时,它是唯一的线索。以后在 Kubernetes 中也会原样沿用这一顺序,只是工具名称会改变。

步骤

  1. 创建 /root/dk3,让 dk-noisy 容器从 line-1 输出到 line-50,最后输出 done-50 后结束。
  2. 只将 dk-noisy 日志的最后 5 行保存到 /root/dk3/tail5.txt
  3. 创建 dk-err 容器,使其向标准输出写入 to-stdout,向标准错误写入 to-stderr,然后分别仅将标准输出保存到 /root/dk3/out.txt,仅将标准错误保存到 /root/dk3/err.txt
  4. dk-noisy 的日志添加时间戳,并只将第一行保存到 /root/dk3/ts.txt
  5. 使用 nginx:1.27-alpine 启动 dk-web2,在其中查看 nginx 版本并保存到 /root/dk3/nginx-version.txt
  6. 创建 dk-crash 容器,让它输出 starting 后尝试读取不存在的路径并失败。然后在 /root/dk3/crash.txt 中写入一行 exit=<실제 종료코드>
  7. 统计 dk-noisy 日志中 line- 出现的次数,并在 /root/dk3/count.txt 中只写入数字。
  8. /root/dk3/triage.md 中逐行写入 dk-noisydk-crashdk-web2 三个容器,每行包含容器名称和当前状态,并在 dk-crash 所在行中加入退出码。

参考

创建不断输出日志的容器

创建 /root/dk3,让 dk-noisy 容器从 line-1 输出到 line-50,最后输出 done-50 后结束。

使用循环输出多行,并在最后留下完成标记。容器必须运行到结束,最后一行才会出现。

只查看最后几行

只将 dk-noisy 日志的最后 5 行保存到 /root/dk3/tail5.txt

日志很长时,应该查看末尾而不是开头。有一个选项可以限制输出行数。

分离标准输出和标准错误

创建 dk-err 容器,使其向标准输出写入 to-stdout,向标准错误写入 to-stderr,然后分别仅将标准输出保存到 /root/dk3/out.txt,仅将标准错误保存到 /root/dk3/err.txt

docker logs 会分别原样传递两个流。可以使用 Shell 重定向逐个筛选。

查明日志记录时间

dk-noisy 的日志添加时间戳,并只将第一行保存到 /root/dk3/ts.txt

有一个添加时间戳的选项。只保存前面带有 RFC3339 时间的第一行。

检查正在运行的容器内部

使用 nginx:1.27-alpine 启动 dk-web2,在其中查看 nginx 版本并保存到 /root/dk3/nginx-version.txt

nginx 将版本信息输出到标准错误。如果忘记重定向,文件可能看起来是空的。

诊断失败的容器

创建 dk-crash 容器,让它输出 starting 后尝试读取不存在的路径并失败。然后在 /root/dk3/crash.txt 中写入一行 exit=<실제 종료코드>

结合日志最后一行和退出码,就能确定原因。请通过 inspect 查看退出码。

统计日志中的模式

统计 dk-noisy 日志中 line- 出现的次数,并在 /root/dk3/count.txt 中只写入数字。

也可以不把日志转存到文件,而是直接通过管道统计。请在文件中只留下准确的数字。

汇总三个容器的状态

/root/dk3/triage.md 中逐行写入 dk-noisydk-crashdk-web2 三个容器,每行包含容器名称和当前状态,并在 dk-crash 所在行中加入退出码。

通过 inspect 查看每个容器的实际状态和退出码,然后逐行写入。已停止的容器还必须包含退出码。