Lab / Monitoring

PVE 备份保留与监控采集

整理 PVE 自动/手动备份保留规则、温度采集、Prometheus/Grafana、Node Exporter textfile collector 和 LXC Docker 安装排查。

结论:PVE 自动备份任务的保留规则主要管理自动任务生成的备份;手动备份通常不会被自动保留规则清理。温度监控可以走两条路线:简单日志采集,或 Prometheus + Grafana。

手动备份与保留规则

PVE 的保留规则主要作用于自动备份任务生成的备份文件。手动点击备份或手动执行 vzdump 产生的备份,通常不会自动被保留规则清理。

如果希望手动备份也被统一管理,需要单独写清理脚本,按文件名、时间或目录规则处理。

备份相关命令

查看备份存放目录:

ls -lh /var/lib/vz/dump

手动备份常见命令:

vzdump <VMID> --storage local --mode snapshot --compress zstd

查看存储配置:

cat /etc/pve/storage.cfg

温度采集:lm-sensors

安装并检测传感器:

apt update
apt install -y lm-sensors
sensors-detect --auto
sensors

如果 cron 里找不到 sensors,先确认路径:

which sensors

例如输出 /usr/bin/sensors,脚本里就使用完整路径。

一次性温度采集脚本

保存为 /usr/local/bin/pve_sensors_once.sh

#!/bin/bash

LOGFILE="/var/log/pve_sensors.log"
SENSORS="/usr/bin/sensors"

TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
CPU_PACKAGE=$($SENSORS | awk '/Package id 0/ {print $4}')
CORE0=$($SENSORS | awk '/Core 0:/ {print $3}')
CORE1=$($SENSORS | awk '/Core 1:/ {print $3}')
CORE2=$($SENSORS | awk '/Core 2:/ {print $3}')
CORE3=$($SENSORS | awk '/Core 3:/ {print $3}')
NVME_TEMP=$($SENSORS | awk '/nvme-pci/,/Composite/ {if($1=="Composite:") print $2}')

echo "$TIMESTAMP CPU_Package=$CPU_PACKAGE Core0=$CORE0 Core1=$CORE1 Core2=$CORE2 Core3=$CORE3 NVMe=$NVME_TEMP" >> "$LOGFILE"

赋权:

chmod +x /usr/local/bin/pve_sensors_once.sh

手动测试:

/usr/local/bin/pve_sensors_once.sh
tail -n 10 /var/log/pve_sensors.log

Cron 定时采集

编辑 root 的定时任务:

crontab -e

每分钟执行一次:

* * * * * /usr/local/bin/pve_sensors_once.sh

查看任务:

crontab -l

查看 cron 是否触发:

grep CRON /var/log/syslog | tail -n 20

日志轮转

新建 /etc/logrotate.d/pve_sensors

/var/log/pve_sensors.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
    copytruncate
}

Prometheus + Grafana 方案

目录建议:

mkdir -p /opt/monitoring
cd /opt/monitoring

docker-compose.yml

services:
  prometheus:
    image: prom/prometheus
    container_name: prometheus
    restart: unless-stopped
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus

  grafana:
    image: grafana/grafana
    container_name: grafana
    restart: unless-stopped
    ports:
      - "3000:3000"
    volumes:
      - grafana_data:/var/lib/grafana

volumes:
  prometheus_data:
  grafana_data:

prometheus.yml

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: "node_exporter"
    static_configs:
      - targets: ["PVE_HOST_IP:9100"]

启动:

docker compose up -d

Grafana 数据源:

http://prometheus:9090

如果 Grafana 不在同一个 docker compose 网络里,使用:

http://PVE_HOST_IP:9090

Node Exporter 安装

下载并安装:

wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz
tar xvf node_exporter-1.8.2.linux-amd64.tar.gz
cd node_exporter-1.8.2.linux-amd64
cp node_exporter /usr/local/bin/

创建 textfile collector 目录:

mkdir -p /var/lib/node_exporter/textfile_collector

创建 /etc/systemd/system/node_exporter.service

[Unit]
Description=Node Exporter
After=network.target

[Service]
ExecStart=/usr/local/bin/node_exporter --collector.textfile.directory=/var/lib/node_exporter/textfile_collector
Restart=always
User=root

[Install]
WantedBy=multi-user.target

启用:

systemctl daemon-reload
systemctl enable --now node_exporter
systemctl status node_exporter

