机器配置
商品名称:幻网 7505 软路由
CPU: Intel Pentium Gold 7505 (2C4T 11代)
GPU: Intel UHD Graphics for 11th Gen Intel® Processors (核显)
显示接口: HDMI+DP
内存插槽: DDR4 32GB(MAX) 3200MHz x2
硬盘接口: PCI-E x4 M.2 NVME x1
网卡: Intel I226-V x6 (2.5Gbps)
外部接口: USB 3.0 x2, USB 2.0 x2, COM x1, USB Type-C x1
内部接口: SATA 3.0 x1, M.2 WIFI
PVE: v8.1.3
小坑
Debian 11 LXC容器
IPv6获取方式不正确会导致启动极慢
前一阵子把家里的IPv6分配改成SLAAC方式,在PVE主机对所有guest备份完成后,发现域名访问断联,排查半天发现反代的LXC容器一直没跑起来,后来翻到这个帖子
大致原因是设置DHCPv6方式获取的Debian 11容器会一直等待地址分配直到超时失败,上游网关如果没有DHCPv6分配功能的话,一定要改成SLAAC方式或者干脆停掉容器的IPv6
前置
PVE换源
wget https://mirrors.ustc.edu.cn/proxmox/debian/proxmox-release-bookworm.gpg -O /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg
echo "#deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise" > /etc/apt/sources.list.d/pve-enterprise.list
echo "deb https://mirrors.ustc.edu.cn/proxmox/debian/pve bookworm pve-no-subscription" > /etc/apt/sources.list.d/pve-no-subscription.list
Debian换源
# 备份文件
mv /etc/apt/sources.list /etc/apt/sources.list.bak
nano /etc/apt/sources.list
# nano编辑之后填入以下内容
deb https://mirrors.ustc.edu.cn/debian bookworm main contrib non-free
deb https://mirrors.ustc.edu.cn/debian bookworm-updates main contrib non-free
deb https://mirrors.ustc.edu.cn/debian-security bookworm-security main contrib non-free
# 或者直接运行
echo -e "deb https://mirrors.ustc.edu.cn/debian bookworm main contrib non-free\ndeb https://mirrors.ustc.edu.cn/debian bookworm-updates main contrib non-free\ndeb https://mirrors.ustc.edu.cn/debian-security bookworm-security main contrib non-free" > /etc/apt/sources.list
Ceph换源
nano /etc/apt/sources.list.d/ceph.list
# nano编辑之后填入以下内容
#deb https://enterprise.proxmox.com/debian/ceph-quincy bookworm enterprise
deb https://mirrors.ustc.edu.cn/proxmox/debian/ceph-quincy/ bookworm no-subscription
# 或者直接运行
echo -e "#https://enterprise.proxmox.com/debian/ceph-quincy bookworm enterprise\ndeb https://mirrors.ustc.edu.cn/proxmox/debian/ceph-quincy/ bookworm no-subscription" > /etc/apt/sources.list.d/ceph.list
# 备份ceph.pm
cp /usr/share/perl5/PVE/CLI/pveceph.pm /usr/share/perl5/PVE/CLI/pveceph.pm.bak
# 替换内部链接
sed -i 's|http://download.proxmox.com|https://mirrors.ustc.edu.cn/proxmox|g' /usr/share/perl5/PVE/CLI/pveceph.pm
CT模板换源
# 备份
cp /usr/share/perl5/PVE/APLInfo.pm /usr/share/perl5/PVE/APLInfo.pm_back
# 替换内部链接
sed -i 's|http://download.proxmox.com|https://mirrors.ustc.edu.cn/proxmox|g' /usr/share/perl5/PVE/APLInfo.pm
# 更换后重启daemon
systemctl restart pvedaemon
额外修改
解决 apt update
时提示 non-free
变为 non-free-firmware
问题
su -c 'echo "APT::Get::Update::SourceListWarnings::NonFreeFirmware \"false\";" > /etc/apt/apt.conf.d/no-bookworm-firmware.conf'
去除每次界面登录时提示 no subscription
提示
sed -Ezi.bak "s/(Ext.Msg.show\(\{\s+title: gettext\('No valid sub)/void\(\{ \/\/\1/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && systemctl restart pveproxy.service
开启硬件直通
BIOS中打开硬件直通相关选项(VT-d & VMX)
默认lvm+UEFI方式安装系统
# 编辑Grub
nano /etc/default/grub
# 注释掉原来的,增加iommu参数,AMD CPU是amd_iommu=on
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on"
# 编辑modules
nano /etc/modules
# 添加以下内容
vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd
# 刷新引导参数
update-grub
update-initramfs -u -k all
# 最后重启
reboot
使用UEFI+ZFS方式安装系统
[网络教程]()
# 编辑/etc/kernel/cmdline
nano /etc/kernel/cmdline
# 在这一行加入intel_iommu=on
root=ZFS=rpool/ROOT/pve-1 boot=zfs intel_iommu=on iommu=pt
# 刷新EFI Boot分区
pve-efiboot-tool refresh
# 添加以下内容
vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd
# 刷新引导参数
update-grub
pve-efiboot-tool refresh
update-initramfs -u -k all
# 最后重启
reboot
解决图表信息无法显示(illegal attempt to update using time)
原因是rrd服务与系统时间不符,需要清除已有数据再重启服务和cluster
systemctl stop rrdcached
cd /var/lib/
mv rrdcached rrdcached.bck
systemctl start rrdcached
systemctl restart pve-cluster
Nginx反代web gui
网关需要转发一个外部可用端口,同时反代PVE的web gui以及虚拟机控制台的SPICE模式
Server{}模块:
# 反代web gui
location / {
proxy_pass https://192.168.9.254:8006;
proxy_buffering off;
client_max_body_size 0;
proxy_connect_timeout 3600s;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
send_timeout 3600s;
}
Stream{}模块
server {
listen 3128;
proxy_pass 192.168.9.254:3128;
}
LXC容器部署Docker
在前置工作里已经给CT模板换源了,可以直接在local存储里下载Debian 11模板
这里使用 debian-11-standard_11.7-1
模板
(施工中)
Unprivileged LXC容器的数据互通
宿主机PVE互通
事先提醒: 如果不需要这种无特权容器的权限隔离功能,完全可以直接在创建容器时将 无特权的容器
选项取消勾选,这样 host
和 guest
就共用一套用户权限方案,避免很多 guest
内部与 host
交互上可能出现的问题
参考文章: proxmox_bind_unprivileged_lxc
在 无特权的容器(unprivileged container)
内,PVE会将容器(后面都称作 guest
)内的 user
和 group
权限与宿主机建立映射关系,默认映射关系是宿主机 (后面都称作 host
)的 uid
以及 gid
同时+100000,即
UID | UID | GID | GID |
---|---|---|---|
host | guest | host | guest |
0 | 100000 | 0 | 100000 |
1000 | 101000 | 1000 | 101000 |
... | ... | ... | ... |
65535 | 1065535 | 65535 | 1065535 |
容器作为 guest
,内部用户的权限只能在 host
内操作相对应用户权限的文件以及文件夹,即
host owner | guest owner |
---|---|
100000:100000 | 0:0 |
101000:101000 | 1000:1000 |
这种映射关系的好处在于可以将LXC guest
与 host
的数据权限隔离,即使容器内服务被人攻破,也能隔离掉对宿主机的操作
如果想保留这种权限隔离的状态,但又需要让 guest
和 host
之间交互,根据上述参考文章有两种方案
以ID为 100
的Docker LXC举例,在 host
建立文件夹/mnt/100,在 guest
建立文件夹/mnt/host-data
方案1
在 host
建立属于对应 guest
内部用户的挂载点,并在 host
修改挂载点 owner
为 guest
映射的用户
host
操作
# host操作
mkdir /mnt/100
chown -R 100000:100000 /mnt/100
# guest操作(以root用户执行)
mkdir /mnt/host-data
# 执行以下命令生成挂载点, pct set <container_id> -mp0 <host_mountpoint>,mp=<guest_mountpoint>
pct set 100
# 或者添加以下内容到/etc/pve/lxc/100.conf并保存, mp<id>: <host_mountpoint>,mp:=<guest_path>
mp0: /mnt/100,mp:=/mnt/host-data
guest
操作
# 创建挂载点
mkdir /mnt/host-data
最后重启 guest
容器生效,guest
内用 root
用户读写 /mnt/host-data
方案2
修改默认的用户映射关系,让 host
的特定用户和用户组与 guest
对照起来,即
UID | UID | GID | GID |
---|---|---|---|
host | guest | host | guest |
1005 | 1005 | 1005 | 1005 |
相应的文件夹所有权设置为
host owner | guest owner |
---|---|
1005:1005 | 1005:1005 |
后续只使用 1005:1005
在 host
和 guest
之间交互,其他id正常映射
host
操作
# 修改owner
chown -R 1005:1005 /mnt/105
# 为host的root用上添加subuid和subgid
echo "root:1005:1" >> /etc/subuid
echo "root:1005:1" >> /etc/subgid
# 添加以下内容到/etc/pve/lxc/105.conf并保存, mp<id>: <host_path>,mp:=<guest_path>
mp0: /mnt/105,mp:=/mnt/host-data
lxc.idmap = u 0 100000 1005
lxc.idmap = g 0 100000 1005
lxc.idmap = u 1005 1005 1
lxc.idmap = g 1005 1005 1
lxc.idmap = u 1006 101006 64530
lxc.idmap = g 1006 101006 64530
以上 lxc.idmap = <u or g> a b n
作用为从a映射b开始,一共映射1005个uid或gid,上述6行即
host | guest |
---|---|
0:0 | 100000:100000 |
1:1 | 100001:100001 |
... | ... |
1004:1004 | 101004:101004 |
1005:1005 | 1005:1005 |
1006:1006 | 101006:101006 |
65535:65535 | 165535:165535 |
guest
操作
与方案1的guest操作一致
优缺点对比
方案1
优点
- 配置迅速简单
- 不更改变动原有的LXC用户权限映射功能
缺点
- 需要用户自己记忆管理
host
与guest
之间的用户权限对应关系,比如要记住host
的100000:100000
对应的是ID 100
的guest
的0:0(root:root)
方案2
优点
- 在
host
和guest
之间建立一一对应的权限映射关系,比如host
的1005:1005
对应的也是guest
的1005:1005
缺点
- 配置繁琐,本质上和方案1的缺点一样需要把控好权限映射关系
- Unprivileged LXC的权限隔离目的部分丧失,让
host
的权限管理变复杂
个人总结
个人倾向于方案1
如果容器内部不需要做额外的权限管控,可以让 host
的高UID&GID用户一一对应每个 guest
的 root(0:0)
用户,这样可以简化权限映射关系的管控,即
100000:100000
-> ID:100 的 root
100001:100001
-> ID:101 的 root
100005:100005
-> ID:105 的 root
需要跟进操作的仅仅是
chown -R 100000:100000 /mnt/100
chown -R 100001:100001 /mnt/101
chown -R 100005:100005 /mnt/105
和
mp0: /mnt/100,mp:=/mnt/host-data
-> /etc/pve/lxc/100.conf
mp0: /mnt/102,mp:=/mnt/host-data
-> /etc/pve/lxc/102.conf
mp0: /mnt/105,mp:=/mnt/host-data
-> /etc/pve/lxc/105.conf
NAS互通
区别在于需要在宿主机PVE上进行远程挂载,以下使用我的群晖NAS smb共享并采用上述方案1进行权限管控
在NAS创建相关的用户以及目录后,主要操作在 host
上
host
操作
vim /etc/fstab
# 使用vim编辑fstab并添加以下内容
# //NAS_IP/path <> cifs username=<smb_user>,password=<smb_password>,uid=100000,gid=100000 0 0
//192.168.9.11/pve/100 /mnt/100 cifs username=<smb_user>,password=<smb_password>,uid=100000,gid=100000 0 0
# :wq保存退出后让挂载生效
mount -av
# 重启daemon,让PVE下次启动按修改版的fstab挂载smb
systemctl daemon-reload
注意后面的UID和GID至关重要,需要和 guest
内部的 root
用户对应
guest操作
# 执行以下命令生成挂载点, pct set <container_id> -mp0 <host_mountpoint>,mp=<guest_mountpoint>
pct set 100 -mp0 /mnt/100,mp=/mnt/nas
最后重启 guest
容器生效
备份与还原
备份
还原
vzdump备份任务hook script
PVE会一直对SMB共享存储刷新状态保持连接,大概10秒以此,会导致对应的共享设备的硬盘和系统无法进入休眠或者持续不断产生SMB访问日志,需要平时停用共享,然后做一个hook script在vzdump备份初始化时自动启用,在完成后自动停止
编辑/etc/vzdump.conf,添加script路径
vim /etc/vzdump.conf
script: /opt/scripts/vzdump-hook-script.pl
:wq
然后根据/usr/share/doc/pve-manager/examples/vzdump-hook-script.pl编写job-init和job-end或job-aboart情况下的自动启用/停用脚本
# nas-backup换成对应的存储id, 可以在数据中心的存储那找到
if ($phase eq 'job-init') {
if ($storeid eq 'nas-backup') {
system ("/usr/sbin/pvesm set $storeid --disable 0") == 0 ||
die "enabling storage $storeid failed";
}
}
#nas-backup换成对应的存储id, 可以在数据中心的存储那找到
if (($phase eq 'job-end') || ($phase eq 'job-abort')) {
if ($storeid eq 'nas-backup') {
system ("/usr/sbin/pvesm set $storeid --disable 1") == 0 ||
die "disabling storage $storeid failed";
}
}
之后在备份vzdump就会自动启用和停用挂载
常用指令
qm
qm <命令> <vmid> [选项]
qm [create|set] <vmid> # 创建虚拟机
--memory <MBYTES> memory in MB (64 - 8192)
--sockets <N> set number of CPU sockets <N>
--cores <N> set cores per socket to <N>
--ostype NAME specify OS type
--onboot [yes|no] start at boot
--keyboard XX set vnc keyboard layout
--cpuunits <num> CPU weight for a VM
--name <text> set a name for the VM
--description <text> set VM description
--boot [a|c|d|n] specify boot order
--bootdisk <disk> enable booting from <disk>
--acpi (yes|no) enable/disable ACPI
--kvm (yes|no) enable/disable KVM
--tdf (yes|no) enable/disable time drift fix
--localtime (yes|no) set the RTC to local time
--vga (gd5446|vesa) specify VGA type
--vlan[0-9u] MODEL=XX:XX:XX:XX:XX:XX[,MODEL=YY:YY:YY:YY:YY:YY]
--ide<N> [volume=]volume,[,media=cdrom|disk]
[,cyls=c,heads=h,secs=s[,trans=t]]
[,cache=none|writethrough|writeback]
[,snapshot=on|off][,cache=on|off][,format=f]
[,werror=enospc|ignore|report|stop]
[,rerror=ignore|report|stop]
[,backup=no|yes]
--ide<N> <GBYTES> create new disk
--ide<N> delete remove drive - destroy image
--ide<N> undef remove drive - keep image
--cdrom <file> is an alias for --ide2 <file>,media=cdrom
--scsi<N> [volume=]volume,[,media=cdrom|disk]
[,cyls=c,heads=h,secs=s[,trans=t]]
[,snapshot=on|off][,format=f]
[,cache=none|writethrough|writeback]
[,werror=enospc|ignore|report|stop]
[,backup=no|yes]
--scsi<N> <GBYTES> create new disk
--scsi<N> delete remove drive - destroy image
--scsi<N> undef remove drive - keep image
--virtio<N> [volume=]volume,[,media=cdrom|disk]
[,cyls=c,heads=h,secs=s[,trans=t]]
[,snapshot=on|off][,format=f]
[,cache=none|writethrough|writeback]
[,werror=enospc|ignore|report|stop]
[,rerror=ignore|report|stop]
[,backup=no|yes]
--virtio<N> <GBYTES> create new disk
--virtio<N> delete remove drive - destroy image
--virtio<N> undef remove drive - keep image
qm monitor <vmid> # 连接到虚拟机控制监视器
qm start <vmid> # 启动实例
qm shutdown <vmid> # 优雅停止实例 发送关机命令
qm wait <vmid> [time] wait until vm is stopped
qm stop <vmid> # 停止实例 强制停止
qm reset <vmid> # 重启实例 相当于stop然后再start
qm suspend <vmid> # 暂停实例
qm resume <vmid> # 恢复实例
qm cad <vmid> #发送按键 ctrl-alt-delete
qm destroy <vmid> # 销毁实例(删除所有已使用/拥有的卷)
qm unlock <vmid> # 清除迁移/备份锁
qm status <vmid> # 显示实例状态
qm cdrom <vmid> [<device>] <path> set cdrom path. <device is ide2 by default>
qm cdrom <vmid> [<device>] eject eject cdrom
qm unlink <vmid> <volume> delete unused disk images
qm vncproxy <vmid> <ticket> open vnc proxy
qm vnc <vmid> start (X11) vncviewer (experimental)
qm showcmd <vmid> # 显示命令行(调试信息)
qm list # 列出所有虚拟机
qm startall # 启动所有虚拟机 当onboot=1时
qm stopall [timeout] # 停止所有虚拟机(默认超时为3分钟)
版权属于:Zakikun
本文链接:https://blog.zakikun.com/archives/84.html
本文采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可。
您可以自由的转载和修改,但请务必注明文章来源并且不可用于商业目的。