Building a Homelab VM Server (2020 Edition)

Michael Lynch

搭建家庭实验室虚拟机服务器(2020 版)

原文由 Michael Lynch 发布,订阅该博客

过去五年里,我所有的软件开发都在虚拟机(VM)中完成。每个项目都独占一台虚拟机,省去了处理依赖冲突和 TCP 端口冲突的麻烦。

三年前,我更进一步,自己搭建了一台家庭实验室服务器来托管所有虚拟机。这是一笔非常划算的投资,它加快了许多开发任务的速度,也提升了稳定性。

最近几个月,我开始触及这台虚拟机服务器的性能瓶颈。项目越来越吃资源,当初搭建时犯下的一些错误也开始带来麻烦。于是我决定在 2020 年全新打造一台家庭实验室虚拟机服务器。

我的新虚拟机服务器组件合照

我这台新虚拟机服务器的大部分组件(算是大部分吧)

不想看背景故事,直接看配置!

如果你对这个项目的“为什么”不感兴趣,可以直接跳到配置清单

为什么要专门搭建一台虚拟机服务器?

最初,我在 Windows 台式机上用 VirtualBox 跑虚拟机。起初还算顺手,但重启很快就成了大麻烦。

Windows Update 的强制重启、为完成软件安装而主动重启,再加上偶尔的系统崩溃,导致我每个月都得把整套开发用虚拟机重启三到五次。

一台专用的虚拟机服务器帮我省去了绝大多数重启。宿主机上只运行最精简的软件,因此崩溃和强制重启都很少见。

什么是“家庭实验室(homelab)”?

Homelab 只是近几年流行起来的一个俗称。家庭实验室服务器与其他服务器并无本质区别,只不过你是把它搭在家里,而不是放在办公室或数据中心。很多人把它当作低成本的练手环境,先在上面熟悉各种工具,再应用到真实的商业场景中。

为什么不用云计算?

云服务器也能实现同样的功能,还能省去(有趣的!)维护硬件的麻烦,但成本实在太高。要获得与我的家庭实验室服务器相当的虚拟机资源,AWS EC2 实例一年要花超过 6000 美元

显示 AWS EC2 实例一年需花费 6,112.68 美元的截图

如果用 AWS 来代替我的家庭实验室服务器,一年要多花 6000 多美元

我当然可以通过按需开关云实例来大幅降低成本,但那样会给工作流带来额外的摩擦。有了本地虚拟机服务器,我可以让 10 到 20 台虚拟机随时待命,无需为精打细算成本而操心。

吸取过去的教训

2017 年搭建的那台机器表现不错,但在三年使用过程中,我也逐渐发现了几个亟待改进的关键问题。

1. 存储要放在本地

我的群晖 NAS 有 10.9 TB 的存储空间。有这么多网络存储,我当时想:“除了够宿主机系统启动的最小空间,服务器上还有必要再加硬盘吗?”

显示 10.9 TB 存储空间的截图

第一次搭建时,我依赖的是 10.9 TB 的网络存储。

结果证明这是个馊主意。

首先,在网络存储上跑虚拟机会让虚拟机强依赖于存储服务器。群晖每隔一两个月就会发布一次系统更新,而且每次打补丁都必须重启。虚拟机跑在群晖的存储之上,意味着每次给群晖打更新,我都得先把所有虚拟机全部关掉。这又回到了当初在 Windows 台式机上跑虚拟机时的重启烦恼。

群晖系统升级界面的截图

存储服务器的操作系统需要频繁升级。

其次,通过网络进行随机磁盘访问非常慢。第一次搭建时,我主要做 Python 和 Go 的后端开发,磁盘 I/O 并不多。后来我开始涉及前端开发。现代前端框架都离不开 Node.js,每个项目的依赖树里都有 1 万到 20 万个零散的 JavaScript 文件。Node.js 的构建过程涉及大量随机磁盘访问,这对网络存储来说是最糟糕的场景。

2. 选更好的虚拟机管理软件

第一台服务器上,我在 KimchiVMware ESXi 之间做过对比。VMware 要成熟、完善得多,但 Kimchi 那种草根气质和开源属性打动了我。

Kimchi 网页界面的截图

通过 Kimchi 网页界面查看虚拟机列表的早期截图

结果我刚装好没多久,Kimchi 的开发就停滞了。

显示 Kimchi 仓库提交记录在我开始使用后不久便停止的图表

Kimchi 的代码提交记录,在我开始使用后不久就戛然而止

