一份网友的内核引导参数:我们逐条评估后的取舍

上一篇记的是运行期能改的 sysctl。这一篇是另一类东西:写在 GRUB 里、开机时传给内核的引导参数(kernel command line)。它们和 sysctl 有个本质区别——sysctl 改错了大不了回滚,引导参数改错可能直接让机器进不去系统,而且你在 SSH 上看不到任何报错,只能去 IPMI/串口控制台救。

这串参数不是我们原创,是在网上流传的一份"调优内核引导参数",有人直接整段贴进 GRUB_CMDLINE_LINUX 就重启了。我们把它完整留在这里,但要明确:这不是推荐配置,是一份我们拿来逐条审过的参考。里面有相当一部分我们在生产机上坚决不开,原因会在下面说清楚。按用途分组看,比当成一长串咒语照抄有用得多。

先给一条铁律:改引导参数之前,确保你有带外管理(IPMI/iDRAC/串口)能进 GRUB。没有带外、机器又在远端机房的,不要碰这些。

日志、审计与启动显示

参数作用
loglevel=3内核控制台打印级别设为 3,少刷屏。
rd.udev.log_priority=3initramfs 里 udev 的日志级别设为 3。
rd.systemd.show_status=auto启动时自动显示 systemd 状态。
log_buf_len=2M内核日志环形缓冲区设为 2M,排障时能留下更多历史。
audit=1启用内核审计子系统。

这组基本无害,是我们会保留的。唯一要注意 audit=1 在高并发系统调用的机器上有可感知的开销,如果没有合规需求可以关掉。

cgroup 与容器

参数作用
systemd.unified_cgroup_hierarchy=false关闭 cgroup v2 统一层级,退回 v1。
systemd.legacy_systemd_cgroup_controller=false关闭旧版 systemd cgroup 控制器。
cgroup_enable=memory启用 memory cgroup。
cgroup_memory=nokmem关闭 kmem 记账(历史上的内存泄漏规避手段)。
swapaccount=1启用 swap 记账,容器限制 swap 时需要。

这些决定了容器运行时拿到的 cgroup 版本。强行退回 cgroup v1 要谨慎:现在的容器运行时(containerd、podman 新版本)越来越以 v2 为主,退回 v1 可能让新版工具行为异常。我们的取舍是跟着实际跑的运行时版本走,而不是无脑退回 v1。

存储与 I/O

参数作用
scsi_mod.use_blk_mq=1启用块层多队列(blk-mq),对 NVMe/多队列 SSD 有意义。

我们的 NVMe/ZFS 机器上 blk-mq 是默认且想要的,这条可以留;在新内核上它基本已经是默认行为。

内存管理与大页

参数作用与风险
transparent_hugepage=never关闭透明大页(THP)。数据库、ZFS ARC 这类对内存延迟敏感的负载上,关 THP 通常是对的,能避免 THP 整理带来的延迟尖刺。这是少数我们明确推荐的。
cma=128M预留 128M 连续内存给 CMA。只有特定设备(某些 DMA)需要,没有对应硬件就是白占。
init_on_free=0、init_on_alloc=0关闭分配/释放时的内存清零。换一点性能,代价是牺牲了一层防信息泄露的加固——这是安全和性能的直接取舍。
vsyscall=none关闭老的 vsyscall 接口,收紧攻击面,现代系统上安全。

注意源里写的是 domain init_on_free=0, init_on_alloc=0,中间带了个 domain 和逗号,这其实是粘贴时混进来的噪声,真正的内核参数就是 init_on_free=0 和 init_on_alloc=0 两个,中间不该有逗号。照抄原样会让内核把 domain 当成一个无法识别的参数。

CPU 电源与频率(追求低延迟)

参数作用与风险
intel_pstate=disable禁用 intel_pstate 调频驱动。
processor.max_cstate=0 / intel_idle.max_cstate=0禁止 CPU 进入深度 C-state。
idle=halt空闲时用 halt 而非更省电的方式。
cpufreq.off=1关闭频率调节。
pcie_aspm=off关闭 PCIe 省电。
thermal.off=1关闭温控。

这一整组是典型的"用功耗换延迟":把 CPU 钉在高频、不让它睡,换取稳定的低延迟响应。在做实时转发、低延迟交易类负载时有意义。代价很直接:功耗和发热大幅上升,电费和机房散热都要跟上。而 thermal.off=1 要特别小心——关掉温控意味着过热时内核不再降频保护,硬件真有散热问题时可能直接烧,我们生产机上不开这一条。普通业务机完全不需要这组参数。

中断、锁与 RCU

参数作用与风险
threadirqs把硬中断处理放到内核线程里,便于调度和隔离。
nosoftlockup关闭软锁定检测。
nmi_watchdog=0关闭 NMI 看门狗,省一点每核开销。
rcu_nocbs=0-64把 CPU 0–64 的 RCU 回调卸载到别处,配合 CPU 隔离做低延迟。
rcupdate.rcu_expedited=1加速 RCU 宽限期,降延迟、略增 CPU 开销。
rcutree.kthread_prio=2提高 RCU 内核线程优先级。
skew_tick=1错开各核时钟中断,减少同时唤醒造成的抖动。
no_timer_check跳过定时器 IRQ 路由检查,省一点启动时间。
noreplace-smp关闭 SMP 相关的代码替换优化。

这组是给专门调过 CPU 隔离的低延迟机准备的,尤其 rcu_nocbs=0-64 只有在你真的做了 isolcpus/nohz_full 把这些核隔出来时才有意义,否则是空设。nosoftlockup+nmi_watchdog=0 则是又把上一篇里当安全网的检测关掉了——省了开销,也失去了发现卡死的手段,取舍要清楚。

