Homelab 过热?给 Proxmox Debian 宿主机降温的完整实战
目录
我的 Homelab 跑在一台迷你主机上:AMD Ryzen 5 5600H(6 核 12 线程,笔记本 U),上面装的是 Proxmox VE,里面只开了一台 K3s 虚拟机。最近摸机箱的时候明显感觉烫手,一查 CPU 温度常驻 72°C,决定好好优化一下。
现状诊断#
先 SSH 上去摸底。我的 Proxmox 宿主机在 Ansible inventory 里已经配好了,直接用 ad-hoc 命令采集信息:
ansible proxmox -m shell -a 'lscpu | grep "Model name"; sensors; free -h; qm list'
诊断结果比我预想得更激进一些:
| 项目 | 现状 | 问题 |
|---|---|---|
| CPU Governor | powersave |
已经是省电模式,没问题 |
| Turbo Boost | 开启 | CPU 频率飙到 3GHz+,主要热源 |
| 内存 | 13GB 物理 / VM 分配 15GB | 严重超售,swap 占了 3.9GB |
| KSM (ksmd) | 默认 20ms 扫描间隔,占 5% CPU | 因为内存超售疯狂做内存去重 |
| ASPM | default |
PCIe 链路没有启用最省电模式 |
| lm-sensors | 未安装 | 之前甚至没法看温度 |
三个主要热源很清晰:Turbo Boost 没关、VM 内存超售导致 swap 和 KSM 双重 CPU 开销、powertop 没做自动调优。
优化方案#
1. 减少 VM 内存分配(效果最大)#
对我这台机器来说,这是效果最明显的一步。宿主机只有 13GB 物理内存,VM 却分了 15GB,导致:
- 3.9GB 数据被挤到 swap,磁盘 I/O 增加
- KSM 以 20ms 间隔疯狂扫描内存页做去重,吃掉 5% CPU
- 整体负载 1.71(12 线程的机器不该有这种空载负载)
解决方法:把 VM 内存从 15GB 降到 10GB,给宿主机留 3GB 余量。
Proxmox 不支持在线缩内存(balloon 值为 0),所以需要关机改配置:
# 关机(ACPI shutdown 如果超时就 force stop)
qm shutdown 100
# 如果等不到就强制关
qm stop 100
# 改内存
qm set 100 --memory 10240
# 启动
qm start 100
如果 VM 是用 Terraform 管理的,记得同步更新 terraform.tfvars:
vm_memory = 10240 # 10GB (host has 13GB, avoid swap/KSM overhead)
注意:不要用
terraform apply来改内存,Terraform 会销毁重建 VM,数据会丢。用qm set原地改更安全。
2. 禁用 Turbo Boost#
AMD Ryzen 5 5600H 的 Turbo 最高能到 4.28GHz,但我这个 Homelab 场景未必需要这种瞬时爆发。关掉以后 CPU 频率上限降到基频,通常很快就能看到温度变化。
立即生效:
echo 0 > /sys/devices/system/cpu/cpufreq/boost
持久化(创建 systemd service):
# /etc/systemd/system/disable-turbo-boost.service
[Unit]
Description=Disable CPU Turbo Boost
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo 0 > /sys/devices/system/cpu/cpufreq/boost'
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
systemctl enable disable-turbo-boost
3. powertop 自动调优#
powertop 能自动把 USB 自动挂起、SATA 链路省电、音频节能等一堆细项全部打开:
# 先看效果
powertop --auto-tune
# 满意了就持久化
cat > /etc/systemd/system/powertop-autotune.service << 'EOF'
[Unit]
Description=PowerTOP auto-tune
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/usr/sbin/powertop --auto-tune
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
systemctl enable --now powertop-autotune
4. 降低 KSM 扫描频率#
即使减了 VM 内存,Proxmox 默认还是会跑 KSM。把扫描间隔从 20ms 调到 200ms,CPU 开销通常也会明显下降:
echo 200 > /sys/kernel/mm/ksm/sleep_millisecs
同样用 systemd service 持久化:
# /etc/systemd/system/ksm-tuning.service
[Unit]
Description=Tune KSM sleep interval
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo 200 > /sys/kernel/mm/ksm/sleep_millisecs'
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
5. PCIe ASPM 省电(可选)#
在 /etc/default/grub 里加入内核参数:
GRUB_CMDLINE_LINUX_DEFAULT="quiet pcie_aspm=powersupersave"
然后 update-grub && reboot。
实测:我的 AMD 平台 BIOS 锁定了 ASPM 策略,内核参数传入了但 sysfs 里仍然显示
[default]。如果你的机器也这样,说明要去 BIOS 里改,或者直接跳过这步。
Ansible Playbook 一键搞定#
上面这些手动操作太零散了,我写了一个 Ansible playbook 把所有优化一步到位:
---
- name: Power & thermal optimization
hosts: proxmox
tasks:
- name: Install lm-sensors
apt:
name: lm-sensors
state: present
update_cache: true
- name: Read current temperatures
command: sensors
register: sensors_before
changed_when: false
- name: Show baseline temperatures
debug:
var: sensors_before.stdout_lines
- name: Disable AMD Turbo Boost
shell: echo 0 > /sys/devices/system/cpu/cpufreq/boost
- name: Persist turbo boost disable
copy:
dest: /etc/systemd/system/disable-turbo-boost.service
content: |
[Unit]
Description=Disable CPU Turbo Boost
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo 0 > /sys/devices/system/cpu/cpufreq/boost'
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
- name: Enable disable-turbo-boost service
systemd:
name: disable-turbo-boost
enabled: true
daemon_reload: true
- name: Create powertop auto-tune service
copy:
dest: /etc/systemd/system/powertop-autotune.service
content: |
[Unit]
Description=PowerTOP auto-tune
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/usr/sbin/powertop --auto-tune
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
- name: Enable and start powertop auto-tune
systemd:
name: powertop-autotune
enabled: true
state: started
daemon_reload: true
- name: Slow down KSM scanning
shell: echo 200 > /sys/kernel/mm/ksm/sleep_millisecs
- name: Persist KSM tuning
copy:
dest: /etc/systemd/system/ksm-tuning.service
content: |
[Unit]
Description=Tune KSM sleep interval
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo 200 > /sys/kernel/mm/ksm/sleep_millisecs'
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
- name: Enable KSM tuning service
systemd:
name: ksm-tuning
enabled: true
daemon_reload: true
- name: Set ASPM to powersupersave in GRUB
lineinfile:
path: /etc/default/grub
regexp: '^GRUB_CMDLINE_LINUX_DEFAULT='
line: 'GRUB_CMDLINE_LINUX_DEFAULT="quiet pcie_aspm=powersupersave"'
backup: true
register: grub_updated
- name: Update GRUB
command: update-grub
when: grub_updated.changed
- name: Read temperatures after optimization
command: sensors
register: sensors_after
changed_when: false
- name: Show results
debug:
var: sensors_after.stdout_lines
跑一下:
ansible-playbook playbooks/power-optimize.yaml
踩坑提醒:sysfs 文件(
/sys/devices/...)不能用 Ansible 的copy模块写入,会报 Permission denied,因为copy会先写临时文件再 rename,但 sysfs 不支持这种操作。必须用shell模块直接echo写入。
效果#
优化前后对比(负载稳定后测量):
| 指标 | 优化前 | 优化后 | 改善 |
|---|---|---|---|
| CPU 温度 (Tctl) | 71.9°C | 62°C | -10°C |
| GPU 温度 (edge) | 65.0°C | 61°C | -4°C |
| NVMe 温度 | 46.9°C | 42.9°C | -4°C |
| 系统负载 | 1.71 | 0.43 | -75% |
| 可用内存 | 837MB | 3.2GB | +4x |
| Swap 使用 | 3.9GB | 0B | -100% |
最大的收益来自两个地方:
- VM 内存从 15GB 降到 10GB — 消除了 swap 和 KSM 的双重 CPU 开销,负载直接砍了 75%
- 禁用 Turbo Boost — CPU 频率上限降下来,温度立即下降 5-6°C
截至目前,K3s 集群在 10GB 内存下运行正常,跑了十几个服务也没遇到 OOM。回头看,之前 15GB 更像是拍脑袋给的保守值。
总结#
这次 Homelab 散热优化中,我最后采用的处理顺序如下:
- 先查内存是否超售 — 这是比较容易被忽视但影响很大的一步。VM 分配超过物理内存 → swap → KSM → CPU 白干活 → 发热
- 关 Turbo Boost — 服务器场景不需要睿频,关了直接降 5°C+
- powertop –auto-tune — 一键开启几十项细碎的省电选项
- KSM 扫描频率 — 如果还在跑 KSM,把间隔调大
- ASPM — 看 BIOS 是否支持,不支持就跳过
全部操作用 Ansible 管理,可重复执行,重启后自动生效。