HomeLAB:思路和实现
背景
追剧的时候,没有什么比可以观看时需要等待漫长的下载更让人受折磨的了。旅行的时候,也没有什么比临时需要改程序参数,提供新版本下载更让人头疼的了。外出的时候,你可能会想,要是我能有一台能够连接到自己所有设备,同时位于云端的服务器,那该多好啊 —— 如果有这种服务器,你可以在平板上打开 VSCode 修改代码并触发远程编译,将结果自动上传到 CDN。如果有这种服务器,你可以在手机直接连接到自己远端的电脑,查看某个正在修改或填报的文件。如果有这种服务器,你可以在美剧更新时,第一时间打开远程的 Windows 虚拟机,用迅雷的国内加速服务下好资源,顺便勾选下载完成后关机。
这一切,只需要一个带有公网 IP 地址的微型 x86 PC 就可以实现。
架构
下面是我自己搭建的 HomeLAB 架构,这里要考虑的内容还是蛮多,比如暴露公共服务的安全问题,公网 IP 地址变更的 DDNS 问题,虚拟专用网的选择、搭建和多平台易用性问题。
ESXi Server
首先是一台微型 x86 PC,闲置的类 Mac Mini 即可,淘汰的笔记本电脑亦可,老旧的 x86 服务器当然更好,如果你不担心电耗和噪音的话。之后在它上面需要实现 All-in-One 的虚拟化,对于家用环境,两地三中心的文件存储方案自不必多提,重点是虚拟化的选择。有很多方式,最简单的是 Windows 上的 Hyber-V,Linux 上的 Docker,但出于可靠性和易用性的角度,我还是选择了 VMware ESXi,它提供了存储层的简单抽象,USB 设备的直通,同时支持大量不同操作系统的虚拟化,包括 Windows 虚拟机。最重要的是,ESXi 裸机消耗的资源,远远少于 Windows 裸机,更何况可以随时休眠,更高效的利用 CPU 和内存资源。
ESXi 对于家用是免费的,只需要注册博通的账号并下载即可。我选择了 8 核心的 Ryzen 7 5800H,搭配 32GB 的内存和 2TB 的存储空间,这足以支撑绝大多数家用场景。安装参考这篇文章。
下面是一些常用的 ESXi 命令:
reboot, poweroff, vmware -v(esxcli system version get)
esxcfg-info -a 所有信息,-w 硬件信息
esxtop 性能监控信息
vscsiStats I/O 负载信息
vmkfstools -i old.vmdk new.vmdk 磁盘格式转换,克隆
vmkping 通过 vMontion 网络发送 ping 包
nc -z IP PORT 确定某个地址 TCP 连通性,nc -uz 检查 UDP 端口
esxcfg-vmknic-l ESXI 的 IP 地址
esxcli 下命令最全,参见 esxcli esxcli command list,比如:
esxcli vm process list
esxcli network ip interface ipv4 get
vim-cmd 下包含了快捷命令。
- vim-cmd vmsvc/getallvms
- vim-cmd vmsvc/get.summary vm-id
- vim-cmd vmsvc/get.config vm-id 配置信息
- vim-cmd vmsvc/power.getstat vm-id
- vim-cmd vmsvc/power.shutdown vm-id
- vim-cmd vmsvc/power.on vm-id
- vim-cmd vmsvc/power.reset vm-id 先关后开
- vim-cmd vmsvc/power.suspend vm-id 挂起
vim-cmd vmsvc/power.off vm-id 强制关闭
如果要暴露 ESXi 的 WebUI,除了要设置路由器的端口转发外,还要配置 HTTPS 证书,以实现安全访问,参照这篇文章
对于 HTTPS 证书设置和轮换:
vim /etc/vmware/ssl/rui.crt, rui.key
/etc/init.d/hostd restart
/etc/init.d/vpxa restart
如果要放通 SSH 端口,则需要配置防火墙规则:
esxcli network firewall ruleset set --enabled=true --ruleset-id=sshClient
如果公网 IP 会变,那么需要创建一个 Linux 虚拟机,在 Docker 中部署一个 DDNS-GO 服务,我用的是 Cloudflare,让 DDNS-GO 定时通过 Cloudflare API 更新域名指向的 IP 地址即可:
docker run -d --name ddns-go --restart=always --net=host -v /home/改成自己的路径/ddns-go:/root jeessy/ddns-go
如果虚拟机挂掉,只留下 VMDK 磁盘,可以在 Linux 中通过如下方式挂载并救回数据。
找到可用的 loop 号:
fdisk -l | grep /dev/loop
df -h | grep /dev/loop
losetup
创建挂载点:
mkdir /mnt/vmdk
将 VMDK 挂载为 loopback 设备:
losetup /dev/loop30 /mnt/storage/vm-flat.vmdk
使用 parted 查找分区位置并挂在为新 loop:
sudo parted /dev/loop30
unit
B
print
quit
Model: Loopback device (loopback)
Disk /dev/loop30: 118111600640B
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1048576B 537919487B 536870912B fat32 boot, esp
2 537919488B 118110552063B 117572632576B ext4
losetup -o 537919488 /dev/loop31 /dev/loop30
将新 loop 挂载到文件系统:
mount /dev/loop31 /mnt/vmdk
Media Server
DSM 的安装网上很多,可以参照这篇文章。SMB、EMBY 等媒体服务器和文件共享服务,都可以在 DSM 上实现。
SMB
[debian-data]comment = Jie's file on Debian Server
path = /mnt/d
read only = no
browsable = yes
create mask = 0644
directory mask = 0775
veto files = /._*/.DS_Store/delete veto files = yes
媒体播放:
EMBY
直接关闭用户 transcoding 功能就行了,只允许 audio transcoding,因为网上的资源基本上都是 H.264 编码,所以使用起来没问题。关了之后,副作用是用户没法看其他编码的视频,但是一般种子都会写清楚是否 H.264 编码,所以可以认为这样做不存在问题。
sudo chown -R emby:emby backup/folder
基于 SMB 共享和 ESXi 的虚拟机备份,我们可以将 ESXi 上所有的虚拟机看作一种即用即弃的服务,随意安装、折腾它们,当出现故障的时候,回撤备份或重建虚拟机,对之前的 VMDK 磁盘数据进行恢复即可。
Home Assistant Server
网上有很多教程,这里就不赘述了。注意,小米智能家居提供了官方的 HA 集成,通过 Home Assistant Bridge 可以接入 Apple 的家庭,实现更方便的智能家居的控制。
docker run -d --name="home-assistant" -v /root/hc:/config -v /etc/localtime:/etc/localtime:ro --net=host registry.cn-hangzhou.aliyuncs.com/corkine/homeassistant_home-assistant:latest
Wireguard Server
Wireguard 对于远程访问 HomeLAB 及其虚拟机(通过 SSH 和 WebUI 即可),尤其是家庭网络中的任意设备具有非常重要的意义。通过部署一个 Ubuntu 24 的虚拟机,并利用 Linux 自带的路由功能和 Wireguard 客户端即可实现这一点。安装文档参见这里,可在官方网站下载 Android、Windows 客户端,macOS 和 iOS 客户端在非中国区 App Store 下载即可。我有自定义动态端口号的需求,因此分叉和修改了些内容,自行编译使用,仓库参见 Windows客户端 macOS 和 iOS客户端。
定制
由于经常需要临时开启、暂停虚拟机,使用 ESXi WebUI 并不方便,因此我写了一个 GUI 工具,通过远程 SSH 的方式执行虚拟机的开机、关机和休眠,以及 ESXi 服务器的关机。这个工具还管理着每台虚机暴露的端口号和对应服务,防止意外泄漏不安全的端点到公网。
此外,我有多个 Wireguard 组网,虽然 Wireguard 性能非常不错,但过于底层,因此也写了一个 GUI 工具来管理组网节点,包括公钥生成、私钥创建,QR 码快速导入导出,登录 Wireguard Server 一键放通新节点等功能:
最后,你就可以在任意远端通过 Wireguard 连接到 HomeLAB 组网内的任意设备了:
最后,基于这套 HomeLAB 实现两地三中心的备份,我是这样做的。首先,需要备份的内容有 OSS 对象存储、OneDrive 云盘和 iCloud 照片数据,以及 SMB Share 共享下载的影视内容,我的第一级备份是 HomeLAB,包括 Windows 系统挂载一整个虚拟磁盘同步 OneDrive 内容,Ubuntu 下通过 icloud-photos-sync 同步 iCloud 照片,rclone 同步 OSS 对象存储。第二级备份是自动的将上述内容复制到一个外挂的备份磁盘。第三级备份是定期将上述备份磁盘内容复制到异地的 NAS 中。