Lazy loaded image
Proxmox VE 虚拟机使用
Words 3551Read Time 9 min
2025-9-29
2025-11-10
date
related_level
slug
pve_vm
type
Post
relate_date
summary
PVE 虚拟机优化, 系统安装及高级配置
status
Published
tags
proxmoxve
虚拟化
实用教程
最新推荐
必看精选
category
运维管理
last_updated
Nov 10, 2025 10:03 PM
是否已更新
orginal_page
是否推荐
 
  • iso 镜像物理存储位置 /var/lib/vz/template/iso
 

PVE 虚拟机优化

PVE 一键优化脚本
虚拟机开启 xterm.js 以便复制粘贴指令
  • 参考资料
    • https://www.stephenwxf.com/post/180.html
  • 宿主机为对应虚拟机设置串行端口
    • qm set 116 -serial0 socket
      • 假设要给 id 为 116 的虚拟机进行设置
  • 重启虚拟机查看是否已开启串行端口 tty
    • dmesg | grep ttyS
  • 修改并更新 grub
    • nano /etc/default/grub
      • GRUB_CMDLINE_LINUX="quiet console=tty0 console=ttyS0,115200"
        • 对应行添加 console=tty0 console=ttyS0,115200 这部分内容
    • update-grub
  • 添加以下 ttyS 启动脚本
    • nano /etc/init.d/ttyS0
    • 重启虚拟机即可生效,在 web 端控制台可选 xterm.js
    虚拟机启用 SPICE
    • VM 硬件中修改显示为 SPICE
    使用 VirtIO 驱动提高性能
    • 允许虚拟机直接(半虚拟化)访问设备和外围设备,而不是速度较慢的模拟设备和外围设备
    iso 未签名,无法使用 SecureBoot 启动
     

    PVE 虚拟机系统安装

    PVE 虚拟机安装 iStoresOS
    写入固件至虚拟机
    • 上传工具及固件至 pve 宿主机
      • sftp root@<pve-ip>
      • cd /var/tmp
      • put <filepath>
    如果需要扩容可以参考以下方法
    • 解压 .img.gz 镜像包 gzip -kd <img_filename>.img.gz
    • 往镜像写入0数据并对新增内容进行重新分区
      • dd if=/dev/zero bs=1G count=4 >> <img_filename>.img
        • 这里为扩容 4 GiB
        • 内存容量不足的话可以到其他文件夹进行处理
      • 对镜像进行重新分区
        • parted <img_filename>.img
          • 查看分区情况 print
            • 如果 GPT 表异常且报错未使用全部空间,选 OK 然后 Fix 再执行后续重新分区
          • resizepart <num> 100%
            • 这里的分区编号根据主要分区来,efi 包一般为 3,其余一般为 2
          • 再次查看分区情况 print
          • quit
    • 删除原压缩包并重新打包镜像 rm <img_filename>.img.gz && gzip <img_filename>.img
    • 安装镜像会同步变大,写入时间会变长
    写入固件至对应虚拟机
    • chmod 777 /var/tmp/img2kvm
      • 修改为可执行
    • /var/tmp/img2kvm /var/tmp/<iso-name> <vm-id>
      • <iso-name> 为对应固件
      • <vm-id> 为虚拟机 ID
    • 在虚拟机→硬件页面编辑新增的未添加硬盘并确认即可
    • 在虚拟机→选项页面编辑引导顺序,把刚才添加的硬盘调到前面,启动即可
      • 如果是 EFI 固件记得删掉 EFI 启动盘
    PVE 虚拟机安装 Win 10 并输出至显示器
    • 编辑虚拟机配置
      • nano /etc/pve/qemu-server/<vmid>.conf
    • 查看虚拟机配置
      • qm showcmd <vmid> --pretty
    • args: -device vfio-pci,host=00:02.0,addr=0x18,x-vga=on,x-igd-opregion=on
      • 核显
    • args: -device vfio-pci,host=01:00.0,addr=0x18,x-vga=on,x-igd-opregion=on
      • 核显
    PVE 虚拟机安装 TrueNAS SCALE
    • 创建虚拟机
      • 镜像选择 TrueNAS-SCALE-23.10.2
      • 开启 QEMU 代理
      • 系统盘给 80 GB,开启 SSD 仿真
      • CPU 4 核,内存 10 GB
      • 后续直通添加 SATA 硬盘和网卡;另外根据需要添加 SSD 缓存盘加快读取速度
    • 选择创建的虚拟机,添加剩余设备
      • 在硬件页面添加 PCI 直通设备和其他需要设备
        • 如 X540-AT2 直通网卡只需选择对应标识符
          • 勾选所有功能可以保证独占双网口
      • 参考 PVE 设备虚拟化的 SATA 硬盘直通进行设置
    • 启动,按照安装流程完成安装后关机,移除引导盘后重新启动
      • 安装过程中可以设置登录用户账户及密码,默认为 admin,可选 root(不推荐)
    • 等待启动完毕至显示 web 管理地址,在别的电脑上登录该地址,输入此前选择的账号密码进行登录即可完成
     

    PVE LXC 高级配置与迁移实践

    通过备份在不同主机上迁移或复制 LXC
    • 在源主机上备份 LXC
      • 备份文件压缩方式,根据需求选取
      • 备份文件存放路径
        • ls -al /var/lib/vz/dump
    • 传输备份文件至目标主机
      • scp -r /var/lib/vz/dump/<backup> root@<target_host>:/var/lib/vz/dump/
    • 在目标主机的存储中选择对应备份进行还原即可
    LXC 每次启动会重置部分配置
    • 可以通过添加 .pve-ignore. 来阻止覆盖
      • touch /etc/.pve-ignore.hosts
        • 防止每次重启后修改 hosts
      • touch /etc/network/.pve-ignore.interfaces
        • 防止每次重启后修改网络
    • 也可以将 ostype 设为 unmanaged 来完全防止修改
    LXC 通用设置
    特权容器可能会出现命名空间问题
    • 如 systemd-logind 报错 Failed to set up mount namespacing: Permission denied
      • vim /lib/systemd/system/systemd-logind.service
        • 设置 ProtectControlGroups=no
    • 通用解决方案:特权容器设置嵌套
      • 注意,具有嵌套的特权容器几乎和宿主机互通,存在安全风险
      • 在 PVE 宿主机上修改容器配置
        • vim /etc/pve/lxc/<CTID>.conf
        • features 项添加 nesting=1
          • features: ...,nesting=1
          • features: nesting=1
            • 如果没有其他已配置 features 项则直接新增一行
    • 容器网络设置
      • debian/ubuntu 系一般采用 /etc/netplan,但容器模板采用 /etc/systemd/network 进行配置
    LXC 容器服务 systemd-networkd-wait-online 异常
    • LXC debian 容器默认使用 ifupdown 而非 system-networkd 管理网络
      • networkctl list
        • configured 表示该接口当前由 systemd-networkd 管理
      • systemctl list-units | grep -e network -e ifupdown
      • systemctl status systemd-networkd-wait-online
      • systemctl status ifupdown-wait-online
    • 已知会影响 apt-daily-upgrade, apt-daily 服务
      • systemctl list-units | grep -e apt-daily
      • systemctl status apt-daily apt-daily-upgrade
      • journalctl -u apt-daily | tail -n 20
        • 报错如下:
          • Sub-process /lib/systemd/systemd-networkd-wait-online returned an error code (1)
    • 安装 ifupdown2 并禁用相关服务
      • systemctl stop systemd-networkd.socket
      • systemctl disable --now systemd-networkd.service systemd-networkd-wait-online.service ifupdown-wait-online.service
      • apt install ifupdown2
    • reboot
    • 测试是否已修复
      • systemctl status systemd-networkd systemd-networkd-wait-online ifupdown-wait-online.service
      • systemctl start apt-daily-upgrade.service
      • systemctl status apt-daily-upgrade.service
    LXC 非特权容器使用低位端口
    • 查看是否为非特权容器,unprivileged=1 为非特权容器
      • pct config <CTID> | grep unprivileged
    LXC 修改 SSH 端口并使用 sshd_config 配置
    • https://www.imval.tech/index.php/blog/proxmox-lxc-ssh-port-change-issue
    • 完全禁用 Socket 激活,仅允许传统服务方式运行 SSH
      • debian lxc
        • alpine lxc
          • 不明
      LXC 非特权容器直通显卡(以 n100 为例)
      (host)编辑 LXC 配置,允许虚拟机设备访问、挂载并创建 ID 映射
      • 查看用户组和设备 id
        • ls -l /dev/dri
          • 结果类似如下
          • 需要留意用户组和设备号,如 video 226, 0
        • cat /etc/group | grep -e "video|render"
          • 查看用户组 ID,用于映射
      • 编辑用户命名空间映射
        • vim /etc/subgid
          • 44, 104 对应 video, render
          • root 用户可以在容器内使用宿主机的 GID 44, 104
      • 添加以下内容以直通显卡
        • vim /etc/pve/lxc/<id>.conf
          • 配置解释
            • 允许访问 GPU 设备路径 /dev/dri/card0, /dev/dri/renderD128
            • 挂载 lxc.mount.entry
              • 每次需要 lxc.hook.pre-start 修改所有用户组
            • 用户和组 ID 映射 lxc.idmap
              • lxc.idmap: <u|g> <容器内起始ID> <宿主机起始ID> <ID数量>
        • 添加 root 用户到 video, render
          • usermod -aG render,video root
        • (LXC)启动容器查看是否挂载成功
          • ls -l /dev/dri
        • 以 debian 12 LXC 模板安装 jellyfin 应用为例
          • 安装 jellyfin 并设置
            • apt install -y curl intel-opencl-icd
              • 安装 openCL runtime
            • curl https://repo.jellyfin.org/install-debuntu.sh | bash
            • service jellyfin status
            • id jellyfin
              • 如果不在 render 组里则手动添加
                • usermod -aG render jellyfin
          • 访问 http://<lxc_ip>:8096,登录成功后进入控制台配置硬件解码
            • 侧边栏 播放 - 解码,选择「In­tel QuickSync (QSV)」,勾选所有解码格式,保存
              • 实际需要看核显是否支持
              • 如果存在中文字幕识别为方块,可以设置备用字体文件路径并启用
            • 如果需要可以进一步启用进度条预览图的硬件解码
          • 挂载媒体库等内容见其他章节
          • 故障排除
            • /usr/lib/jellyfin-ffmpeg/vainfo --display drm --device /dev/dri/renderD128
              • 检查支持编码
            • /usr/lib/jellyfin-ffmpeg/ffmpeg -v verbose -init_hw_device vaapi=va:/dev/dri/renderD128 -init_hw_device opencl@va
              • 检查 openCL runtime
            • intel_gpu_top
              • apt install -y intel-gpu-tools
              • 注意:这个要在宿主机而非 LXC 中执行
                • 按 q 退出
              • 播放视频时查看占用率以检测硬件转码是否生效
        LXC 非特权容器部署 clash 旁路由
        • (host) 配置 LXC 容器访问 /dev/net/tun 的权限
          • vim /etc/pve/lxc/<id>.conf
            • pve 版本 7.0 之前的用 cgroup2 而非 cgroup
        • (LXC) 配置内核允许 ipv4 转发
          • vim /etc/sysctl.conf
            • net.ipv4.ip_forward = 1
        • (LXC) 通过一键安装脚本安装 clash-for-linux
          • apt install -y git curl sudo
          • git clone --branch master --depth 1 https://github.com/nelvko/clash-for-linux-install.git \ && cd clash-for-linux-install \ && sudo bash install.sh
            • 未使用加速 CDN
        LXC 中的 debian 模板存在 locale 未正确设置的问题
        • locale -a
        • apt install --reinstall --purge locales
        • dpkg-reconfigure locales
          • space 勾选,enter 确认
        • cat /etc/default/locale
        LXC 安装 k3s
        使用 CT模板安装 debian 12 容器
        • 前置:调整 PVE 宿主机配置
          • PVE 宿主机加载必要模块并启用配置
            • vim /etc/modules-load.d/modules.conf
              • 部分版本内核已内置 br_netfilter,可以不添加
              • aufs 为早期方案,推荐使用 overlay
            • vim /etc/sysctl.d/99-k3s.conf
              • 使用 ipv6 转发时需要配置为 accept_ra = 2
              • sysctl --system
                • 查看系统目录内 sysctl 配置项
          • PVE 宿主机进一步移除swap交换分区
          • 重启 PVE 宿主机并查看是否生效
            • reboot
            • lsmod | grep -E 'overlay|nf_nat|xt_conntrack|aufs|br_netfilter'
            • 部分版本的 br_netfilter 可能在内核中加载,需要使用以下指令来查看
              • grep 'BRIDGE_NETFILTER' /boot/config-$(uname -r)
            • sysctl vm.swappiness net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv6.conf.all.accept_ra
        • 配置为 2 核 8 G 内存 32G 硬盘空间,swap 交换分区设为 0
        • 启用 IPv6 SLAAC
        • 在 PVE 宿主机上修改容器配置
          • 注意,这些设置项存在安全风险,后果自负
          • vim /etc/pve/lxc/<CTID>.conf
            • 添加以下底层 LXC 样式配置项
            • lxc.cap.drop 禁止容器使用某些 Linux 内核的能力
              • 为空则不禁止使用
            • lxc.apparmor.profile 配置容器的 AppArmor 安全策略
              • unconfined 表示 禁用 AppArmor 对容器的限制
            • lxc.cgroup2.devices.allow 允许容器通过 cgroups v2 访问特定的设备文件
              • c 10:200 rwm
                • c 10:200 允许访问主设备号 10(杂项设备)、次设备号 200 的字符设备
                • rwm 允许 读(r)、写(w) 和 创建(m) 该设备节点
            • lxc.mount.auto 自动挂载宿主机的一些虚拟文件系统
              • proc:rw:以读写模式挂载
                • 容器内可查看/修改进程信息
              • sys:rw:以读写模式挂载
                • 容器内可访问硬件和内核参数
              • cgroup:rw:以读写模式挂载
                • 容器内可管理 cgroups
        启动 debian 12 LXC 并安装 k3s
        • 创建 rc.local 脚本
          • vim /etc/rc.local
          • 由于 LXC 的特殊性,某些设备文件和挂载选项可能与传统的虚拟机或物理服务器不同。通过运行这个脚本,可以确保 Kubernetes 的组件能够正确地访问所需的设备文件,并且挂载点能够正确地传播
        • 修改脚本权限为可执行并重启 LXC
          • chmod +x /etc/rc.local
          • reboot
        • 检查脚本是否执行成功
          • findmnt / -o TARGET,OPT-FIELDS,PROPAGATION
          • ls -al /dev/kmsg
        • 添加 kubelet 选项确保在用户态下正确启动 k3s
        LXC 容器内挂载 SMB/CIFS 共享
        • LXC 中添加组 lxc_shares, 并添加需要使用 CIFS 共享的用户至组 lxc_shares
          • groupadd -g 10000 lxc_shares
            • GID=10000 与 PVE 宿主机中的 GID=110000 相对应
          • usermod -aG lxc_shares <username>
        • 关闭 LXC,后续在编辑 LXC 配置添加挂载后重新启动
        • PVE 宿主机创建挂载点并通过 /etc/fstab 挂载
          • mkdir -p /mnt/lxc_shares/nas_rwx
          • 编辑 /etc/fstab 配置挂载点
            • { echo '' ; echo '# Mount CIFS share on demand with rwx permissions for use in LXCs (manually added)' ; echo '//NAS_ip/nas/ /mnt/lxc_shares/nas_rwx cifs _netdev,x-systemd.automount,noatime,uid=100000,gid=110000,dir_mode=0770,file_mode=0770,user=smb_username,pass=smb_password 0 0' ; } | tee -a /etc/fstab
              • 修改 //NAS_ip/nas/ 为共享挂载的对应 NAS 主机 ip 或域名以及共享路径
              • 修改 smb_username, smb_password 为共享账户密码
          • systemctl daemon-reload
          • mount -a
            • 挂载 fstab 中未挂载的条目
            • local-fs 会自动挂载,如果未挂载可以添加到启动脚本 /etc/rc.local 开机执行
        (可选) 通过 systemd mount 文件挂载
        • mkdir -p /mnt/lxc_shares/nas_rwx
        • vim /etc/systemd/system/mnt-lxc_shares-nas_rwx.mount
          • 文件名需要与挂载点一致, 使用以下指令转义
            • systemd-escape -p /mnt/lxc_shares/nas_rwx
        • vim /etc/systemd/system/mnt-lxc_shares-nas_rwx.automount
          • 定期触发 automount
            • vim /etc/systemd/system/mnt-lxc_shares-nas_rwx-retry.service
              • vim /etc/systemd/system/mnt-lxc_shares-nas_rwx-retry.timer
              • systemctl daemon-reload
              • systemctl enable --now mnt-lxc_shares-nas_rwx.automount
              • systemctl enable --now mnt-lxc_shares-nas_rwx-retry.timer
              • systemctl status mnt-lxc_shares-nas_rwx.mount
              • PVE 宿主机查看挂载情况
                • df -hT | grep lxc_shares
                • umount /mnt/lxc_shares/nas_rwx
                  • l 强制
              • PVE 宿主机编辑 LXC 配置添加挂载点 mp0 并重新启动
                • 挂载 PVE 宿主机路径 /mnt/lxc_shares/nas_rwx/ 到 LXC 容器内路径 /mnt/nas
                  • { echo 'mp0: /mnt/lxc_shares/nas_rwx/,mp=/mnt/nas' ; } | tee -a /etc/pve/lxc/<CT_ID>.conf
                    • <CT_ID> 为对应 LXC 容器 ID
                  • 其他可选项
                    • ,ro=1 只读挂载
                    • ,shared=1 可以在不同 PVE 节点上迁移,但先添加对应挂载
                • 重新启动 LXC 容器即可
              LXC 容器的 chrony 需要修改启动参数,禁用对系统时钟的控制
              • TFA 依赖于 chrony 或 ntp 服务,chrony 默认无法正常启动
              • nano /etc/systemd/system/chronyd.service
                • ExecStart=/usr/sbin/chronyd -x
                  • 添加 x 参数禁用对系统时钟的控制
              • systemctl daemon-reload
              • systemctl restart chrony
              • systemctl status chrony
              上一篇
              配置 PostgreSQL 高可用集群
              下一篇
              mihomo 配置 tproxy 透明代理

              Comments
              Loading...