随着时间推移,Kimchi 的缺点越来越明显。我经常要点好几次虚拟机的“克隆”或“关机”按钮,它才有反应。还有让人抓狂的界面 bug——按钮会在你点下去的前一瞬间消失或错位。

3. 提前规划远程管理

我的旧虚拟机服务器照片

我的虚拟机服务器就塞在办公室的角落里,平时很方便,但偶尔需要物理接触时就很麻烦。

如果你看到上面会想:“Kimchi 不过是个软件,Michael 为什么为了换个虚拟机管理器就要重搭一整台服务器?”那是因为我当初没有预见到远程管理的重要性。

我的虚拟机服务器就是一台放在办公室角落、没接显示器和键盘的电脑。99% 的时间里通过 SSH 或网页界面就能搞定,完全没问题。但剩下 1% 的情况——比如服务器无法启动,或是想重装宿主机系统——就非常痛苦。我得把服务器拖到桌边,拔掉台式机的键鼠和显示器,修好问题后,再把办公室的一切恢复原状。

下一次搭建,我想要一个一开机就能获得物理级别访问权限的虚拟控制台。类似戴尔的 iDRAC惠普的 iLO 那样的方案。

戴尔 iDRAC 界面的截图

戴尔 iDRAC 是我考虑过的远程服务器管理方案之一。

硬件选型

CPU

我第一台虚拟机服务器的 CPU 是 Ryzen 7 1700。8 核 16 线程,当时可是炙手可热的新品。但当我在 /r/homelab(Reddit 的家庭实验室版块)上晒配置时,却被嘲笑为用消费级配件的“菜鸟”。大佬们用的都是企业级硬件。

Reddit 用户 /u/pylori 提问:‘兄弟,你真的算玩 homelab 吗?说真的,你担心企业级硬件会故障?它可比新的消费级硬件耐用多了。’

/r/homelab 对我的第一台机器不以为然

为了不再被 /r/homelab 嘲笑,我决定投身企业级服务器硬件的世界,甚至还玩起了花活,选了双路 CPU 的方案。

为了让每分钱都花在性能上,我把范围限定在发布已有四到八年的二手 CPU 上。对每个候选型号,我都会去 PassMark 上查跑分,然后在 eBay 上看该型号二手的近期成交价。

性价比最高的似乎是 Intel Xeon E5 v3 系列,尤其是 2600 型号。我最终选定了 E5-2680 v3。它的平均跑分是 15,618,在 eBay 上的二手价大约是 130 美元。

Intel Xeon E5-2680 v3 CPU 照片Xeon E5-2680 v3 在 cpubenchmark.net 上得分 15618 的截图

Intel Xeon E5-2680 v3 在 cpubenchmark.net 上的得分为 15,618

作为对比,我上一台机器的 Ryzen 7 跑分是 14,611。所以用上两颗 E5-2680,处理能力就能比旧服务器翻一倍还多。

主板

SuperMicro MBD-X10DAL-I-O 主板照片

双路系统的缺点是主板可选范围非常有限。只有少数几款主板支持双路 Intel 2011-v3 CPU,价格从 300 到 850 美元不等,远超我对主板的预算预期。

我选了 SuperMicro MBD-X10DAL-I-O,320 美元的价格在同类主板中算便宜的,但仍是我上一块主板价格的五倍。

内存

Crucial 内存条照片

服务器内存在选购时似乎没那么多有依据的选择。消费级硬件有大量网站会评测、跑分各种内存条,但服务器内存几乎找不到类似的信息。

我选了 Crucial CT4K16G4RFD4213 64GB(4 x 16GB),主要是信得过这个品牌。之所以选 64GB,是因为上一台机器是 32GB,有些工作流已经快把内存用满了,我想着翻倍应该能撑过未来几年。

存储

Samsung 860 EVO 照片

我很喜欢 M.2 固态硬盘,小巧、性能出色,还能直接插在主板上,不需要任何线缆。可惜 MBD-X10DAL 不支持 M.2 接口。

于是我只能用传统的 SATA。我买了一块 1TB Samsung 860 EVO。我一般给每台虚拟机分配 40GB 空间,所以 1TB 足够宽裕。以后如果需要升级,再加硬盘就是了。

电源

Corsair CX550M 550W 80 Plus Bronze 电源照片

选电源(PSU)没什么可说的,我还是按信得过的品牌选了 Corsair CX550M 550W 80 Plus Bronze

我所有配件的功耗加起来是 400W,所以 450W 本来就够了。但 550W 的版本只贵 10 美元,多 100W 的余量很划算。

对我来说另一个重要的特性是半模组线材。上一次搭建时,我犯了用非模组电源的错误,所有线缆都固定在电源上拆不下来。我的服务器内部本来就没多少配件,多余的电源线只会让机箱里一团乱。半模组则可以把用不到的线直接从电源上拔掉,保持整洁。

散热器

Hyper 212 CPU 散热器照片

双路搭建让散热成了意料之外的难题。MBD-X10DAL 的两个 CPU 插槽之间空间很小,所以我特意找了足够薄、能并排安装的散热器。一对 Cooler Master Hyper 212 刚好合适。

机箱

Fractal Meshify C 机箱照片

我的服务器低调地放在办公室角落,所以我不想要带透明侧板或炫彩灯光的机箱。

Fractal Design Meshify C Black 评价不错,看起来是个简洁、安静的机箱。

显卡

MSI GeForce GT 710 显卡照片

对于无头服务器来说,显卡并不重要。但在初次安装和偶尔调试时还是得能看到画面,所以我选了便宜省事的 MSI GeForce GT 710

远程管理

我研究了一下远程管理方案,结果被它们的价格吓了一跳。起初我想用戴尔的 iDRAC,但远程控制台需要 300 美元的企业授权,还会把整机限制在戴尔的配件体系内。我又看了 KVM over IP 方案,结果更贵,要 600 到 1000 美元。

Raritan Dominion KVM over IP 购买页面截图

市售的 KVM over IP 设备价格在 500 到 1000 美元之间。

为了实现远程管理,我走了一条不寻常的路——用树莓派自己做了一台 KVM over IP 设备。我把它叫做 TinyPilot

TinyPilot 连接到服务器的照片通过 TinyPilot 安装 Proxmox 的录屏

使用 TinyPilot 为服务器安装操作系统

TinyPilot 会捕获 HDMI 输出,并从浏览器转发键鼠输入。它提供的体验就跟你在机器上直连一套真实的键鼠和显示器一样。软件是开源的,我也提供做好的成品供购买。

我 2020 年的服务器配置

类别组件价格
CPUIntel Xeon E5-2680 v3(x2,二手)$264.82
主板SuperMicro MBD-X10DAL-I-O$319.99
硬盘Samsung 860 EVO(1TB)$149.99
内存Crucial CT4K16G4RFD4213 64GB(4 x 16GB)$285.99
电源Corsair CX550M 550W 80 Plus Bronze$79.99
显卡MSI GeForce GT 710$44.99
机箱Fractal Design Meshify C Black$84.99
CPU 散热器Cooler Master Hyper 212(x2)$72.98
远程管理TinyPilot(KVM over IP)$65.00
总计$1,368.74
空机箱外侧照片空机箱内部照片

Meshify C 是我用过最利于理线的机箱。它自带的魔术贴绑带能把线缆整理好,橡胶隔板则能把线都藏到机箱背部。

已安装 CPU 的主板照片已安装所有配件的主板照片

安装主板、CPU、内存和散热器

已完成的家庭实验室虚拟机服务器成品

组装完成,摆进新家的成品

虚拟机管理:Proxmox

我用 Proxmox VE 来管理虚拟机。

Proxmox 控制面板截图

Proxmox 中所有虚拟机的总览面板

上一次被 Kimchi 坑过之后,我本来不太想再尝试免费方案。Proxmox 已经有 12 年历史,感觉算是靠谱的选择。界面上它比 Kimchi 强得多,但精致度上还是不如 ESXi。

我最欣赏 Proxmox 的一点是它的可脚本化。我经常要做的是从模板创建新虚拟机,再用 Ansible 安装额外软件。在 ESXi 上,我找不到不用每次都去网页界面手动点按钮就能完成这件事的办法。而有了 Proxmox 强大的命令行工具,我只需运行 ./create-vm whatgotdone-dev,脚本就能自动创建一台全新的 What Got Done 开发用虚拟机。

我对 Proxmox 最大的抱怨是它不够直观。要不是找到了 Craft Computing 的安装教程,我连怎么装都搞不定。不过一旦摸熟了,用起来就很顺手。

性能测试

在退役旧虚拟机服务器之前,我针对常用工作流做了一些简单的性能测试,以衡量提升幅度。

