Proxmox VE 8.3 安装与配置指南

random-pic-api

简介

本文详细介绍了如何在 Proxmox VE 8.3 系统中进行安装和配置,包括网络设置、源更换、Ceph 集群配置、ZFS 存储池创建、4G 网卡拨号、USB 摄像头连接等。通过本文,读者可以快速搭建和优化自己的 Proxmox VE 环境。

安装完成后 IP 不对

启动后出现了一张 vmbr0 网卡, 这个是桥接网卡, 可以查看绑定的物理网卡:

1
ip link show master vmbr0

修改一下 3 个文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# /etc/network/interfaces

auto lo
iface lo inet loopback

iface enp92s0 inet manual

auto vmbr0
iface vmbr0 inet static
address 192.168.100.100/24
gateway 192.168.100.1
bridge-ports enp92s0
bridge-stp off
bridge-fd 0

# /etc/issue
Welcome to the Proxmox Virtual Environment. Please use your web browser to
configure this server - connect to:

https://192.168.100.100:8006/

# /etc/hosts

127.0.0.1 localhost.localdomain localhost
192.168.100.100 nuc.ihome nuc

参考:

更换源

1
2
3
sudo apt install apt-transport-https ca-certificates

wget https://mirrors.ustc.edu.cn/proxmox/debian/proxmox-release-bookworm.gpg -O /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg

通用软件源

1
2
cp /etc/apt/sources.list /etc/apt/sources.list.bak
vim /etc/apt/sources.list
1
2
3
4
5
6
7
8
9
10
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free-firmware

# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free-firmware
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free-firmware
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free-firmware
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free-firmware
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free-firmware
deb https://mirrors.tuna.tsinghua.edu.cn/debian-security bookworm-security main contrib non-free-firmware
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian-security bookworm-security main contrib non-free-firmware

pve 软件源

1
2
3
cp /etc/apt/sources.list.d/pve-enterprise.list /etc/apt/sources.list.d/pve-enterprise.list.bak

# 清空 /etc/apt/sources.list.d/pve-enterprise.list
1
2
# 使用Proxmox非企业版源
echo "deb https://mirrors.ustc.edu.cn/proxmox/debian bookworm pve-no-subscription" > /etc/apt/sources.list.d/pve-no-subscription.list

Ceph 源

1
2
3
cp /etc/apt/sources.list.d/ceph.list /etc/apt/sources.list.d/ceph.list.bak

echo "deb https://mirrors.ustc.edu.cn/proxmox/debian/ceph-quincy bookworm no-subscription" > /etc/apt/sources.list.d/ceph.list

CT 镜像下载源

将 /usr/share/perl5/PVE/APLInfo.pm 文件中默认的源地址 http://download.proxmox.com 替换为 https://mirrors.tuna.tsinghua.edu.cn/proxmox 即可。

1
2
3
cp /usr/share/perl5/PVE/APLInfo.pm /usr/share/perl5/PVE/APLInfo.pm.bak

sed -i 's|http://download.proxmox.com|https://mirrors.ustc.edu.cn/proxmox|g' /usr/share/perl5/PVE/APLInfo.pm
1
2
3
4
5
{
host => "mirrors.ustc.edu.cn",
url => "https://mirrors.ustc.edu.cn/turnkeylinux/metadata/pve",
file => 'aplinfo.dat',
}
1
2
3
systemctl restart pvedaemon.service
pveam update
pveam available

删除订阅弹窗

1
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

oh-my-zsh

1
2
3
4
5
6
7

apt update && apt install git zsh curl \
&& sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting \
&& git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions \
&& git clone https://github.com/zsh-users/zsh-completions ${ZSH_CUSTOM:-${ZSH:-~/.oh-my-zsh}/custom}/plugins/zsh-completions

连接 WiFi

1
2
3
4
5
6
apt-get install wpasupplicant wireless-tools -y

ip link set wlp91s0 up
iwlist wlp91s0 scanning | grep "ESSID"

wpa_passphrase [WIFI名称] [WIFI密码]

No wpa_supplicant executable

会得到类似以下的输出(也可以使用网页工具计算: https://www.wireshark.org/tools/wpa-psk.html:

1
2
3
4
5
network={
ssid="[WIFI名称]"
#psk="[WIFI密码]"
psk=[WIFI密码的密钥值]
}

我们需要复制这个 PSK 值。


  1. 打开/etc/network/interfaces文件
  2. 添加以下内容
1
2
3
4
5
6
7
8
9
10
11
12
13
auto [网卡名称]

# 如果你使用静态IP
iface [网卡名称] inet static
address [你要分配的IP地址,如192.168.4.1/24]
gateway [网关地址]
wpa-ssid [WIFI名称]
wpa-psk [WIFI密码的密钥值]

# 如果你使用动态IP
iface [网卡名称] inet dhcp
wpa-ssid [WIFI名称]
wpa-psk [WIFI密码的密钥值]

为了方便管理,我们推荐你使用静态 IP 3. 重启网络

1
2
ifdown [网卡名称]
ifup [网卡名称]

安装 iw 工具

1
apt install iw -y

查看 WiFi 信息

1
2
3
4
5
6
7
8
9
10
$ iwconfig wlp91s0
wlp91s0 IEEE 802.11 ESSID:"xxxxx"
Mode:Managed Frequency:5.745 GHz Access Point: 9C:9D:7E:7C:90:19
Bit Rate=29.2 Mb/s Tx-Power=22 dBm
Retry short limit:7 RTS thr:off Fragment thr:off
Encryption key:off
Power Management:on
Link Quality=48/70 Signal level=-62 dBm
Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0
Tx excessive retries:0 Invalid misc:92 Missed beacon:0

参考


Web 打不开

501 no such file '/PVE/StdWorkspace.js'

1
2
3
4
5
6
7
8
apt install --reinstall proxmox-widget-toolkit

apt update && apt upgrade
apt install -f

apt dist-upgrade
pvecm updatecerts --force
service pveproxy restart

pve_source 脚本

https://bbs.x86pi.cn/thread?topicId=20

稳定版

1
wget -q -O /root/pve_source.tar.gz 'https://bbs.x86pi.cn/file/topic/2023-11-28/file/01ac88d7d2b840cb88c15cb5e19d4305b2.gz' && tar zxvf /root/pve_source.tar.gz && /root/./pve_source

开发版 (PVE 系统配置 IOMMU、核显直通、核显 SR-IOV 调整为定制向导+推荐方案)

1
wget -q -O /root/pve_source.tar.gz 'https://bbs.x86pi.cn/file/topic/2024-01-06/file/24f723efc6ab4913b1f99c97a1d1a472b2.gz' && tar zxvf /root/pve_source.tar.gz && /root/./pve_source

迁移 Ubuntu 系统到 PVE

列举一下已存在的 M.2 固态硬盘信息:

20250218100813_9YKCDhZZ.webp

一共 1T *4 M.2 固态硬盘, 其中 nvme0n1 安装的 PVE, 其他 3 根还未使用.

镜像打包

原来安装 Ubuntu 的 M.2 500G 固态硬盘已经从机器上拔下来了, 为了将此固态硬盘中的系统打包成镜像然后恢复到 PVE 中, 这里使用了 Clonezilla 来完成这项工作.

使用到的工具:

  1. Clonezilla
  2. Ventoy

20250218105012_ChdOGfq8.webp

20250221012151_nPtdL8DT.webp

执行完成后会在指定的 U 盘生成一些系统文件, 但是这个还不能直接使用, 所以我又使用 Clonezilla 将这些文件打包成 ISO.

最终的目的是将 Ubuntu 系统打包成 ISO, 然后在 PVE 中使用虚拟机安装.

参考

安装到 PVE

在 PVE 下查看 P40 显卡的信息:

1
2
lspci |  grep 3D
81:00.0 3D controller: NVIDIA Corporation GP102 [P102-100] (rev a1)

要直通这块卡给 Ubuntu 24.04 虚拟机,需要准备:

  • 开启 pcie 直通
  • 安装 Ubuntu 24.04 虚拟机(就是上一步打包的 ISO)

安装 Windows

https://www.mulingyuer.com/archives/1027/

https://willxup.top/archives/pve-install-win11

https://imacos.top/2023/09/07/pve-windows-11/

核显直通与虚拟核显直通

物理核显直通 vs SRIOV vGPU 的优缺点对比:

优点缺点
物理核显直通1、性能强 2、支持物理显示输出 (VGA/DP/HDMI/Type-C) 3、兼容性好,不妨碍 PVE 升级。独占(不支持直通给多个虚拟机) 直通后,PVE 宿主不能同时用核显。
SRIOV 虚拟核显直通可分为多个 VF 虚拟显卡, 给不同的虚拟机使用。1、性能拆分(分成多个 VF 显卡具体如何分配性能不详) 如 N100 等不建议超过 3 个 VF 显卡,具有性能高核显的处理器可以分为最高 7 个); 2、不支持物理显示输出,虽可使用 Todesk 等软件远程桌面,但 CPU 占用率较高。在作为服务器的小主机上,让原本紧张的资源更加捉襟见肘。 3、对内核 header 依赖(6.1-6.5),PVE 升级受限。 4、兼容性稳定性一般,部分流媒体软件硬解/转码功能受限。

