PVE运维记录
换源(PVE 8.x)
首先更新证书:
sudo apt install apt-transport-https ca-certificates
接着就可以修改 Debian 源和 PVE 软件源了:
curl -fsSL https://mirrors.ustc.edu.cn/repogen/conf/debian-https-4-bookworm -o /etc/apt/sources.list
echo "deb https://mirrors.ustc.edu.cn/proxmox/debian bookworm pve-no-subscription" > /etc/apt/sources.list.d/pve-enterprise.list
echo "deb https://mirrors.ustc.edu.cn/proxmox/debian/ceph-quincy bookworm no-subscription" > /etc/apt/sources.list.d/ceph.list
wget https://mirrors.ustc.edu.cn/proxmox/debian/proxmox-release-bookworm.gpg -O /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg
apt update
最后修改 CT Templates 源(需要重启服务):
sed -i 's|http://download.proxmox.com|https://mirrors.ustc.edu.cn/proxmox|g' /usr/share/perl5/PVE/APLInfo.pm
systemctl restart pvedaemon.service
时间同步(NTP)
cat >> /etc/chrony/chrony.conf <<'EOF_INNER'
# Aliyun NTP
server ntp1.aliyun.com minpoll 4 maxpoll 10 iburst
server ntp2.aliyun.com minpoll 4 maxpoll 10 iburst
server ntp3.aliyun.com minpoll 4 maxpoll 10 iburst
server ntp4.aliyun.com minpoll 4 maxpoll 10 iburst
server ntp5.aliyun.com minpoll 4 maxpoll 10 iburst
server ntp6.aliyun.com minpoll 4 maxpoll 10 iburst
server ntp7.aliyun.com minpoll 4 maxpoll 10 iburst
EOF_INNER
systemctl restart chrony
chronyc sources -v
解决 unsupported Ubuntu version ‘24.04’ / ‘24.10’ / ‘25.04’
首先修改 /usr/share/perl5/PVE/LXC/Setup/Ubuntu.pm:
my $known_versions = {
+ '25.04' => 1, # plucky
+ '24.10' => 1, # oracular
+ '24.04' => 1, # noble
'23.10' => 1, # mantic
'23.04' => 1, # lunar
然后在母鸡的 Shell 中执行:
pveam available
pveam update
接着在母鸡的磁盘 -> CT 模板 -> 模板中选择下载 Ubuntu_24.04,接着再次执行 pveam available 即可。
合并命令:
grep -q "25.04" /usr/share/perl5/PVE/LXC/Setup/Ubuntu.pm || sed -i "/'23.10'/i\ '25.04' => 1, # plucky\n '24.10' => 1, # oracular\n '24.04' => 1, # noble" /usr/share/perl5/PVE/LXC/Setup/Ubuntu.pm
pveam available
pveam update
解决 CT 容器内无法使用 tun 网卡
编辑 /etc/pve/lxc/<CT_ID>.conf,在最后加入:
lxc.cgroup.devices.allow: a
lxc.cap.drop:
lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
批量添加:
for f in /etc/pve/lxc/*.conf; do
grep -q "lxc.mount.entry: /dev/net/tun" "$f" || cat <<'EOF' >> "$f"
lxc.cgroup.devices.allow: a
lxc.cap.drop:
lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
EOF
done
删除克隆任务提示 TASK ERROR: VM is locked (clone)
在 PVE 中,Full Clone 克隆 VM 模板或者克隆普通 VM 一般要比 Linked Clone 模板要慢,也更容易在克隆硬盘时卡住,因此优先使用 Linked Clone
假如克隆已经卡住,停止后尝试删除 VM 则会提示“TASK ERROR: VM is locked (clone)”,此时需要进入母鸡 Shell 使用 qm unlock <CT_ID> 来解锁容器,再在 UI 控制台中操作删除
缩小 CT 容器磁盘空间
首先关闭 CT 容器,接着定位到磁盘存储位置,其中 PVE 母鸡中的在 /dev/pve/ 下,NFS 挂载存储中的在 /mnt/pve/<storage_name>/images/<CT_ID>/ 下
接着执行下面的命令检查并调整磁盘空间:
e2fsck -fy ./vm-<CT_ID>-disk-0*
resize2fs ./vm-<CT_ID>-disk-0* <size>G
接着缩小文件系统占用空间:
如果磁盘是 PVE 母鸡中的,那么执行:
lvreduce -L <size>G ./vm-<CT_ID>-disk-0*
如果是 NFS 挂载存储中的,那么执行:
qemu-img resize --shrink ./vm-<CT_ID>-disk-0* <size>G
最后修改配置文件 /etc/pve/lxc/<CT_ID>.conf:
- rootfs: <storage_name>:vm-<CT_ID>-disk-0*,size=<old_size>G
+ rootfs: <storage_name>:vm-<CT_ID>-disk-0*,size=<size>G
最后重启 CT 容器,修改完成~
使用模板批量克隆创建 CT 容器
#!/bin/bash
# ========================
# 配置
# ========================
TEMPLATE=1252 # LXC 模板ID
nodes=(pve1 pve2 pve3 pve4) # 节点列表,一空格分隔
ct_per_node=5 # 每个节点创建的容器数量
hostname_prefix="CT" # hostname 前缀,例如 CT.xxx
hostname_start=201 # hostname 起始尾号
ip_prefix="172.16.1" # IP 前缀,例如 172.16.1.xxx
ip_start=201 # IP 起始尾号
ip_netmask="/16" # 子网掩码
gateway="172.16.1.1" # 网关
vmid=$((hostname_start)) # VMID起点默认和hostname_start一致,可单独调整
# ========================
# 执行克隆与配置
# ========================
for node in "${nodes[@]}"; do
for i in $(seq 0 $((ct_per_node - 1))); do
cur_vmid=$((vmid + i))
cur_ip="${ip_prefix}.$((ip_start + i))${ip_netmask}"
cur_hostname="${hostname_prefix}.$((hostname_start + i))"
echo "=== Creating CT $cur_vmid on $node ==="
echo "Hostname: $cur_hostname"
echo "IP: $cur_ip"
# full clone 到目标节点
pct clone $TEMPLATE $cur_vmid \
--full 1 \
--target $node \
--hostname $cur_hostname
# 使用 pvesh 修改网络和hostname(支持跨节点)
pvesh set /nodes/$node/lxc/$cur_vmid/config \
--net0 name=eth0,bridge=vmbr0,firewall=1,gw=$gateway,ip=$cur_ip,type=veth \
--hostname $cur_hostname
# 启动容器
pvesh create /nodes/$node/lxc/$cur_vmid/status/start
done
# 每个节点结束后更新 VMID / IP / hostname 起点
vmid=$((vmid + ct_per_node))
hostname_start=$((hostname_start + ct_per_node))
ip_start=$((ip_start + ct_per_node))
done
母鸡挂载 VM 磁盘
有些时候(比如忘记了虚拟机密码)需要将虚拟机磁盘挂载到母鸡,以便查看和修改其中的文件。首先需要查看虚拟机的存储类型:
qm config <VMID>
若看到类似 scsi0: local-lvm:vm-<VMID>-disk-0,size=<SIZE>G 则说明该虚拟机的磁盘类型为 LVM,位于 local-lvm 中的逻辑卷路径一般为 /dev/pve/vm-<VMID>-disk-0(可以使用 lvs 确认),然后扫描分区:
fdisk -l /dev/pve/vm-<VMID>-disk-0
对于 Linux,输出一般为:
Disk /dev/pve/vm--disk-0: GiB, bytes, sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 65536 bytes / 65536 bytes
Disklabel type: gpt
Disk identifier:
Device Start End Sectors Size Type
/dev/pve/vm--disk-0p1 2048 4095 2048 1M BIOS boot
/dev/pve/vm--disk-0p2 4096 G Linux filesystem
我们需要挂载的是较大的 /dev/pve/vm-<VMID>-disk-0p2 分区,但直接使用 mount 挂载会发现找不到,这是因为对于PVE 的 VM 磁盘,类型通常是 LVM thin volume,因此内核不会自动生成子设备。
此时可以使用 kpartx 来映射分区:
apt update
apt install kpartx -y
kpartx -av /dev/pve/vm-<VMID>-disk-0
然后会输出:
add map pve-vm----disk--0p1 (253:32): 0 2048 linear 253:12 2048
add map pve-vm----disk--0p2 (253:35): 0 linear 253:12 4096
现在子设备成功生成,现在即可挂载数据分区:
mkdir -p /mnt/<VMID>
mount /dev/mapper/pve-vm--<VMID>--disk--0p2 /mnt/<VMID>
然后就可以在 /mnt/<VMID>/ 下查看虚拟机磁盘中的文件了。
卸载与清理:
umount /mnt/<VMID>
kpartx -d /dev/pve/vm-<VMID>-disk-0
rm -r /mnt/<VMID>
参考链接: