综合 systemd 259 之后 journal 默认写 /var/log/journal,networkd 的 iptables NAT 规则不再生成

2026-11-04 21:08:48

systemd v259 升级笔记:journal 默认持久化、iptables NAT 规则失效、大页计入内存上限

systemd v259 于 2025-12-17 发布,release notes 见 github.com/systemd/systemd/releases/tag/v259。下面三处默认行为变更在升级后会立刻反映到运行状态上;后面再补几个同版本值得跟进的接口变化和 v260 的移除预警。

1. journal 默认存储从 auto 改为 persistent

原来的默认值是 auto:在没有覆盖配置时,journald 看 /var/log/journal 目录是否存在来决定日志存到哪里——目录在就持久化,不在就走运行时/易失存储。v259 把默认值改成 persistent,不再依赖目录探测。编译期可以用 -Djournal-storage-default= 改这个默认值:

meson setup build -Djournal-storage-default=auto

升级后先确认当前实际生效的值,以及日志落盘位置:

grep -E '^\s*Storage=' /etc/systemd/journald.conf /etc/systemd/journald.conf.d/*.conf
ls -ld /var/log/journal
journalctl --disk-usage

三种环境需要提前看:

  • 只读根文件系统:持久化路径 /var/log/journal 在只读根上不可写,journald 无法按持久化方式落盘,需要显式设置 Storage=(如 volatile)或把 /var/log/journal 挂到可写卷上。
  • 容器:日志会写进容器的可写层,随容器销毁一起丢失,同时持续占用可写层容量;镜像里若残留 /var/log/journal 目录,行为也会跟着变。
  • 小磁盘:默认持久化意味着日志长期留在磁盘上,容量受 journald.conf 的 SystemMaxUse 一类策略约束,盘小的机器要显式收紧上限或定期 journalctl --vacuum-size=。

2. networkd 与 nspawn 只走 nftables,原 iptables NAT 规则不再被创建

systemd-networkd 与 systemd-nspawn 不再支持通过 iptables/libiptc API 创建 NAT 规则,只支持 nftables。升级后表现为:依赖这两个组件做地址转换的配置(networkd 的 IPMasquerade、nspawn 的网络端口映射等)不再在 iptables 的 nat 表里出现规则,原有围绕 iptables -t nat 写的检查脚本、审计和清理逻辑会全部落空。

升级前后对比一下两套规则集:

# 升级后应能在 nftables 侧看到规则
nft list ruleset
nft list tables

# 升级前由 libiptc 写下的规则,升级后不会再有新增
iptables -t nat -S

如果宿主机上还有其它组件依赖 iptables 后端兼容层,需要自行确认 nftables 路径已经生效,并把 NAT 相关的排查手段切到 nft。

3. cgroup2 挂上 memory_hugetlb_accounting,大页计入内存上限

cgroup2 文件系统现在以 memory_hugetlb_accounting 挂载选项挂载(内核 6.6 起支持)。含义是 HugeTLB 的内存用量会计入该 cgroup 的整体内存用量(memory controller)。

影响集中在事先预留大页的服务上:过去大页用量不计入 cgroup 内存账,memory.max 看起来还有余量;升级后这部分被算进来,原本刚好卡在上限附近的服务可能直接被 OOM。升级后先确认挂载选项:

findmnt -no OPTIONS /sys/fs/cgroup
grep hugetlb /proc/mounts

再核对关键 unit 的内存水位与上限:

systemctl show -p MemoryCurrent -p MemoryMax -p MemoryHigh
cat /sys/fs/cgroup/$(systemctl show -p ControlGroup --value )/memory.current

对预留大页的服务,需要重新评估 MemoryMax=/MemoryHigh= 的取值,或者把大页用量纳入容量规划。

4. OOMKills 属性与 run0 --empower

OOMKills / ManagedOOMKills。 服务管理器新增 D-Bus 属性 OOMKills 与 ManagedOOMKills,分别统计被内核或 systemd-oomd 杀掉的进程数,适用于会拉起进程的 unit 类型。可以直接从 manager 或 unit 上读:

busctl get-property org.freedesktop.systemd1 /org/freedesktop/systemd1 \
org.freedesktop.systemd1.Manager OOMKills
systemctl show -p OOMKills -p ManagedOOMKills

run0 --empower。 run0 新增 --empower:以提权会话运行但不切换成 root 用户,设置完整 ambient capabilities 掩码(含 CAP_SYS_ADMIN),并把会话进程加入新的 empower 系统组(由 polkit 认可)。好处是 $HOME 和 UID 不变,不会在用户家目录里留下 root 属主的文件。

run0 --empower id
run0 --empower -- capsh --print

注意很多程序仍只看 UID 做访问检查,--empower 不保证在所有场景生效。

5. dlopen 弱依赖与 systemd-analyze dlopen-metadata

共享库依赖里,Linux audit、PAM(pam_systemd 等需 PAM 加载的模块除外)、libacl、libblkid、libseccomp、libselinux、libmount 都改为 dlopen() 加载,属于弱依赖,目的之一是缩小容器里的体积。

副作用是 ldd 看不到这些库,排查运行期缺库时要换工具。systemd-analyze 新增 dlopen-metadata filename 子命令,列出通过 dlopen 访问的库:

systemd-analyze dlopen-metadata /usr/lib/systemd/systemd
ldd /usr/lib/systemd/systemd | grep -E 'pam|audit|acl|blkid|seccomp|selinux|mount'

对裁剪过的镜像,这意味着 audit、PAM、SELinux 等能力缺失时进程仍能启动,只在具体功能被调用时失败,验证要覆盖到实际使用路径。

6. v260 移除预警:SysV 脚本与最低依赖

SysV 服务脚本支持在 v259 弃用,v260 移除,涉及 systemd-rc-local-generator、systemd-sysv-generator、systemd-sysv-install(即 systemctl enable/disable/is-enabled 的 hook)。升级到 v259 后就该盘点:

ls /etc/init.d/
ls /run/systemd/generator/*.service 2>/dev/null

v260 还计划抬高最低依赖版本:内核 >= 5.10(建议 >= 5.14)、glibc >= 2.34、libxcrypt >= 4.4.0、util-linux >= 2.37、elfutils >= 0.177、openssl >= 3.0.0、cryptsetup >= 2.4.0、libseccomp >= 2.4.0、python >= 3.9。

另外 v260 会改 RootImageOptions= 与 ExtensionImages=/MountImages= 的挂载参数解析:同一分区的重复定义从「第一个生效」改为「最后一个生效」,与其它 unit 设置的惯例一致。

7. 其它同版本变更

  • systemd-boot 与 systemd-stub 移除 TPM 1.2 支持,只保留 TPM 2.0。
  • systemd-repart 设置的 LUKS 卷标不再默认与分区/文件系统标签字面相同,而是加 luks- 前缀,用于消除 /dev/disk/by-label/ 符号链接冲突;新增 VolumeLabel= 可显式指定 LUKS 超级块标签,也能显式恢复旧命名。
  • 新增 ExecReloadPost=,在 reload 完成后执行命令。
  • 新增 UserNamespacePath=,对应已有的 IPCNamespacePath= / NetworkNamespacePath=,作用于用户命名空间。
  • $LISTEN_FDS 协议扩展:新增 $LISTEN_PIDFDID 环境变量,包含 pidfd 的 inode ID,解决 PID 回收带来的歧义。
  • 服务退出时的日志现在同时显示 wallclock 时间与原来的 CPU 时间。
  • 服务管理器的 Varlink IPC 扩展较多,新增 Unit.List() 按 cgroup 或 invocation ID 过滤,以及 Reload()、Reexecute() 调用。
  • systemd-modules-load 改为并行加载配置的内核模块。
  • systemd-udevd 规则支持 OPTIONS="dump-json";udevd 与 repart 改用 BLKPG ioctl 增量重读分区表,不再用 BLKREMOVES 清理全部内存分区对象的 BLKRRPART。
  • 实验性支持用 musl libc 编译 systemd,最大限制是缺 NSS(域名、用户名、组名解析),大量基础设施会缺失或半残。
复制全文 生成海报 systemd 运维 Linux journald

推荐文章

程序员茄子在线接单