虚拟核显直通

1
2
3
4
5
6
7
8
9
10
11
12
13
apt install pve-kernel-$(uname -r)
proxmox-boot-tool kernel pin $(uname -r)
apt install pve-headers-$(uname -r)

wget https://github.com/moetayuko/intel-gpu-i915-backports/releases/download/I915MT65-24.1.19-6/intel-i915-dkms_1.24.1.19.240119.1.nodrm+i6-1_all.deb

apt update & apt install build-* pve-headers-$(uname -r) git dkms sysfsutils flex bison -y

wget -O /lib/firmware/updates/i915/tgl_guc_70.9.1.bin https://github.com/intel-gpu/intel-gpu-firmware/blob/main/firmware/tgl_guc_70.9.1.bin

dpkg -i intel-i915-dkms_1.24.1.19.240119.1.nodrm+i6-1_all.deb

vim /etc/default/grub

quiet 后添加 intel_iommu=on iommu=pt i915.enable_guc=3 i915.max_vfs=7

1
2
3
4
update-grub
update-initramfs -u

apt install -y sysfsutils
1
2
3
4
5
6
7
8
9
echo "devices/pci0000:00/0000:00:02.0/sriov_numvfs = 3" > /etc/sysfs.conf

----------------
#有修改虚拟核显数量的需求
nano /etc/sysfs.conf
#将原来写入的参数注释掉
#devices/pci0000:00/0000:00:02.0/sriov_numvfs = 3
#改成你需要的数量,例如下述为5个
devices/pci0000:00/0000:00:02.0/sriov_numvfs = 5
1
reboot
1
2
$ dkms status
intel-i915-dkms/1.24.1.19.240119.1.nodrm, 6.8.12-8-pve, x86_64: installed
1
2
3
4
$ dmesg |grep i915

...
[ 4.564128] i915 0000:00:02.0: Enabled 3 VFs
1
2
3
vim /etc/pve/qemu-server/100.conf

args: -set device.hostpci0.addr=02.0 -set device.hostpci0.x-igd-gms=0x2

参考


安装 Ubuntu

PVE(Proxmox VE)中的网络模型选择取决于 虚拟机的用途和性能需求。不同的网卡模型有不同的兼容性性能,以下是对比:

1. VirtIO(半虚拟化)(✅ 推荐)

  • 优点

    • 性能最佳,支持 高吞吐量低 CPU 开销
    • 延迟最低,适合高性能服务器、数据库、Web 服务等应用。
    • 现代 Linux(Ubuntu、Debian、CentOS)自带 VirtIO 驱动,无需额外安装。
  • 缺点

    • Windows 需要 手动安装 VirtIO 驱动(可以从这里下载)。

推荐用于:Linux 虚拟机、Windows(安装 VirtIO 驱动)、高性能应用

2. Intel E1000 / E1000E(🟡 兼容性好,但性能一般)

  • 优点

    • 兼容性非常好,几乎所有操作系统都自带驱动,无需额外安装。
    • 适用于老旧操作系统(如 Windows XP/2003)。
  • 缺点

    • CPU 开销大,数据包处理效率低。
    • 带宽限制在 1Gbps,无法发挥现代硬件的最大性能。

🟡 适用于:老旧操作系统(如 Windows XP/2003)、兼容性优先的环境

3. Realtek RTL8139(⚠️ 极老,几乎不推荐)

  • 优点

    • 兼容性好,适用于一些极老的操作系统(如 Windows 98)。
  • 缺点

    • 性能最差,带宽 100Mbps,完全跟不上现代网络需求。
    • 高 CPU 负载,不适合生产环境。

不推荐,除非你要运行 Windows 98 这类老系统。

4. VMware vmxnet3(🟡 适用于 VMware 兼容环境)

  • 优点

    • 适合从 VMware 迁移的虚拟机,可无缝兼容 VMware 环境。
    • 低 CPU 开销,性能比 Intel E1000 好。
  • 缺点

    • 需要安装 VMware Tools 才能正常工作,否则性能低下。
    • 如果不是从 VMware 迁移过来的 VM,VirtIO 仍然是更好的选择

🟡 适用于:从 VMware 迁移过来的虚拟机

总结

选项性能兼容性适用场景推荐度
VirtIO(半虚拟化)✅ 最佳需要驱动(Linux 自带,Windows 需安装)现代 Linux、Windows(安装驱动)、高吞吐应用⭐⭐⭐⭐⭐
Intel E1000/E1000E🟡 一般无需驱动老旧 Windows/Linux 兼容性优先⭐⭐⭐
Realtek RTL8139❌ 最差无需驱动极老系统(Windows 98/2000)
VMware vmxnet3🟡 较好需要 VMware Tools从 VMware 迁移的 VM⭐⭐⭐

推荐

  • Linux(Ubuntu、Debian、CentOS)→ 选 VirtIO
  • Windows(10/11/Server)→ 选 VirtIO(安装 VirtIO 驱动)
  • Windows XP/2003 → 选 Intel E1000
  • VMware 迁移过来的 VM → 选 vmxnet3