导出温度为 Prometheus 指标

创建 /usr/local/bin/export_sensors.sh

#!/bin/bash

OUTPUT="/var/lib/node_exporter/textfile_collector/sensors.prom"
SENSORS="/usr/bin/sensors"

CPU_PACKAGE=$($SENSORS | awk '/Package id 0/ {gsub(/[+°C]/,"",$4); print $4}')
CORE0=$($SENSORS | awk '/Core 0:/ {gsub(/[+°C]/,"",$3); print $3}')
CORE1=$($SENSORS | awk '/Core 1:/ {gsub(/[+°C]/,"",$3); print $3}')
CORE2=$($SENSORS | awk '/Core 2:/ {gsub(/[+°C]/,"",$3); print $3}')
CORE3=$($SENSORS | awk '/Core 3:/ {gsub(/[+°C]/,"",$3); print $3}')
NVME=$($SENSORS | awk '/nvme-pci/,/Composite/ {if($1=="Composite:") {gsub(/[+°C]/,"",$2); print $2}}')

cat > "$OUTPUT" <<EOF
# HELP pve_cpu_package_temperature_celsius PVE CPU package temperature.
# TYPE pve_cpu_package_temperature_celsius gauge
pve_cpu_package_temperature_celsius ${CPU_PACKAGE:-0}
# HELP pve_cpu_core_temperature_celsius PVE CPU core temperature.
# TYPE pve_cpu_core_temperature_celsius gauge
pve_cpu_core_temperature_celsius{core="0"} ${CORE0:-0}
pve_cpu_core_temperature_celsius{core="1"} ${CORE1:-0}
pve_cpu_core_temperature_celsius{core="2"} ${CORE2:-0}
pve_cpu_core_temperature_celsius{core="3"} ${CORE3:-0}
# HELP pve_nvme_temperature_celsius PVE NVMe temperature.
# TYPE pve_nvme_temperature_celsius gauge
pve_nvme_temperature_celsius ${NVME:-0}
EOF

赋权并测试:

chmod +x /usr/local/bin/export_sensors.sh
/usr/local/bin/export_sensors.sh
cat /var/lib/node_exporter/textfile_collector/sensors.prom

Cron 每分钟生成一次:

* * * * * /usr/local/bin/export_sensors.sh

Prometheus 里测试查询:

pve_cpu_package_temperature_celsius
pve_cpu_core_temperature_celsius
pve_nvme_temperature_celsius

Grafana 温度图表

在 Grafana 中:

  1. 添加 Prometheus 数据源。
  2. 新建 Dashboard。
  3. 添加 Time series 面板。
  4. 查询:
pve_cpu_package_temperature_celsius

CPU 核心温度:

pve_cpu_core_temperature_celsius

NVMe 温度:

pve_nvme_temperature_celsius

Node Exporter Full Dashboard 常用 ID 是 1860,但它默认不一定包含温度。温度通常需要用 textfile collector 自定义指标后手动加面板。

PVE LXC 安装 Docker

编辑容器配置:

nano /etc/pve/lxc/<CTID>.conf

添加或确认:

features: nesting=1,keyctl=1,mknod=1
lxc.apparmor.profile: unconfined
lxc.cap.drop:
lxc.cgroup2.devices.allow: a
lxc.mount.auto: proc:rw sys:rw

重启容器:

pct stop <CTID>
pct start <CTID>

进入容器:

pct enter <CTID>

安装 Docker 官方源:

apt update
apt install -y ca-certificates curl gnupg lsb-release
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
  $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl enable --now docker

测试:

docker run hello-world
docker compose version

查看已安装 Docker 组件:

apt list --installed | grep -E 'docker|containerd'

docker.io 是 Debian/Ubuntu 仓库里的 Docker 包,版本通常较旧;生产或长期使用优先选择 Docker 官方源的 docker-ce

常见排查

Prometheus 容器:

docker ps | grep prometheus
docker logs prometheus

配置变更后重启:

docker compose down
docker compose up -d

Prometheus 访问:

http://PVE_HOST_IP:9090

Grafana 访问:

http://PVE_HOST_IP:3000

如果 Grafana 没数据:

  • 检查数据源 URL 是否正确。
  • 检查 Prometheus targets 是否 UP。
  • 检查 prometheus.yml 是否挂载到容器内。
  • 检查防火墙和端口映射。