我的旧虚拟机大多跑在网络存储上,因为本地 SSD 只够放一两台。下面测试对比了三种场景的性能:

  • 2017 年服务器(NAS):跑在网络存储上的典型虚拟机
  • 2017 年服务器(SSD):少数放在本地存储上的虚拟机
  • 2020 年服务器:所有虚拟机都跑在本地 SSD 上,不再区分 NAS 与 SSD

提醒:这些并非严谨的测试。每个工作流我只采了一个样本,也没有对测试条件做归一化处理。

创建新虚拟机

第一项测试是创建新虚拟机。我有一个标准的 Ubuntu 18.04 虚拟机模板,几乎所有虚拟机都基于它。每次需要新虚拟机时,我都会运行一个执行以下步骤的 shell 脚本:

  1. 从基础模板克隆虚拟机。
  2. 启动虚拟机。
  3. 将主机名从 ubuntu 改为新虚拟机的名称。
  4. 重启虚拟机以应用新主机名。
  5. 通过 apt update && apt upgrade 获取最新软件。
显示 2020 年服务器在 NAS 和 SSD 上均优于 2017 年服务器的图表

新服务器让这个流程大幅提速。克隆一台虚拟机的时间从旧服务器上的 15 分钟缩短到了新服务器上的不到 4 分钟。

如果跳过软件包升级这一步,提升就没那么惊艳了。新服务器相比 NAS 存储依然是碾压式的提升,时间从 8 分钟降到不到 2 分半。但在 SSD 对 SSD 的对比中,它反而比旧服务器慢。克隆虚拟机很可能是受限于磁盘,而我旧的 M.2 SSD 比新的 SATA SSD 更快。

启动虚拟机

从给虚拟机通电开始,多久能看到登录提示?

显示 2017 年服务器在 NAS 上用时 48.5 秒、SSD 上 32.4 秒,而 2020 年服务器仅用 18.5 秒的图表

旧虚拟机启动需要 48 秒。旧系统上少数放在 SSD 上的虚拟机表现稍好,32 秒出现登录提示。新服务器则把两者都远远甩在身后,只需 18 秒就能启动一台虚拟机。

运行 What Got Done 端到端测试

我的周记应用 What Got Done 有一套端到端自动化测试,会完整演练它的各项功能。这是我最多样化的工作流之一——涉及编译 Go 后端、编译 Vue 前端、构建一系列 Docker 容器,以及通过自动化 Chrome 来驱动应用。这曾是在旧虚拟机上把资源耗尽的工作流之一,所以我原本期待会有大幅提升。

显示 2017 年 SSD 服务器用时 5.4 分钟、2020 年服务器用时 5.6 分钟的图表

出乎意料的是,两台服务器之间并没有显著的性能差异。冷启动(需下载所有 Docker 基础镜像)时,新服务器反而比旧的慢 2%。当基础镜像已在本地时,新服务器确实更快,但也只快了 6%。瓶颈似乎主要在磁盘和浏览器交互上,所以新服务器的优势并不明显。

构建 Is It Keto

我另一个常见的工作流是构建 Is It Keto——我为生酮饮食人群做的资源站。我用 Gridsome 来生成网站,这是一个面向 Vue 的静态站点生成器。

显示 2017 年 SSD 服务器用时 3.7 分钟、2020 年服务器用时 4 分钟的图表

我原本期待这里会有明显提速,结果构建反而变慢了,让我很意外。在旧服务器上,构建似乎主要是 CPU 瓶颈,但新服务器的 CPU 资源翻倍却毫无作用。我接着猜测是磁盘瓶颈,于是试着把文件放到内存盘(RAMdisk)上,但构建速度依然不变。

我的推测是,这个工作流虽然受限于 CPU,但并行化很差。旧服务器的 CPU 核心数更少,但单核更快。如果构建只能用到五六个线程,就无法发挥新服务器 48 核的优势。

训练新的 Zestful 模型

Zestful 是我基于机器学习做的菜谱配料解析 API。每隔几个月,我就会用新数据重新训练模型。这是我最吃 CPU 的工作流,所以我很想看看新系统表现如何。

显示 2017 年 SSD 服务器用时 18.3 分钟、2020 年服务器用时 8 分钟的图表

终于有一个能让 48 核大显身手的场景了!新服务器把旧的远远甩开,训练时间缩短了一半还多。可惜,这个工作流一年也就跑几次。

总结与反思

用消费级硬件没什么丢人的

尽管 /r/homelab 可能永远不会认可我,但下一次搭建,我打算回归消费级硬件。