✅ 最终建议:如果是 Linux 或现代 Windows,请使用 VirtIO(半虚拟化),它的性能最佳。

开启 SSH 登录

  1. 安装 openssh-server

    1
    sudo apt install openssh-server
  2. 安装完成后,SSH 服务默认自动启动,你可以通过以下命令校验服务运行状态:

    1
    sudo systemctl status ssh
  3. 如果你启用了防火墙,请确保防火墙打开了 SSH 端口,命令如下:

    1
    sudo ufw allow ssh
  4. 允许远程登录

    1
    2
    3
    sudo nano /etc/ssh/sshd_config
    # 修改配置
    PubkeyAuthentication yes
  5. 重启 ssh 服务

    1
    service ssh restart

开启远程桌面

因为通过 PVE 控制台链接 Ubuntu 后, 进入设置页面打开远程桌面老是卡死, 所以直接通过命令行操作.

1
sudo apt update && sudo apt install xrdp -y && sudo systemctl enable --now xrdp

安装 docker

1
2
3
4
5
6
7
8
sudo apt remove -y docker docker-engine docker.io containerd runc \
$$ sudo mkdir -p /etc/apt/keyrings \
&& curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo tee /etc/apt/keyrings/docker.asc > /dev/null \
&& sudo chmod a+r /etc/apt/keyrings/docker.asc \
&& sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg /etc/apt/keyrings/docker.asc \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null \
&& sudo apt update \
&& sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

直通 nvme

因为同品牌 nvme 固态硬盘在 PVE WebUI 的硬件列表中无法区分, 所以需要在命令行在找到具体的 PCI ID 才能直通给虚拟机, 避免错误的将安装了 PVE 系统的 nvem 分配给虚拟机导致 PVE 崩溃.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 查看 nvme 的 PCI 列表
$ lspci | grep -i nvme

01:00.0 Non-Volatile memory controller: Yangtze Memory Technologies Co.,Ltd ZHITAI TiPro5000 NVMe SSD (rev 01)
81:00.0 Non-Volatile memory controller: Yangtze Memory Technologies Co.,Ltd ZHITAI TiPro5000 NVMe SSD (rev 01)

# 查看系统安装在哪块盘
$ lsblk -o NAME,MAJ:MIN,RM,TYPE,SIZE,MOUNTPOINT,UUID

NAME MAJ:MIN RM TYPE SIZE MOUNTPOINT UUID
nvme0n1 259:0 0 disk 953.9G
└─nvme0n1p1 259:2 0 part 953.9G 1a8fd1dd-021a-4e59-bcde-d77502ecc0e7
nvme1n1 259:1 0 disk 953.9G
├─nvme1n1p1 259:3 0 part 1007K
├─nvme1n1p2 259:4 0 part 1G /boot/efi 4773-0652
└─nvme1n1p3 259:5 0 part 952.9G 5v5ZMp-dJCX-EEep-rBgv-U5ry-q4E4-8vGhuC
├─pve-swap 252:0 0 lvm 8G [SWAP] ad3ef0fd-b31a-49a3-b72d-8a059358f99a
├─pve-root 252:1 0 lvm 96G / 877cad13-9e68-4d5c-b4bf-fe92ffc241d8
├─pve-data_tmeta 252:2 0 lvm 8.3G
│ └─pve-data-tpool 252:4 0 lvm 816.2G
│ ├─pve-data 252:5 0 lvm 816.2G
│ └─pve-vm--102--disk--0 252:6 0 lvm 32G
└─pve-data_tdata 252:3 0 lvm 816.2G
└─pve-data-tpool 252:4 0 lvm 816.2G
├─pve-data 252:5 0 lvm 816.2G
└─pve-vm--102--disk--0 252:6 0 lvm 32G

上面的输出得知 PVE 安装在 nvme1n1, 因此 nvme0n1 就是应该直通给虚拟机的盘, 让我们找出它的 PCI ID:

1
2
3
4
$ udevadm info -q path -n /dev/nvme0n1 | grep -oP '\d+:\d+\.\d+'

00:01.0
01:00.0

找到了: 01:00.0.

或者这样也行:

1
2
3
4
5
$ cd /sys/block/nvme0n1/device && ls -al

...
lrwxrwxrwx 1 root root 0 Feb 19 17:23 device -> ../../../0000:01:00.0
...

LVM 扩容

刚开始只给了 32G 磁盘, 后面光安装显卡驱动就不够用了, 所以在 PVE 控制天新添加了 100G 空间给 Ubuntu:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
➜  ~ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0 7:0 0 73.9M 1 loop /snap/core22/1748
loop1 7:1 0 44.4M 1 loop /snap/snapd/23545
sda 8:0 0 32G 0 disk
├─sda1 8:1 0 1M 0 part
├─sda2 8:2 0 2G 0 part /boot
└─sda3 8:3 0 30G 0 part
├─ubuntu--vg-ubuntu--lv 252:0 0 15G 0 lvm /
└─ubuntu--vg-lv--0 252:1 0 15G 0 lvm /home
sdb 8:16 0 100G 0 disk
sr0 11:0 1 2.6G 0 rom
nvme0n1 259:0 0 953.9G 0 disk
└─nvme0n1p1 259:1 0 953.9G 0 part

其中 sdb 是新增的磁盘, 需要将这 100G 空间添加到根分区中:

1
2
3
4
5
6
7
8
9
10
11
12
# 将 sdb 添加为一个物理卷(PV):
sudo pvcreate /dev/sdb
# 将新创建的物理卷添加到现有的卷组中
sudo vgextend ubuntu-vg /dev/sdb
# 扩展的是根分区(/dev/ubuntu-vg/ubuntu-lv)
sudo lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv
# 扩展完逻辑卷后,需要扩展文件系统,使其能够使用新的空间(ext4 文件系统)
sudo resize2fs /dev/ubuntu-vg/ubuntu-lv
# xfs 文件系统
# sudo xfs_growfs /dev/ubuntu-vg/ubuntu-lv
# 检查文件系统是否成功扩展
df -h

参考:

磁盘共享

Ceph 节点简介

  • Ceph MON:Ceph 监视器(Monitor),负责维护集群状态映射,帮助协调 Ceph 守护进程,并负责管理守护进程与客户端之间的身份验证。通常需要至少三个 MON 节点。
  • Ceph MGR:Ceph 管理器守护进程(Manager Daemon),负责跟踪运行时指标和 Ceph 当前运行状态,并负责管理和公开 Ceph 集群信息。通常需要至少两个 MAN 节点。
  • Ceph OSD:Ceph 对象存储守护进程(Object Storage Daemon),负责存储数据、处理数据复制、恢复、重新平衡,并通过检查其他 OSD 心跳向 Ceph 监视器和管理器提供监视信息。通常需要至少三个 OSD 节点。
  • Ceph MDS:Ceph 元数据服务器(Metadata Server),负责存储元数据,并允许 CephFS 用户运行基本命令,而不为 Ceph 存储集群带来负担。

时间同步

1
2
3
apt install ntpdate -y

ntpdate ntp1.aliyun.com
1
2
3
crontab -e

0 0 * * 6 ntpdate ntp1.aliyun.com

安装 Ceph

直接在 PVE Web 端安装, 但是安装后报错:

1
rados_connect failed - No such file or directory (500)

原因是 MON 节点启动失败, 但是在 Web 端有没有 MON 节点显示, 创建的时候报错:

1
Multiple IPs for ceph public network '192.168.31.99/24' detected on nuc: 192.168.31.99 192.168.31.9 use 'mon-address' to specify one of them. (500)

所以直接使用命令行来处理:

1
2
3
4
# NUC 节点
pveceph mon create --mon-address 192.168.31.99
# Station 节点
pveceph mon create --mon-address 192.168.31.66

配置 Ceph

NUC 节点上的 nvme:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
nvme3n1 259:0 0 953.9G 0 disk
nvme2n1 259:1 0 953.9G 0 disk
nvme1n1 259:2 0 931.5G 0 disk
├─nvme1n1p1 259:3 0 1007K 0 part
├─nvme1n1p2 259:4 0 1G 0 part /boot/efi
└─nvme1n1p3 259:5 0 930.5G 0 part
├─pve-swap 252:0 0 8G 0 lvm [SWAP]
├─pve-root 252:1 0 96G 0 lvm /
├─pve-data_tmeta 252:2 0 8.1G 0 lvm
│ └─pve-data-tpool 252:4 0 794.3G 0 lvm
│ ├─pve-data 252:5 0 794.3G 1 lvm
│ ├─pve-vm--100--disk--0 252:6 0 4M 0 lvm
│ ├─pve-vm--100--disk--1 252:7 0 200G 0 lvm
│ ├─pve-vm--100--disk--2 252:8 0 4M 0 lvm
│ └─pve-vm--103--disk--0 252:9 0 128G 0 lvm
└─pve-data_tdata 252:3 0 794.3G 0 lvm
└─pve-data-tpool 252:4 0 794.3G 0 lvm
├─pve-data 252:5 0 794.3G 1 lvm
├─pve-vm--100--disk--0 252:6 0 4M 0 lvm
├─pve-vm--100--disk--1 252:7 0 200G 0 lvm
├─pve-vm--100--disk--2 252:8 0 4M 0 lvm
└─pve-vm--103--disk--0 252:9 0 128G 0 lvm
nvme0n1 259:6 0 931.5G 0 disk

所以有 nvme0n1, nvme2n1nvme3n1 可以使用, Station 上的 nvme:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
nvme0n1 259:0 0 953.9G 0 disk
├─nvme0n1p1 259:1 0 1007K 0 part
├─nvme0n1p2 259:2 0 1G 0 part /boot/efi
└─nvme0n1p3 259:3 0 952.9G 0 part
├─pve-swap 252:0 0 8G 0 lvm [SWAP]
├─pve-root 252:1 0 96G 0 lvm /
├─pve-data_tmeta 252:2 0 8.3G 0 lvm
│ └─pve-data-tpool 252:4 0 816.2G 0 lvm
│ ├─pve-data 252:5 0 816.2G 1 lvm
│ ├─pve-vm--102--disk--0 252:6 0 32G 0 lvm
│ └─pve-vm--102--disk--1 252:7 0 100G 0 lvm
└─pve-data_tdata 252:3 0 816.2G 0 lvm
└─pve-data-tpool 252:4 0 816.2G 0 lvm
├─pve-data 252:5 0 816.2G 1 lvm
├─pve-vm--102--disk--0 252:6 0 32G 0 lvm
└─pve-vm--102--disk--1 252:7 0 100G 0 lvm

上面是 PVE 系统盘, 另一块直通给 Ubuntu 使用了, 所以没有显示出来, 这个在数据迁移完成后再处理, 我们先将 NUC 节点的 3 块 nvme 添加到 OSD.

这里将每块 NVMe 盘拆分为 4 个分区,然后 将这些分区分别添加为独立的 OSD。这样可以让 Ceph 更加 高效利用 NVMe 资源,同时 减少 IO 阻塞,提高并发性能。

1
2
3
4
5
6
7
for disk in /dev/nvme0n1 /dev/nvme2n1 /dev/nvme3n1; do
parted --script $disk mklabel gpt
parted --script $disk mkpart primary 0% 25%
parted --script $disk mkpart primary 25% 50%
parted --script $disk mkpart primary 50% 75%
parted --script $disk mkpart primary 75% 100%
done
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
nvme3n1 259:0 0 953.9G 0 disk
├─nvme3n1p1 259:11 0 238.5G 0 part
├─nvme3n1p2 259:16 0 238.5G 0 part
├─nvme3n1p3 259:21 0 238.5G 0 part
└─nvme3n1p4 259:22 0 238.5G 0 part
nvme2n1 259:1 0 953.9G 0 disk
├─nvme2n1p1 259:12 0 238.5G 0 part
├─nvme2n1p2 259:13 0 238.5G 0 part
├─nvme2n1p3 259:17 0 238.5G 0 part
└─nvme2n1p4 259:18 0 238.5G 0 part
nvme1n1 259:2 0 931.5G 0 disk
├─nvme1n1p1 259:3 0 1007K 0 part
├─nvme1n1p2 259:4 0 1G 0 part /boot/efi
└─nvme1n1p3 259:5 0 930.5G 0 part
└─ ...
nvme0n1 259:6 0 931.5G 0 disk
├─nvme0n1p1 259:8 0 232.9G 0 part
├─nvme0n1p2 259:9 0 232.9G 0 part
├─nvme0n1p3 259:10 0 232.9G 0 part
└─nvme0n1p4 259:14 0 232.9G 0 part

使用 pveceph osd create 命令,将这些分区作为 OSD:

1
2
3
4
5
$ for part in {1..4}; do
pveceph osd create /dev/nvme0n1p$part
pveceph osd create /dev/nvme2n1p$part
pveceph osd create /dev/nvme3n1p$part
done

检查结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ ceph osd tree
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-1 2.77271 root default
-3 2.77271 host nuc
0 ssd 0.22739 osd.0 up 1.00000 1.00000
1 ssd 0.23289 osd.1 up 1.00000 1.00000
2 ssd 0.23289 osd.2 up 1.00000 1.00000
3 ssd 0.22739 osd.3 up 1.00000 1.00000
4 ssd 0.23289 osd.4 up 1.00000 1.00000
5 ssd 0.23289 osd.5 up 1.00000 1.00000
6 ssd 0.22739 osd.6 up 1.00000 1.00000
7 ssd 0.23289 osd.7 up 1.00000 1.00000
8 ssd 0.23289 osd.8 up 1.00000 1.00000
9 ssd 0.22739 osd.9 up 1.00000 1.00000
10 ssd 0.23289 osd.10 up 1.00000 1.00000
11 ssd 0.23289 osd.11 up 1.00000 1.00000

接下来还需要配置存储池, 并将存储池添加到 RBD 和 CephFS.

使用

在 PVE 虚拟机中挂载 CephFS

  1. 创建 CephFS:

    1
    ceph fs new cephfs cephfs_metadata cephfs_data
  2. 添加到 PVE Web UI 中的 CephFS:

  3. 在 VM 或 LXC 中挂载 CephFS:

    1
    2
    mkdir /mnt/cephfs
    mount -t ceph 192.168.31.99:6789:/ /mnt/cephfs -o name=admin,secret=<ceph-secret>