虚拟化与 IOMMU

参数作用
intel_iommu=on / amd_iommu=on开启 IOMMU,做 PCI 直通(passthrough)的前提。
iommu.strict=0非严格模式,延迟 TLB 刷新换性能,代价是直通设备的隔离性略降。
kvm-intel.nested=1启用嵌套虚拟化。
kvm-intel.vmentry_l1d_flush=never关闭进 VM 时的 L1D 刷新——这是关掉 L1TF 的一个缓解,见下面安全一节。
pci=realloc允许重新分配 PCI 资源,解决某些设备 BAR 空间不够。

做 GPU/网卡直通时 intel_iommu=on 是必须的。iommu.strict=0 和各种 flush=never 都是用隔离性换性能,多租户环境要想清楚。

网卡命名

参数作用
net.ifnames=0关闭 systemd 的可预测网卡命名,网卡回到 eth0 这类传统名字。
biosdevname=0同样关闭 BIOS 风格命名。

这两条纯看运维习惯。好处是名字短、脚本好写;坏处是多网卡机器上传统命名顺序不稳定,插拔网卡后名字可能对调,自动化反而更容易踩坑。我们在网卡固定、靠 MAC 绑定的机器上才用。

显卡

参数作用与风险
nomodeset禁用内核模式设置(KMS)。
vt.cur_default=50设置虚拟终端光标。

nomodeset 要特别点名:它会禁掉内核显卡驱动的模式设置,对纯服务器可能无所谓,但在需要显卡驱动正常工作的机器(比如上一篇讲的 GPU 节点)上开 nomodeset,驱动会起不来。这类参数的"好坏"完全取决于机器角色,不能一概照抄。

安全缓解——风险最高的一组

mitigations=off noibrs nopti l1tf=off nospec_store_bypass_disable noibpb spectre_v2_user=off spectre_v2=off
参数作用
mitigations=off一次性关闭所有 CPU 漏洞缓解(这一条就等于下面全部)。
nopti关闭 KPTI(Meltdown 缓解)。
noibrs / noibpb / spectre_v2=off / spectre_v2_user=off关闭 Spectre v2 相关缓解。
l1tf=off关闭 L1TF(L1 终端失效)缓解。
nospec_store_bypass_disable关闭 SSB 缓解。

这是整串参数里我们最要给出警告的部分。 关掉这些缓解确实能拿回被 Meltdown/Spectre 一系列补丁吃掉的性能,在某些计算密集负载上收益可观。但代价是把机器暴露在已知的侧信道漏洞下。在多租户、跑别人代码、或任何不完全可信负载的机器上,绝对不能开——这相当于主动拆掉 CPU 的安全隔离。只有在物理隔离、单租户、确认负载完全可信、并且你确实量到性能瓶颈在这里的前提下,才可以考虑,而且要作为一个明确的风险决策记录下来,而不是随手贴进 GRUB。

其它

参数作用与风险
selinux=0关闭 SELinux。省心,但也去掉了一层强制访问控制。
mce=off关闭机器检查异常(MCE)。危险:MCE 是硬件报告内存/CPU 错误的机制,关掉它等于让你对正在发生的硬件故障视而不见,我们不开。
noresume禁用从休眠恢复,服务器本来也不休眠,无害。
workqueue.power_efficient=0关闭省电型工作队列,偏向性能。
cryptomgr.notests跳过启动时的加密算法自测,省一点启动时间。
nosync关闭相关忙等待行为。
nf_conntrack.acct=0关闭 conntrack 流量计数,省一点每连接开销——对上一篇那种几十万连接的机器有点意义。
crashkernel=384M-2G:64M,2G-:128M按物理内存大小给 kdump 预留崩溃内核内存。想要崩溃转储就保留。

完整参考(原样保留)

下面是源里的完整一行。再强调:这不是让你照抄的配置,是一份评估对象。mitigations=off 那组、mce=off、thermal.off=1、nomodeset 请根据机器角色明确决定,domain ... , 那处是粘贴噪声需要清掉。

loglevel=3 selinux=0 audit=1 rd.systemd.show_status=auto rd.udev.log_priority=3 systemd.unified_cgroup_hierarchy=false systemd.legacy_systemd_cgroup_controller=false scsi_mod.use_blk_mq=1 crashkernel=384M-2G:64M,2G-:128M workqueue.power_efficient=0 domain init_on_free=0, init_on_alloc=0 cma=128M vsyscall=none nosoftlockup mce=off threadirqs noresume nmi_watchdog=0 vt.cur_default=50 transparent_hugepage=never cgroup_enable=memory cgroup_memory=nokmem swapaccount=1 nf_conntrack.acct=0 log_buf_len=2M intel_pstate=disable processor.max_cstate=0 intel_idle.max_cstate=0 thermal.off=1 pci=realloc pcie_aspm=off cpufreq.off=1 idle=halt net.ifnames=0 biosdevname=0 mitigations=off noibrs nopti l1tf=off nomodeset nospec_store_bypass_disable noibpb spectre_v2_user=off spectre_v2=off kvm-intel.vmentry_l1d_flush=never no_timer_check noreplace-smp kvm-intel.nested=1 nosync iommu.strict=0 intel_iommu=on amd_iommu=on cryptomgr.notests rcu_nocbs=0-64 rcupdate.rcu_expedited=1 rcutree.kthread_prio=2 skew_tick=1

正确的做法是:挑出和你机器角色对得上的几条,一次只加一组,改完 grub2-mkconfig 后重启、从带外控制台确认能进系统、再验证关掉的东西没造成功能缺失。引导参数没有"抄一份万能配置"这回事——每台机器的角色不同,该开的和会要命的也不同。

Published At (Updated At) Tagged with