我认为服务器配件最大的优势是与服务器软件的兼容性更好。早在 2017 年,我必须关闭 CPU 的多线程才能装上 ESXi,性能大打折扣。但那其实是 Linux 内核的限制,后来的更新已经修复了这个问题

服务器硬件之所以溢价,是因为更高的可靠性。对于面向用户的服务,这一特性很重要,但在开发服务器上就没那么关键。开发机上偶尔崩溃或出现一次比特翻转,并不会毁掉你的一天。

要算清双路 CPU 的综合成本

这是我第一次组装双路 CPU 的电脑,体验很有意思,但我觉得不值得这么折腾。

从测试结果看,CPU 很少成为我工作流的瓶颈。最有力的证据是 Proxmox 记录的 CPU 使用率曲线。过去几个月里,我的 CPU 负载从未超过 11%,配置严重过剩。

显示 CPU 使用率从未超过 11% 的图表

过去几个月里,我的 CPU 使用率峰值从未超过服务器总容量的 11%。

对双路 CPU 的需求大幅推高了主板成本,也限制了可选范围。只有极少数主板支持双路 Intel 2011-v3 CPU,因此在其他主板特性上几乎没得选。

远程管理带来灵活性

在用 TinyPilot 管理服务器之前,我没意识到自己有多抗拒改变。改动任何 BIOS 或网络设置,都可能让我接下来几个小时都得来回搬机器、重接外设去排错修复。一想到这,我就根本不想去动那些设置。

有了虚拟控制台,我就有了试错的自由,也更愿意去尝试不同的操作系统。安装和学习一个新系统始终要花不少功夫,但知道不必再来回搬机器,就让我更愿意去尝试。要不是做了 TinyPilot,我可能会觉得 ESXi“够用就好”,而不会去尝试 Proxmox。

一年之后

更新于 2021-12-05

有读者问我回头看这套配置有没有想改的地方,正好这台服务器已经用了一年多,我想来分享一下后续情况。

CPU——给得太多了

双路 E5-2680 v3 确实有些过头了。

显示 CPU 使用率很少超过 50% 的图表

使用一年来,我很少超过 50% 的 CPU 使用率,说明单颗 CPU 其实就够了。

一年用下来,我从未达到 100% 的 CPU 使用率,超过 50% 的情况也只有寥寥几次,所以单颗 CPU 完全够用。

SSD——给得不够

我的 1TB 三星 SSD 快要塞满了,所以我又买了一块 2TB Samsung 870 Evo,总计 3TB 的固态空间。机箱里还有很多位置可以继续加硬盘。

显示磁盘已使用 85% 的截图

我的服务器只剩下 15% 的磁盘空间。

默认情况下,我给每台虚拟机分配 40GB 磁盘,有时会有点紧张。做 Docker 相关工作时,容器镜像会很快占满空间。每隔几周,我就会发现虚拟机磁盘被塞满,不得不运行 docker system prune --all 来清理,额外增加的磁盘能让我少受这种打扰。

内存——稍微少了点

64GB 内存大多时候够用,但也有几次我不得不关掉一些虚拟机来腾出内存。我不想因为管理资源而打断工作流,所以又订了 64GB 同款内存。

显示内存频繁达到 64GB 上限的图表

64GB 内存已经快要触顶。

Proxmox——依然很棒

我依然很喜欢用 Proxmox 来管理虚拟机。我买了授权,虽然不确定它是否带来了我用得上的新功能,但我很乐意支持这个项目。

烦人的是,授权是按 CPU 计费的,所以除了为买多了 CPU 而懊恼,我还得为 Proxmox 付双份钱。

配件清单(截至 2021-12-05)

类别组件价格
CPUIntel Xeon E5-2680 v3(x2,二手)$264.82
主板SuperMicro MBD-X10DAL-I-O$319.99
硬盘Samsung 860 EVO(1TB)$149.99
硬盘Samsung 870 EVO(2TB)$239.99*
内存Crucial CT4K16G4RFD4213 64GB(4 x 16GB)$285.99
内存Crucial CT4K16G4RFD4213 64GB(4 x 16GB)$164.11*
电源Corsair CX550M 550W 80 Plus Bronze$79.99
显卡MSI GeForce GT 710$44.99
机箱Fractal Design Meshify C Black$84.99
CPU 散热器Cooler Master Hyper 212(x2)$72.98
远程管理TinyPilot(KVM over IP)$65.00
总计$1,772.84

* 在初次搭建约一年后购买。

本文章由 muse-spark-1.2-contributor 进行翻译

评论