在虚拟机中使用 RBD(块存储)

  1. 查看 Ceph 存储池:

    1
    rbd pool ls
  2. 创建 RBD:

    1
    rbd create --size 10G vm_storage/test-disk
  3. 在 VM 内部映射 RBD 磁盘并进行基本设置:

    1
    2
    3
    rbd map vm_storage/test-disk --name client.admin
    mkfs.ext4 /dev/rbd0
    mount /dev/rbd0 /mnt

参考:

PVE 上使用 Ceph 的想法算了总结了, 太复杂了, 现在 12 个 OSD 跑了一晚上数据还没有同步完成, 所以打算玩玩 ZFS, 家用应该也够了.

For Best Performance - Proxmox Cluster with CEPH or ZFS?

卸载 Ceph 🙉

1. 停止并禁用 Ceph 服务

首先,确保停止所有与 Ceph 相关的服务,包括 Monitor(mon)OSDMDSManager(mgr) 等:

1
2
3
4
systemctl stop ceph-mon.target
systemctl stop ceph-osd.target
systemctl stop ceph-mgr.target
systemctl stop ceph-mds.target

然后,禁用这些服务,以确保它们不会在系统重启后自动启动:

1
2
3
4
systemctl disable ceph-mon.target
systemctl disable ceph-osd.target
systemctl disable ceph-mgr.target
systemctl disable ceph-mds.target

2. 卸载 Ceph 软件包

卸载所有 Ceph 相关的包:

1
apt-get remove --purge ceph ceph-common ceph-mds ceph-mon ceph-osd ceph-mgr ceph-fuse librados2 librgw1 libcephfs1 librados-dev librgw-dev libboost-iostreams1.58.0 libboost-filesystem1.58.0 libboost-system1.58.0 librados2 librgw1

这将删除所有 Ceph 相关的软件包及其依赖。

3. 删除 Ceph 配置和数据

删除 Ceph 的配置文件和数据目录:

1
2
3
rm -rf /etc/ceph
rm -rf /var/lib/ceph
rm -rf /var/log/ceph

这些目录包含了 Ceph 的所有配置、日志和数据文件。

4. 清理 LVM 卷和 Ceph OSD 数据

如果您使用了 LVM 来管理 Ceph OSD,确保删除所有的 LVM 卷和卷组。首先,查看当前的 LVM 配置:

1
2
3
sudo lvdisplay
sudo vgdisplay
sudo pvdisplay

如果存在 Ceph 使用的 LVM 逻辑卷卷组物理卷,可以使用以下命令删除它们:

  1. 删除 LVM 逻辑卷:
1
sudo lvremove /dev/ceph/<volume_group>/<logical_volume>
  1. 删除 LVM 卷组:
1
sudo vgremove <volume_group>
  1. 删除物理卷:
1
sudo pvremove /dev/<device>
  1. 删除 Ceph OSD 设备:
1
sudo wipefs -a /dev/<device>   # 用实际的设备路径替换 <device>

5. 删除 Ceph 相关的系统服务文件

清理 Ceph 服务文件,确保没有服务文件残留:

1
2
3
4
5
rm -f /etc/systemd/system/ceph-*
rm -f /etc/systemd/system/ceph-mgr@*.service
rm -f /etc/systemd/system/ceph-mon@*.service
rm -f /etc/systemd/system/ceph-mds@*.service
rm -f /etc/systemd/system/ceph-osd@*.service

6. 清除 Ceph 集群配置和密钥

如果还没有删除 Ceph 集群的密钥环和配置文件,可以手动清理:

1
2
3
rm -f /etc/ceph/ceph.client.admin.keyring
rm -f /etc/ceph/ceph.mon.keyring
rm -f /etc/ceph/ceph-osd.keyring

7. 删除 ceph-crash

1
2
3
4
5
6
7
systemctl stop ceph-crash
systemctl disable ceph-crash
systemctl mask ceph-crash

rm -rf /etc/systemd/system/multi-user.target.wants/ceph-crash.service
rm -rf /var/lib/ceph/crash
rm -f /usr/bin/ceph-crash

8. 清理网络和存储设置

如果配置了 Ceph 使用的特定 网络接口防火墙规则,请手动清理这些设置:

  • 清理防火墙规则:使用 iptables 或 firewalld 清理 Ceph 使用的端口。

  • 删除 虚拟网络接口(如 virtio 等)和 存储挂载点

9. 重启系统

完成以上步骤后,最好重启系统以确保所有 Ceph 组件完全卸载:

1
reboot

10. 检查系统状态

重启后,可以使用以下命令检查系统中是否仍然存在与 Ceph 相关的进程或配置:

  1. 检查是否有 Ceph 相关的进程:
1
ps aux | grep ceph
  1. 检查 Ceph 配置是否被完全清除:
1
2
ls /etc/ceph
ls /var/lib/ceph
  1. 检查 LVM 是否有残留的 Ceph 卷:
1
sudo lvdisplay
  1. 使用以下命令检查系统日志是否仍有 Ceph 相关的错误:
1
tail -f /var/log/syslog

ZFS

我 2 块 1T 的 pcie4 Gen3 的 nvme 固态硬盘, 分别是 nvme2n1 和 nvme3n1, 还有一块 1T 的 pcie4 Gen4: nvme0n1. 而且后期我可能还会增加其他 nvme 和 ssd. 现在我想在 pve 集群中使用 ZFS, 初步计划是让 nvme0n1 划分为 2 个分区, 分别作为 zfs 的读写缓存, 而其他盘作为数据盘.

下面是具体操作:

1
2
3
4
5
6
7
parted /dev/nvme0n1

(parted) mklabel gpt
(parted) print
(parted) mkpart primary 0GB 500GB
(parted) mkpart primary 500GB 100%
(parted) quit
1
2
3
4
5
6
7
zpool create nvmes mirror /dev/nvme2n1 /dev/nvme3n1

zfs set secondarycache=all nvmes
zfs set recordsize=128k nvmes

zpool add nvmes cache /dev/nvme0n1p1
zpool add nvmes log /dev/nvme0n1p2

20250221012158_iZntJA26.webp

使用

1. 在 PVE 宿主机中使用 ZFS 存储

PVE 支持直接在宿主机中使用 ZFS 存储池。可以将 ZFS 存储池挂载到宿主机的特定目录,然后将虚拟机和 LXC 容器配置为使用该存储。

挂载 ZFS 存储:

1
zfs set mountpoint=/mnt/nvmes nvmes

这将把你的 mypool ZFS 存储池挂载到 /mnt/nvmes 目录。可以在这个目录下创建文件并访问。

创建 ZFS 快照:

如果你想对 ZFS 存储池进行快照,可以使用:

1
zfs snapshot nvmes@snapshot_name

2. 在虚拟机中使用 ZFS 存储

要在虚拟机中使用 ZFS 存储,可以通过以下两种方式:

方式 1: 使用 ZFS 作为虚拟机的磁盘

在宿主机中创建一个 ZFS 数据集作为虚拟机的磁盘:

1
zfs create nvmes/nvmes-disk

