- iso 镜像物理存储位置
/var/lib/vz/template/iso
- 各种 PVE 一键部署脚本(VM 或 LXC)
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/grubGRUB_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
- http://www.spice-space.org/download.html
- Windows 系统虚拟机需要安装 spice-guest-tools
- VM 硬件中修改显示为 SPICE
使用 VirtIO 驱动提高性能
- 允许虚拟机直接(半虚拟化)访问设备和外围设备,而不是速度较慢的模拟设备和外围设备
iso 未签名,无法使用 SecureBoot 启动
PVE 虚拟机系统安装
PVE 虚拟机安装 iStoresOS
- 下载固件
- 官方固件
- iStoresOS 24 大版本,非官方固件
- https://github.com/zijieKwok/istoreos-actions/releases
- 参考文章根据硬件需求创建虚拟机
写入固件至虚拟机
- 下载 img2kvm 工具
- 上传工具及固件至 pve 宿主机
sftp root@<pve-ip>cd /var/tmpput <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>.conffeatures项添加nesting=1features: ...,nesting=1features: 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 ifupdownsystemctl status systemd-networkd-wait-onlinesystemctl status ifupdown-wait-online
- 已知会影响
apt-daily-upgrade,apt-daily服务 systemctl list-units | grep -e apt-dailysystemctl status apt-daily apt-daily-upgradejournalctl -u apt-daily | tail -n 20- 报错如下:
Sub-process /lib/systemd/systemd-networkd-wait-online returned an error code (1)
- 安装 ifupdown2 并禁用相关服务
systemctl stop systemd-networkd.socketsystemctl disable --now systemd-networkd.service systemd-networkd-wait-online.service ifupdown-wait-online.serviceapt install ifupdown2
reboot
- 测试是否已修复
systemctl status systemd-networkd systemd-networkd-wait-online ifupdown-wait-online.servicesystemctl start apt-daily-upgrade.servicesystemctl 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 | bashservice jellyfin statusid jellyfin- 如果不在 render 组里则手动添加
usermod -aG render jellyfin- 访问
http://<lxc_ip>:8096,登录成功后进入控制台配置硬件解码 - 侧边栏 播放 - 解码,选择「Intel 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_topapt 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.confnet.ipv4.ip_forward = 1
- (LXC) 通过一键安装脚本安装 clash-for-linux
apt install -y git curl sudogit 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
- 参考资料
- https://gist.github.com/triangletodd/02f595cd4c0dc9aac5f7763ca2264185
- https://github.com/k3s-io/k3s/issues/4249
- https://forum.proxmox.com/threads/k3s-on-lxc-modprob-fatal-module-overlay-not-found-in-directory-lib-modules-5-13-19-1-pve.100584/
- https://pve.proxmox.com/wiki/Linux_Container#pct_configuration
- https://linuxcontainers.org/zh-cn/lxc/manpages//man5/lxc.container.conf.5.html
- https://github.com/bottlerocket-os/bottlerocket/issues/3411
使用 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交换分区
- https://www.kernel.org/doc/html/latest/admin-guide/sysctl/vm.html
vm.swappiness = 0实际不代表无交换swapoff -alvchange -a n /dev/pve/swaplvremove /dev/pve/swaplvdisplay | grep /dev/pve- 查看是否已移除
vim /etc/fstab- 注释对应部分,禁用挂载
- 重启 PVE 宿主机并查看是否生效
rebootlsmod | 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 rwmc 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.localreboot
- 检查脚本是否执行成功
findmnt / -o TARGET,OPT-FIELDS,PROPAGATIONls -al /dev/kmsg
- 添加 kubelet 选项确保在用户态下正确启动 k3s
- https://docs.k3s.io/installation/configuration#kubelet-configuration-files
curl -sfL https://get.k3s.io | sh -s - server --docker\ --kubelet-arg=feature-gates=KubeletInUserNamespace=true \ --kube-controller-manager-arg=feature-gates=KubeletInUserNamespace=true \ --kube-apiserver-arg=feature-gates=KubeletInUserNamespace=true \ ...- 其余选项根据自身情况添加
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-reloadmount -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.servicevim /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_sharesumount /mnt/lxc_shares/nas_rwxl强制
- 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.serviceExecStart=/usr/sbin/chronyd -x- 添加
x参数禁用对系统时钟的控制
systemctl daemon-reload
systemctl restart chrony
systemctl status chrony
- Author:白鸟3
- URL:https://blog.kun2peng.top/operation/pve_vm
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
