AI Infra 训练营
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
HiHuo 主站
GitHub
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
HiHuo 主站
GitHub

dmesg —— 看内核环形缓冲日志

一句话定义

dmesg(display message)显示内核环形缓冲区(kernel ring buffer)里的消息——硬件检测、驱动加载、OOM 杀进程、内核错误、网络接口 link up/down 等。所有"在内核里发生的事"都先到这里。

典型场景

  • pod 被 OOM 杀:dmesg -T | grep -i 'killed process'
  • 节点丢包:dmesg | grep -i 'drop\|congestion'
  • 网卡断开 / 链路 down:dmesg | grep -i 'link\|eth0'
  • 硬件错误:dmesg | grep -i 'mce\|hardware error'
  • 磁盘 I/O error:dmesg | grep -iE 'i/o|sector|sda'

dmesg vs journalctl -k 的关系

命令看什么
dmesg直接读内核环形缓冲(内存中、有限大小)
journalctl -k同样是内核日志,但由 journald 收集、持久化(如果配了)
journalctl --dmesg等价 journalctl -k

环形缓冲会覆盖——满了之后新消息冲掉旧的。机器重启后清空。

  • 现场调试 → dmesg(最快)
  • 回查历史 → journalctl -k --since yesterday(如果持久化了)

五个核心 flag

dmesg                              # 看全部
dmesg -T                           # 带可读时间戳(**必加**)
dmesg -w                           # 跟随(类似 tail -f)
dmesg -l err,warn                  # 按级别
dmesg --since "10 min ago"          # 按时间(新版 dmesg)
dmesg -c                           # 看完清空(小心,旧消息全没了)

-T —— 把秒数翻译成人类可读时间

不加 -T:

[12345.678901] kernel: ...

那个 12345.678901 是自系统启动以来的秒数。看不出来到底什么时候发生的。

加 -T:

[Mon May 27 14:30:00 2026] kernel: ...

永远加 -T。

Ubuntu 默认 dmesg 已经显示绝对时间(取决于内核 printk.time),但 CentOS 老系统不行。-T 永远保险。


级别

dmesg -l emerg              # 紧急
dmesg -l alert
dmesg -l crit
dmesg -l err                # 错误
dmesg -l warn               # 警告
dmesg -l notice
dmesg -l info
dmesg -l debug

dmesg -l err,warn           # 多个级别

排查"今天有什么内核错误":

dmesg -T -l err,warn | tail

或者:

dmesg -T --level=err,warn,crit --since "1 hour ago"

跟随 -w —— 实时看

dmesg -Tw
# 持续输出新内核消息,Ctrl-C 退出

排查"现在正在发生什么内核事件"。

类似 tail -f 但是是内核日志。


训练营典型场景

场景 1:pod 被 OOMKilled

kubectl get pod my-pod -o yaml | grep -A 5 lastState
# reason: OOMKilled                       ← 被 OOM 杀

# 节点上看 dmesg
ssh m4 'dmesg -T | grep -iE "oom|killed process" | tail -10'
# [Mon May 27 14:30:00 2026] kernel: out of memory: Kill process 12345 (myapp)
# [Mon May 27 14:30:00 2026] kernel: Killed process 12345 (myapp), UID 0,
#                                    total-vm:1024MB, anon-rss:512MB, file-rss:0MB

anon-rss 是真实占用——和 pod limit 比对。

场景 2:节点丢包 / 网络抖动

dmesg -T | grep -iE 'drop|congestion|conntrack|nf_conntrack'
# kernel: nf_conntrack: table full, dropping packet           ← conntrack 满
# kernel: nf_conntrack: nf_conntrack_buckets ...

修:

sysctl -w net.netfilter.nf_conntrack_max=1048576

场景 3:磁盘 I/O 错误

dmesg -T | grep -iE 'i/o error|sector|sda|nvme'
# kernel: I/O error, dev sda, sector 12345678
# kernel: end_request: I/O error, dev sda, sector 12345678

这是真硬件问题信号——盘要坏了。立刻:

  • 备份这台机器的数据
  • 联系 IDC / 云厂商换盘
  • K8s 节点 drain 这个节点

场景 4:内存压力

dmesg -T | grep -iE 'memory|allocation|reclaim'
# kernel: Memory cgroup out of memory: Killed process ...    ← cgroup OOM(容器超 limit)
# kernel: SLUB: Unable to allocate memory ...                ← 内核分配失败(严重)

场景 5:网卡 link 抖动

dmesg -T | grep -i 'eth0\|link'
# kernel: e1000e: eth0 NIC Link is Down
# kernel: e1000e: eth0 NIC Link is Up 1000 Mbps Full Duplex

网线 / 交换机 / 网卡硬件问题。

场景 6:内核 panic / crash

dmesg -T -l emerg,alert,crit
# 显示最严重的几个

如果有 Kernel panic 或 Oops,是内核 bug 或硬件问题。重启避免,保留 dmesg 输出 报内核 / 硬件厂商。

场景 7:容器运行时报错

dmesg -T | grep -iE 'cgroup|systemd-cgroup|runc|containerd'
# kernel: cgroup: ...

cgroup v1 / v2 配置错、systemd cgroup driver 和 containerd 不匹配等。


看完整原始内容

某些消息在 dmesg 里被换行 / 截断,看完整:

dmesg --raw                              # 原始格式
dmesg --kernel                           # 只内核消息(默认)
dmesg --userspace                        # 用户空间消息(罕见)

JSON 输出(脚本用):