在 PVE 中的虚拟机配置中,将 nvmes/nvmes-disk 数据集作为虚拟磁盘挂载给虚拟机。例如,通过 PVE Web 界面,可以在虚拟机的硬盘设置中选择该数据集,或者通过命令行使用:

1
qm set VMID -ide0 /dev/zvol/nvmes/nvmes-disk

方式 2: 使用 ZFS 文件共享给虚拟机

如果不希望直接将 ZFS 存储池作为虚拟磁盘,可以将 ZFS 存储池中的某个目录挂载为共享目录,虚拟机通过网络访问。

  1. 在宿主机中创建目录:
1
mkdir /mnt/nvmes/share
  1. 设置权限:
1
chmod -R 777 /mnt/nvmes/share
  1. 在虚拟机内挂载 NFS 或 Samba 共享(见下面的“共享 ZFS 存储到局域网”部分)。

3. 在 LXC 容器中使用 ZFS 存储

LXC 容器与虚拟机类似,也可以直接访问宿主机上的 ZFS 存储池。可以通过以下方式将 ZFS 存储挂载到容器内部:

  1. 挂载 ZFS 存储到容器目录:

可以将宿主机上的 ZFS 存储池挂载到容器的某个目录。假设将 nvmes/share 挂载到容器中的 /mnt/storage,可以在容器配置中添加以下配置:

编辑 /etc/pve/lxc/VMID.conf 配置文件,添加:

1
mp0: /mnt/nvmes/share,mp=/mnt/storage
  1. 重新启动容器:
1
pct restart VMID

容器就能访问宿主机上的 ZFS 存储了。

4. 在局域网中共享 ZFS 存储

如果希望将 ZFS 存储共享给局域网中的其他设备(比如其他计算机、服务器或虚拟机),可以使用 NFS 或 Samba。

使用 NFS 共享 ZFS 存储:

  1. 安装 NFS 服务:
1
apt install nfs-kernel-server
  1. 配置 NFS 共享目录:

在 /etc/exports 文件中添加 ZFS 存储目录:

1
/mnt/nvmes/share *(rw,sync,no_subtree_check)
  1. 重新启动 NFS 服务:
1
systemctl restart nfs-kernel-server
  1. 在客户端(其他计算机)挂载共享:
1
mount -t nfs <宿主机_IP>:/mnt/nvmes/share /mnt/nfs_share

使用 Samba 共享 ZFS 存储:

  1. 安装 Samba:
1
apt install samba
  1. 配置共享目录:

编辑 /etc/samba/smb.conf 文件,添加以下配置:

1
2
3
4
5
6
7
[nvmes]
path = /mnt/nvmes
browsable = yes
read only = no
guest ok = yes # 允许匿名访问
create mask = 0775 # 设置文件的创建权限
directory mask = 0775 # 设置目录的创建权限
1
2
chmod -R 775 /mnt/nvmes
chown -R nobody:nogroup /mnt/nvmes
  1. 重启 Samba 服务:
1
systemctl restart smbd
  1. 在客户端(其他计算机)访问共享:

通过 smb:// 协议挂载共享:

1
smbclient //宿主机_IP/nvmes

网络

qemu-guest-agent

虚拟机执行命令:

1
2
3
sudo apt install qemu-guest-agent -y

sudo systemctl start qemu-guest-agent

不过报错了:

1
2
3
4
5
(base) ➜  ~ sudo systemctl start qemu-guest-agent
^@A dependency job for qemu-guest-agent.service failed. See 'journalctl -xe' for details.

Feb 20 06:26:26 ai systemd[1]: dev-virtio\x2dports-org.qemu.guest_agent.0.device: Job dev-virtio\x2dports-org.qemu.guest_agent.0.device/start timed out.
Feb 20 06:26:26 ai systemd[1]: Timed out waiting for device dev-virtio\x2dports-org.qemu.guest_agent.0.device - /dev/virtio-ports/org.qemu.guest_agent.0.

虚拟机内的 QEMU Guest Agent 无法找到 /dev/virtio-ports/org.qemu.guest_agent.0 设备,通常是因为 PVE 的 VM 配置没有正确启用 QEMU Guest Agent

所以需要在 PVE 宿主机上开启虚拟机的 Guest Agent:

1
2
3
qm set 102 --agent enabled=1

qm reboot 102

然后还是启动失败:

1
2
3
4
5
6
7
8
(base) ➜  ~ sudo systemctl status qemu-guest-agent
○ qemu-guest-agent.service - QEMU Guest Agent
Loaded: loaded (/usr/lib/systemd/system/qemu-guest-agent.service; static)
Active: inactive (dead)

Feb 20 06:34:46 ai systemd[1]: qemu-guest-agent.service: Bound to unit dev-virtio\x2dports-org.qemu.guest_agent.0.device, but unit isn't active.
Feb 20 06:34:46 ai systemd[1]: Dependency failed for qemu-guest-agent.service - QEMU Guest Agent.
Feb 20 06:34:46 ai systemd[1]: qemu-guest-agent.service: Job qemu-guest-agent.service/start failed with result 'dependency'.

查阅资料后发现是需要添加一个 virtio-serial 的设备:

1
2
3
qm set 102 -serial0 socket

qm reboot 102

然后再次启动 agent:

1
2
3
4
5
6
7
8
9
10
11
12
(base) ➜  ~ sudo systemctl status qemu-guest-agent
● qemu-guest-agent.service - QEMU Guest Agent
Loaded: loaded (/usr/lib/systemd/system/qemu-guest-agent.service; static)
Active: active (running) since Thu 2025-02-20 06:37:46 UTC; 3s ago
Main PID: 1549 (qemu-ga)
Tasks: 2 (limit: 38427)
Memory: 416.0K (peak: 840.0K)
CPU: 5ms
CGroup: /system.slice/qemu-guest-agent.service
└─1549 /usr/sbin/qemu-ga

Feb 20 06:37:46 ai systemd[1]: Started qemu-guest-agent.service - QEMU Guest Agent.

显示启动成功了, 能够正常获取 IP 信息:

20250221012204_Kp7lflpS.webp

服务器上查看虚拟机信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
qm agent <vmid> <cmd>

fsfreeze-freeze
fsfreeze-status
fsfreeze-thaw
fstrim #查看ssd——trim
get-fsinfo #查看磁盘信息
get-host-name #查看主机名
get-memory-block-info #查看内存块 信息
get-memory-blocks #查看您内存
get-osinfo #查看系统信息
get-time #查看时间
get-timezone #查看时区
get-users #用户
get-vcpus #查看CPU数量
info #查看支持的命令
network-get-interfaces #查看网络
ping #不明
shutdown #关机
suspend-disk #休眠,储存到硬盘
suspend-hybrid #休眠,混合
suspend-ram #挂起/休眠 内存

参考:

删减 PCIe 设备后网卡名称变更

网卡名称发生变化是因为系统使用了 udev(设备管理器)来自动为网络接口分配名称,默认使用 Predictable Network Interface Names(可预测的网络接口名称)规则。这个规则基于网卡的硬件地址(MAC 地址)或者设备路径(例如 PCI 地址)来命名网卡。

当拔掉 GPU 后,系统可能重新分配了网卡接口的名称,这主要是因为 PCI 插槽顺序、设备初始化顺序等因素的变化,导致了 udev 给网卡分配了不同的名称。

