新买了一台主机,准备搭个 PVE 服务器,在这记录一下过程。

安装 PVE

PVE 本身基于 Debian 系统,安装起来并不会十分复杂。下载最新版的 PVE 镜像,还有最新版引导盘制作软件 Rufus,将镜像写入 U 盘后再从 U 盘启动即可。遇到一个比较坑的问题,引导进入 PVE 安装界面后却提示 no device with valid ISO found, please check your installation medium。因为我这 U 盘拿来做各种启动盘也挺久了所以一开始没怀疑到它,总觉得是自己引导盘做的有问题,还换了 Etcher,用 AI 搜来的过时信息对 bios 一通修改。结果最后换了个 U 盘就好了,并不用做任何多余的操作。

安装 PVE 时注意考虑好主机名和分配给服务器的 ip 再设置,之后虽然也可以修改,不过一开始能固定下来后面就省点心。

PVE 服务器改名

hostnamectl set-hostname <新名字>
修改 /etc/hosts 替换老名字

mkdir /root/tmp
cp -r /etc/pve/nodes/<老名字>/* /root/tmp/ # 复制现有配置
rm -rf /etc/pve/nodes/<老名字>
mkdir /etc/pve/nodes/<新名字>
cp -r /root/tmp/* /etc/pve/nodes/<新名字> # 复制现有配置
reboot

修改镜像源

安装完后要更新软件,首先就是改镜像源了。按清华大学镜像站的指引更换 Debian 和 Proxmox 软件源。

企业版源列表文件内的内容 /etc/apt/sources.list.d/pve-enterprise.list 可以全部注释掉。

ceph 源,将 ceph.source 复制备份后新建 /etc/apt/sources.list.d/ceph.list,内容为

deb https://mirrors.ustc.edu.cn/proxmox/debian/ceph-squid bookworm no-subscription

最后执行 apt update && apt dist-upgrade -y 更新并重启即可。

删除 local-lvm

local-lvm 和 local 本意是一个放 iso 方便安装虚拟机,一个放虚拟机磁盘,相当于默认分了个区,没法有效利用磁盘空间,所以直接删了合并成一个。local-lvm 删除后,空间合并给 local 存储空间。

lvremove /dev/pve/data
lvextend -l +100%FREE -r /dev/pve/root

命令操作完后在 Web 界面删除 local-lvm 存储:点击左侧列表的数据中心节点 – 存储 – 选中 local-lvm 删除。
最后还要配置下 local 存储,在上一步的存储界面选中 local,点击 编辑 – 内容,确保选中了 所有选项(包括磁盘映像、容器等),这样 local 分区就可以存放各类文件了。

安装文件虚拟机

新建一个虚拟机用来管理所有数据磁盘,并通过 smb 分享给其他服务,省得虚拟机各搞各的了。随便装个 Fedora 或者 Debian,配一下 smb.conf。

/usr/sbin/groupadd smbgroup               # 设置 smb 用户组
/usr/sbin/useradd smb_user1               # 新建 smb 用户
/usr/sbin/usermod -aG smbgroup smb_user1  # 添加到组
smbpasswd -a smb_user1                    # 设置密码

ufw allow samba                           # 防火墙放行,如果有的话

sudo chgrp -R smbgroup /srv/samba/shared  # 每个共享目录都要操作
sudo chmod 2770 /srv/samba/shared         # 设置 SGID,保证新建文件继承组身份

配置 smb.conf

[global]
   security = user
   smb passwd file = /etc/samba/smbpasswd
   access based share enum = Yes
   server min protocol = SMB3    # 避免用不安全的过时协议
   ntlm auth = ntlmv2-only       # 禁用不安全的 NTLMv1 认证   
   server smb encrypt = required # 明确要求客户端使用加密
[tmp-space]  # 设置共享目录
   comment = 临时目录
   create mask = 0664
   directory mask = 0775
   inherit permissions = Yes
   path = /srv/samba/tmp-folder
   read only = No                     # 目录默认可写
   valid users = smb_user1 smb_user2  # 允许哪些用户访问
   read list = smb_user1              # 重载读写配置,user1 设为只读 
   write list = smb_user2 @wgroup     # 仅 user2 和 wgroup 里的用户可写,再配合全局的 read only 设置就比较完善了

最后重启 smb:systemctl restart smbd nmbd

连接 smb

Windows 系统只需要在我的电脑 – 工具栏中的“计算机” – 映射网络驱动器即可。

Linux 系统可以添加到 systemd 中以便开启自动挂载,/etc/systemd/system/mnt-sync.mount创建配置文件

[Unit]
Description=Mount My SMB Share
Requires=network-online.target  # 需要网络就绪
After=network-online.target     # 在网络就绪后才执行
Wants=network-online.target     # 期望网络就绪

[Mount]
What=//192.168.A.B/smb-dir
Where=/mnt/smb
Type=cifs
Options=credentials=/etc/samba/credentials,iocharset=utf8,nofail

[Install]
WantedBy=multi-user.target

其中 /etc/samba/credentials 保存了 smb 的用户名和密码用于连接。内容为

username=smb_user
password=123456

另外,如果你的 linux 用户跟 smb 用户不是同一个,那么在 .mount 文件的 Options 里再加上 uid=1000,gid=1000,1000 换成 linux 用户的实际 id,这样 linux 用户才有权限写入 smb 目录。
设置完毕后 reload 下配置

systemctl daemon-reload
systemctl enable mnt-sync.mount
systemctl start mnt-sync.mount

直通硬盘给文件服务器

上面设置文件服务器的目的就是将所有数据硬盘都交由一个虚拟机管理,然后通过 smb 共享给其他机器使用,这样方便集中化管理与隔离,而且相比直接部署在 pve 上,用单独的虚拟机也不会污染主机。

识别硬盘

使用 ls -l /dev/disk/by-id/ 找到新硬盘的持久化 ID。因为还会有其他包括系统盘的输出,不好辨认的话可以 apt install lshw 安装 lshw 查看硬盘的具体信息。安装后执行 lshw -class disk -class storage 即可,输出类似

  *-disk
    description: ATA Disk
    product: ST3000DM001-1CH1
    vendor: Seagate
    physical id: 0.0.0
    bus info: scsi@3:0.0.0
    logical name: /dev/sda
    version: CC27
    serial: Z1F41BLC
    size: 2794GiB (3TB)
    configuration: ansiversion=5 sectorsize=4096

找到这里 serial: Z1F41BLC,然后再执行对比 ls -l /dev/disk/by-id | grep Z1F41BLC 的输出,找到磁盘的 id,不要直接用 /dev/sda,因为它每次重启后是可能发生变化的。

直通硬盘

使用 qm set <VMID> -scsiX /dev/disk/by-id/<硬盘ID>,backup=0,discard=on 命令(推荐VirtIO-SCSI)。

  • backup=0:防止 PVE 备份工具尝试备份这个直通磁盘,因为这些磁盘通常很大且可能包含不支持快照的文件系统。
  • discard=on:如果直通的是 SSD,启用此选项以支持 TRIM/Discard 指令,有助于 SSD 维护性能和寿命。
  • -scsiX:控制器类型选择,推荐 VirtIO SCSI 控制器,性能最好,支持更多高级特性(如 TRIM),不过需要虚拟机安装驱动(现代 Linux 系统通常自带,Windows 需额外安装)。参数中的 X 可以是 0~5 数字,查看虚拟机的硬件,像图中并没有 scsi0,所以可以填 0~5 均可虚拟机硬件配置信息

重启虚拟机,配置硬盘

  • Linux:系统内分区、格式化、挂载。
  • Windows:如用 VirtIO-SCSI,需要安装 VirtIO 驱动;如果用 SATA,则可直接在磁盘管理中初始化使用。

全盘加密

apt install cryptsetup
... # 先用 lsblk 找到对应的磁盘
cryptsetup -y -v luksFormat /dev/sdX            # 把 X 替换成目标磁盘,会清空硬盘所有数据
... # 根据提示输入一个密码用于加解密磁盘

cryptsetup luksOpen /dev/sdX encrypted-disk     # 打开加密磁盘,会要求输入刚才的密码
mkfs.ext4 /dev/mapper/encrypted-disk            # 创建 ext4 文件系统
mkdir /mnt/enc-disk                             # 挂载加密磁盘
mount /dev/mapper/encrypted-disk /mnt/enc-disk  # 之后可以正常使用了

# 卸载和关闭
umount /mnt/enc-disk
cryptsetup luksClose encrypted-disk

# 添加恢复密钥
cryptsetup luksAddKey /dev/<你的设备>
openssl rand -hex -out /root/encryption-key.bin 2048   # 生成密钥文件
cryptsetup luksAddKey /dev/sdX /path/to/keyfile

每次开机执行 luksOpen + mount 后即可使用。关机时系统会自动卸载磁盘,一般不用手动处理。但是手动卸载可以确保没有正在使用的连接,以免被强制卸载导致数据损坏。文件服务器一般是常开的,所以挂载卸载都是手动操作一下。

Syncthing

Syncthing 用来做设备间数据同步。下面设置以当前用户的身份启动 syncthing。

mkdir -p ~/.config/systemd/user/
vi ~/.config/systemd/user/syncthing.service  # 文件内容在下方
systemctl --user daemon-reload
systemctl --user enable syncthing.service
systemctl --user start syncthing.service
loginctl enable-linger <用户名>              # 用户不登陆也自动运行 systemd 服务
[Unit]
Description=Syncthing - Open Source Continuous File Synchronization for %i
Documentation=man:syncthing(1)
After=network.target

[Service]
ExecStart=/usr/bin/syncthing serve --no-browser --no-restart --logflags=0
Restart=on-failure
SuccessExitStatus=3 4
RestartForceExitStatus=3 4

# Hardening
ProtectSystem=full
PrivateTmp=true
SystemCallArchitectures=native
MemoryDenyWriteExecute=true
NoNewPrivileges=true

[Install]
WantedBy=default.target

PS:因为是在 smb 目录里做同步,同步时就会看到本机会自动修改同步数据中各个目录的权限,搞得很麻烦,到所有目录设置里勾选上“忽略权限”就可以了。

To be continued

还有其他一些东西需要配置,比如 电源管理、jellyfin 直通核显硬解、备份等,后续再一一补充。

参考

最后贴一下官方文档,有各种问题都可以去里面找找