dmesg -J | jq                            # JSON

dmesg -c —— 看完清空(小心)

dmesg -c > /tmp/dmesg-snapshot.txt
# 读出当前所有 + 清空环形缓冲

# 之后 dmesg 显示的都是清空之后的新消息
dmesg                                    # 只显示新的

需要 root。

用途:故障排查时先 snapshot 当前状态、然后清空、然后等待事件发生——更易抓"事件相关" 的消息。

生产环境少用 -c——清掉的内容如果没存就丢了。


看环形缓冲大小

dmesg | wc -l                            # 多少行
sysctl kernel.printk_ringbuffer_size      # 缓冲大小(字节)

默认 4 MB 左右。改大:

sysctl -w kernel.printk_ringbuffer_size=16777216  # 16 MB(要重新编译内核或 boot param,运行时通常无法改)

更实际:让 journald 持久化 内核日志,环形缓冲不够大也无所谓。


journalctl -k 等价用法

journalctl -k                            # 同 dmesg
journalctl -k -b                          # 本次启动
journalctl -k -b -1                       # 上一次启动(含重启前的)
journalctl -k --since today
journalctl -k -p err                      # 按级别
journalctl -k -g "oom"                    # grep 模式

journalctl -k -b -1 是 dmesg 做不到的——重启后 dmesg 没了,journalctl 还能看上次 boot 的内核日志(前提是 journald 持久化)。


实用的 grep 模板

# OOM
dmesg -T | grep -iE 'oom|killed process|out of memory'

# 网络
dmesg -T | grep -iE 'eth|link|drop|conntrack'

# 磁盘
dmesg -T | grep -iE 'i/o|sector|sd[a-z]|nvme|filesystem'

# K8s / 容器
dmesg -T | grep -iE 'cgroup|runc|container'

# 内存 / SLAB
dmesg -T | grep -iE 'memory|slab|reclaim'

# 安全 / 审计
dmesg -T | grep -iE 'denied|selinux|apparmor|audit'

# 防火墙 / netfilter
dmesg -T | grep -iE 'iptables|netfilter|firewall'

# 最近 1 小时所有 err / warn
dmesg -T --since "1 hour ago" -l err,warn

# 最近 10 行(最简便)
dmesg -T | tail

常见踩坑

坑 1:忘加 -T,看到诡异的秒数

[12345.678] kernel: ...

不是 unix timestamp。是开机后的秒数。算绝对时间要:

date -d "$(uptime -s) + 12345 seconds"

或者直接 dmesg -T。

坑 2:环形缓冲不够大、看不到老消息

dmesg -T | head
# [Mon May 27 13:00:00 2026] kernel: ...   ← 几小时前

机器跑久了 / 内核消息多,老的被覆盖。要看更老的:

journalctl -k --since "2026-05-26"

前提:journald 持久化。

坑 3:非 root 用户被拒

$ dmesg
dmesg: read kernel buffer failed: Operation not permitted

kernel.dmesg_restrict = 1 时(许多发行版默认开),非 root 不能读内核日志。

sudo dmesg
# 或者
sysctl -w kernel.dmesg_restrict=0     # 不推荐生产开

K8s 节点上加 CAP_SYSLOG 也能读:

securityContext:
  capabilities:
    add: ["SYSLOG"]

坑 4:在容器里跑 dmesg 看到的是节点的

kubectl exec my-pod -- dmesg

dmesg 看内核环形缓冲——这是全节点共享的,不是容器隔离的。容器里看到的是节点的内核日志。

这通常是好的——能看到节点级问题(如果 pod 有 SYSLOG 权限)。

坑 5:OOM 信息找不到

dmesg -T | grep -i oom
# 没结果

可能:

  • 进程是被 cgroup OOM(容器超 limit)而不是全局 OOM。grep 范围扩大:
    dmesg -T | grep -iE 'Memory cgroup|oom_reaper|invoked oom'
    
  • 时间太久、被覆盖。看 journalctl:
    journalctl -k --since yesterday | grep -i oom
    

坑 6:误以为 dmesg --since 老内核也支持

dmesg --since "1 hour ago"
# 老 util-linux:unrecognized option '--since'

--since 是 util-linux 2.30+。老系统用:

dmesg -T | awk -v t="$(date -d '1 hour ago' '+%s')" '...'
# 或者直接 journalctl -k --since "1 hour ago"

坑 7:journald 没持久化、重启后 dmesg 全没了

reboot
dmesg -T | head
# 重启之后的,老的全没了

journalctl -k -b -1
# No persistent journal was found.

预防:让 journald 持久化(journalctl.md):

mkdir -p /var/log/journal
systemctl restart systemd-journald

K8s 节点强烈建议这么做——不然故障重启后无从查证。

坑 8:dmesg 显示一堆 audit 噪音

某些 SELinux / AppArmor 系统会把所有 audit 日志塞 dmesg:

dmesg -T | wc -l
# 50000,但其中 49000 是 audit

过滤掉:

dmesg -T | grep -v 'audit:'
# 或者
dmesg -T --console-on               # 只看 console 级(去掉 audit / debug)

关联命令

  • journalctl —— -k 看持久化的内核日志
  • systemctl —— systemd-journald 服务管理
  • top —— 看到 wa / 高 CPU 后再 dmesg 验证
  • lsof —— dmesg 报 OOM 后看哪个进程占
  • mcelog —— Memory ECC error 详细日志
  • smartctl —— 看磁盘 SMART 信息(dmesg 报 sector error 后用)
在 GitHub 上编辑此页