这会导致 PVE 系统中已经配置好的网络会无法获取 IP.

我们可以 通过 udev 规则固定网卡名称:

1
2
3
4
5
6
vim /etc/udev/rules.d/99-network.rules

SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="1c:69:7a:d0:c5:11", NAME="enp92s0"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="18:9b:a5:80:5a:22", NAME="enp2s0f0"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="18:9b:a5:80:5a:33", NAME="enp2s0f1"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="28:df:eb:5c:ab:44", NAME="wlp91s0"

重新加载 udev 规则:

1
udevadm control --reload

我重新加载后没有生效, 是重启解决的

这样,系统每次启动时,都会根据这个规则将指定的网卡名称固定为你指定的名称。


4G 网卡拨号(qmi_wwan)

1
2
sudo apt update
sudo apt install libqmi-utils udhcpc

配置 4G 网卡并拨号上网

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查看系统中识别到的 QMI 设备
qmicli -d /dev/cdc-wdm0 --device-open-proxy --dms-get-model

# 获取 4G 卡的设备 ID 信息
qmicli -d /dev/cdc-wdm0 --device-open-proxy --dms-get-ids

# 获取 4G 卡的 SIM 卡状态
qmicli -d /dev/cdc-wdm0 --device-open-proxy --uim-get-card-status

# 获取网络信号强度信息
qmicli -d /dev/cdc-wdm0 --device-open-proxy --nas-get-signal-strength

# 获取运营商网络状态
qmicli -d /dev/cdc-wdm0 --device-open-proxy --nas-get-serving-system

# 设置 APN 并启动拨号连接(替换 `your_apn` 为实际 APN)[中国移动:cmnet 中国联通:3gnet 中国电信:ctnet]
qmicli -d /dev/cdc-wdm0 --device-open-proxy --wds-start-network="apn=your_apn,ip-type=4" --client-no-release-cid

获取拨号后的网络配置

1
2
# 获取当前网络配置,包括 IP 地址、子网掩码和网关
qmicli -d /dev/cdc-wdm0 --device-open-proxy --wds-get-current-settings

配置动态获取 IP(DHCP)

1
2
3
4
5
6
7
# 为 wwan0 接口配置 DHCP 动态获取 IP 地址
sudo nano /etc/network/interfaces

# 在文件中添加以下内容
# 配置 wwan0 使用 DHCP 动态获取 IP 地址
auto wwan0
iface wwan0 inet dhcp

启动并检查网络接口

1
2
3
4
5
6
7
8
# 重启网络服务以使配置生效
sudo systemctl restart networking

# 确认 wwan0 接口已正确获取 IP 地址
ip a show wwan0

# 查看网络路由,确保默认路由通过 4G 网卡
ip route show

手动请求 DHCP 获取 IP(可选)

1
2
3
4
5
# 使用 dhclient 手动请求 DHCP 服务器分配 IP 地址
sudo dhclient wwan0

# 再次检查接口状态,确认是否已获取到 IP 地址
ip a show wwan0

添加默认路由(如果需要)

1
2
# 如果 IP 地址已正确分配,但默认路由没有设置,可以手动添加默认路由
sudo ip route add default via <your_gateway> dev wwan0

配置 DNS(可选)

1
2
3
# 手动添加 DNS 服务器
echo "nameserver 218.6.200.139" | sudo tee /etc/resolv.conf
echo "nameserver 61.139.2.69" | sudo tee -a /etc/resolv.conf

配置虚拟网络桥接(PVE)

1
2
3
4
5
6
7
8
9
10
11
12
# 编辑网络配置文件,确保 wwan0 接口桥接到虚拟网桥 vmbr0
sudo nano /etc/network/interfaces

# 添加如下配置,使虚拟机通过 4G 网络连接
auto vmbr0
iface vmbr0 inet static
address 10.165.54.10
netmask 255.255.255.0
gateway 10.165.54.153
bridge_ports wwan0
bridge_stp off
bridge_fd 0

测试网络连接

1
2
3
4
5
# 测试网络是否能正常连接到外部地址
ping 8.8.8.8

# 测试 DNS 是否能解析域名
dig @218.6.200.139 google.com

动态更新 IP 地址和路由(如果需要静态配置)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 创建脚本来动态更新 IP 地址和路由(当 IP 变化时)
sudo nano /etc/network/if-up.d/update-wwan0-ip

# 添加以下内容
#!/bin/bash
if [ "$IFACE" == "wwan0" ]; then
IP=$(ip addr show wwan0 | grep 'inet ' | awk '{print $2}' | cut -d/ -f1)
GATEWAY=$(ip route show dev wwan0 | grep default | awk '{print $3}')
DNS1="218.6.200.139"
DNS2="61.139.2.69"

# 更新 resolv.conf
echo "nameserver $DNS1" > /etc/resolv.conf
echo "nameserver $DNS2" >> /etc/resolv.conf

# 更新默认路由
ip route del default
ip route add default via "$GATEWAY"

# 更新 wwan0 的 IP 地址(仅在你使用静态 IP 时才需要)
ip addr add "$IP/30" dev wwan0
fi

# 赋予脚本执行权限
sudo chmod +x /etc/network/if-up.d/update-wwan0-ip

自动拨号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
vim /etc/systemd/system/qmi-network.service

[Unit]
Description=QMI 4G Network
After=network.target

[Service]
ExecStart=/usr/bin/qmicli -d /dev/cdc-wdm0 --device-open-proxy --wds-start-network="apn=ctnet,ip-type=4" --client-no-release-cid
ExecStartPost=/sbin/udhcpc -i wwan0
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
1
2
3
sudo systemctl daemon-reload
sudo systemctl enable qmi-network
sudo systemctl start qmi-network

参考

4G 网卡拨号(wvdial)

1
2
3
4
apt install wvdial

# 打开配置文件
vim /etc/wvdial.conf
1
2
3
4
5
6
7
8
9
10
11
12
# 电信
[Dialer T]
Init1 = ATZ
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
Modem Type = Analog Modem
Baud = 9600
New PPPD = yes
Modem = /dev/ttyUSB3
ISDN = 0
Phone = *99#
Password = card
Username = card

拨号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ wvdial  T
--> WvDial: Internet dialer version 1.61
--> Initializing modem.
--> Sending: ATZ
ATZ
OK
--> Sending: ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
OK
--> Modem initialized.
--> Sending: ATDT*99#
--> Waiting for carrier.
ATDT*99#
CONNECT 150000000
--> Carrier detected. Waiting for prompt.
--> Don't know what to do! Starting pppd and hoping for the best.
--> Starting pppd at Mon Feb 24 18:23:27 2025
--> Pid of pppd: 6407
--> Using interface ppp0
--> local IP address 10.165.54.154
--> remote IP address 10.64.64.64
--> primary DNS address 218.6.200.139
--> secondary DNS address 61.139.2.69

自动拨号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#! /bin/bash

#运行步骤变量初始化
ec20_step=0

#超时计数初始化
over_time=0

#循环
while [ 1 ]
do
#第一步先检查驱动
if [ $ec20_step -eq 0 ]; then
#使用lsusb查看是否有ec20驱动 grep查询结果是否包含Quectel
result=$(lsusb | grep Quectel)
echo "1. 检查驱动: " $result
if [[ $result =~ "EC25" ]]; then
ec20_step=1

else
ec20_step=0
fi
#延时2s
sleep 2
#第二步 开始使用 wvdial 拨号
elif [ $ec20_step -eq 1 ]; then
echo "2. wvdial 拨号"
echo "password" | sudo nohup wvdial T &
ec20_step=2

sleep 2
#第三步 查询路由是否包含 ppp0 网卡,拨号成功则会包含有 ppp0 网卡
elif [ $ec20_step -eq 2 ]; then
result=$(route -n | grep ppp0)

echo "3. 检查是否存在 ppp0 网卡" $result

if [[ $result =~ "ppp0" ]]; then
echo "3.1 包含网卡,添加默认路由"
#若包含网卡,则添加默认路由
echo "password" | sudo route add default dev ppp0
ec20_step=3
over_time=0
else
echo "3.2 不包含网卡, 再次循环查询, 循环次数:" $over_time
#超时计数
let over_time++
fi
#若一分钟都没有路由网卡则说明没有拨号成功
if [ $over_time -eq 12 ]; then
echo "12 次检查不存在路由网卡, 说明没有拨号成功, 进入重启逻辑"
over_time=0
#超时拨号则跳入重启步骤
ec20_step=4
fi

sleep 5
#第四步 通过 ping 命令检查网络状态
elif [ $ec20_step -eq 3 ]; then
result=$(ping -I ppp0 -c 1 www.baidu.com)

echo "4. 通过 ping 命令检查网络状态" $result

if [[ $result =~ "1 received" ]]; then
echo "4.1 ping 成功"
over_time=0
else
echo "4.2 ping 失败, 再次循环查询"
let over_time++

fi
#超时则杀掉拨号线程,并进入重启步骤
if [ $over_time -eq 6 ]; then
echo "6 次 ping 失败, 进入重启逻辑"
over_time=0
ec20_step=4
echo "password" | sudo pkill wvdial
fi
sleep 5

#第五步重启模块
elif [ $ec20_step -eq 4 ]; then
echo "重启网卡"
echo -e "AT+CFUN=1,1\r\n" > /dev/ttyUSB2
ec20_step=0
#重启命令后延时稍微长一点
sleep 15
fi

done
exit 0

Cloud-init

参考

备份

https://zhuanlan.zhihu.com/p/661921259

https://kb.synology.cn/zh-cn/DSM/tutorial/back_up_restore_proxmox_vm

参考

Debian 连接 USB 摄像头

1
2
3
$ lsusb

Bus 003 Device 004: ID 1bcf:2c6a Sunplus Innovation Technology Inc. 5M Cam

加载驱动

1
modprobe uvcvideo

检查摄像头设备文件

1
2
3
$ ls /dev/video*

/dev/video0 /dev/video1

安装 v4l-utils

v4l-utils 是用于视频设备的工具,可以测试和配置摄像头:

1
2
3
4
5
6
7
$ apt install v4l-utils

$ v4l2-ctl --list-devices
5M Cam: 5M Cam (usb-0000:00:14.0-6):
/dev/video0
/dev/video1
/dev/media0

推流:

1
ffmpeg -f v4l2 -i /dev/video0 -vcodec libx264 -preset ultrafast -tune zerolatency -f flv rtmp://192.168.31.7/live/stream

如果需要修改分辨率, 我们需要先支持摄像头支持哪些分辨率:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
$ v4l2-ctl --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
Type: Video Capture

[0]: 'YUYV' (YUYV 4:2:2)
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 800x600
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 320x240
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 352x288
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 1024x768
Interval: Discrete 0.125s (8.000 fps)
Size: Discrete 1280x720
Interval: Discrete 0.100s (10.000 fps)
Size: Discrete 1280x960
Interval: Discrete 0.125s (8.000 fps)
Size: Discrete 1600x1200
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 1920x1080
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 2592x1944
Interval: Discrete 0.333s (3.000 fps)
Size: Discrete 2048x1536
Interval: Discrete 0.333s (3.000 fps)
[1]: 'MJPG' (Motion-JPEG, compressed)
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 800x600
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 320x240
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 352x288
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 1024x768
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 1280x720
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 1280x960
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 1600x1200
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 1920x1080
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 2592x1944
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 2048x1536
Interval: Discrete 0.067s (15.000 fps)
1
ffmpeg -f v4l2 -i /dev/video0 -vcodec libx264 -preset ultrafast -tune zerolatency -s 1280x720 -f flv rtmp://192.168.31.7/live/stream

参数解析:

1. -f v4l2

  • 作用:指定输入格式为 v4l2,即使用 Video4Linux2 驱动来捕获视频流。

  • 背景:v4l2 是 Linux 系统中处理视频设备(例如 USB 摄像头)的视频驱动标准。此参数告诉 ffmpeg 使用 v4l2 驱动来捕获摄像头的实时视频流。

2. -i /dev/video0

  • 作用:指定输入视频源,这里是 /dev/video0,表示连接的 USB 摄像头设备。

  • 背景:在 Linux 系统中,视频设备通常以 /dev/videoX 的形式表示(X 是数字)。你可以通过 ls /dev/video* 命令查看设备名称,通常第一个摄像头是 /dev/video0。

3. -vcodec libx264

  • 作用:指定视频编码器使用 libx264,即 H.264 编码格式。

  • 背景:libx264 是一种高效的 H.264 视频编码器,广泛用于视频流和视频文件的压缩。H.264 是现代视频流媒体中的常见编码格式,因为它可以提供较高的压缩效率和质量。

4. -preset ultrafast

  • 作用:设置编码预设为 ultrafast,这是一个编码速度最快的设置,但会牺牲一定的视频压缩率。

  • 背景:preset 控制 libx264 编码的速度和压缩效率,选择较快的编码预设可以减少延迟。ultrafast 是最快的预设,但会使文件体积相对较大,适合低延迟的实时流。

5. -tune zerolatency

  • 作用:优化编码器以减少延迟。

  • 背景:tune 选项控制 libx264 编码器的调优模式。zerolatency 是一种专门用于低延迟流的设置,适用于直播、视频会议等实时应用。

6. -s 1280x720

  • 作用:设置输出视频的分辨率为 1280x720。

  • 背景:-s 选项用于设置输出视频的分辨率,1280x720 是常见的高清分辨率。如果你的摄像头支持更高的分辨率,可以根据需要进行调整。

7. -f flv

  • 作用:设置输出格式为 flv(Flash Video 格式)。

  • 背景:flv 是一种常用于流媒体传输的格式,尤其是在 RTMP(Real-Time Messaging Protocol)流媒体传输中。大部分流媒体服务器(如 NGINX 和 RTMP)支持这种格式。

8. rtmp://192.168.31.7/live/stream

  • 作用:指定 RTMP 服务器地址。

  • 背景:这是你要推送流的 RTMP 服务器地址。rtmp://192.168.31.7/live/stream 表示推送流到 IP 地址 192.168.31.7 上的 live/stream 路径。你可以根据自己的服务器地址和路径进行修改。