搭建 Homelab 虚拟机服务器
注意:本文介绍的是 2017 年的一次虚拟机搭建。
2020 年版请见,“搭建 Homelab 虚拟机服务器(2020 版)。”
概述
我大部分的家庭开发工作都是在虚拟机(VM)中完成的。我的主力台式机是一台 Windows 10 电脑,所以过去我一直通过 VirtualBox 来运行虚拟机。
这套配置运行得还不错,但我开始越来越意识到其中的痛点。我搜索后找到了 Brian Moses(布莱恩·摩西)的一篇博文,他在文中介绍了如何搭建一台专门用于运行虚拟机的“Homelab(家用实验室)”服务器。我非常喜欢这个想法,并受此启发决定自己也搭建一台。
为什么要用虚拟机?
干净的环境
我编写的所有软件都依赖于特定的软件环境。例如,我的项目 ProsperBot 的开发就依赖于 Go 工具链、nginx 和 Redis。如果我在主力台式机上为每个项目不断安装依赖,最终就会变成各种 Web 服务器、数据库服务器以及同一库的不同版本相互冲突的一团乱麻。
安全性:虚拟机隔离
虚拟机还能通过将软件与主系统隔离来提供安全性。我喜欢尝试各种新工具和应用,但应用有可能是恶意的(可能是开发者本身就制作了恶意应用,也可能是合法应用被攻击者入侵后被用来传播恶意软件)。如果我直接在 Windows 机器上安装应用并感染了恶意软件,那就全完了。即使是非常基础的恶意软件,一旦在我的机器上运行,就能记录屏幕上的所有内容、控制我的 Gmail、Facebook、GitHub 账号,甚至将我的所有文件加密勒索。
在虚拟机中运行的恶意软件能造成的破坏则要有限得多。如果我在虚拟机中安装软件,而它偷偷安装了键盘记录器,它也只能记录该虚拟机内的按键,而无法记录主力台式机的按键。虚拟机并非万全的防御手段,因为高级恶意软件可能会逃逸出虚拟机,但它们仍然能提供很大程度的保护。
为什么需要一整台虚拟机服务器?
我一直在主力 Windows 台式机上通过 VirtualBox 运行虚拟机,这存在几个问题:
- 每当我重启主力电脑时,都必须费力地关闭或挂起所有正在运行的虚拟机,然后在重启后再逐个重新启动。
- 我的主力电脑大约每月会崩溃一次,而 VirtualBox 在崩溃恢复方面表现很差。重启后,它会认为虚拟机镜像文件被锁定,我不得不去摆弄文件系统来修复。
有了专用的虚拟机服务器,我就可以在上面运行一个极简的 Linux 服务器操作系统。机器上运行的软件越少,需要重启的频率就越低,崩溃的可能性也越小。
还有一些我觉得很有意思的点对点项目(例如 OpenBazaar、BitSquare),但它们需要服务器全天候运行。我曾尝试通过 VirtualBox 来实现,但上述的那些麻烦让我渐渐失去了让这些虚拟机持续运行的兴趣。如果我能一次性启动虚拟机后就让它一直运行,尝试这些项目就会变得有吸引力得多。
挑选配件
CPU
在布莱恩·摩西的博文中,他很兴奋地利用了二手 Intel Xeon CPU 的低价。这是个不错的想法,但我担心二手服务器硬件出现故障的风险,所以更倾向于全新的零售版 CPU。
我在主力电脑上对 CPU 进行了超频,但这也会导致偶尔崩溃。为了让虚拟机服务器尽可能稳定,我决定不对这套系统超频。这样带来的好处是,挑选配件变得更容易、也更便宜,因为我无需为不锁频的 CPU、支持超频的主板或高端 CPU 散热器支付额外费用。
最终我选择了 AMD Ryzen 7 1700。它拥有 8 核 16 线程,应该很适合运行多个虚拟机,而且最近获得了大量好评。
主板
我住在曼哈顿一套相当小的一居室公寓里,所以物理空间非常宝贵。我的需求也省去了许多通常在 PC 中占用大量空间的组件,比如硬盘驱动器、显卡或高端 CPU 风扇。
这些需求让我倾向于 MicroATX 主板,最终我选择了 ASRock AB350M-HDV。我过去使用华擎主板的体验一直不错,这款看起来也是个稳妥的选择。我对其内存支持有些犹豫,因为它只有两个内存插槽,这意味着我只能安装 2 条 16GB 的内存条,没有扩展余地。我想,如果以后内存不够用了,到时候应该已经有 2 条 32GB 的套条了,大不了到时咬咬牙把两条都换掉。
回过头看,我真希望当初买的是一块带集成显卡的主板(见下文的配件回顾)。
内存
我的主力电脑有 32GB 内存,日常使用中通常会占用约 15GB(即使同时运行 Windows 10 和多个虚拟机)。我觉得 16GB 也许够用,但 32GB 在未来 2 到 3 年内应该是一个安全的上限。我选择了 G.SKILL Flare X Series 32GB (2 x 16GB),因为这是经测试与我的主板兼容的速度最快的内存条。
硬盘
和布莱恩·摩西一样,我有一台 NAS,有充足的空间可用,所以本地存储只需要一块小硬盘来存放宿主机 / Hypervisor(虚拟机监控程序) 操作系统即可。我选择了 250GB 的 Samsung 850 EVO,主要是因为我觉得 M.2 接口非常简洁。只需将一块芯片拧到主板上就完成了,无需处理支架或 SATA 线缆。250GB 远超我的实际需求,但对于 M.2 SSD 来说,这似乎是入门容量。
机箱
对于机箱,我主要想找一个非常小的。我打算把服务器藏在看不见的地方,所以不需要好看或花哨的外观。Rosewill Micro ATX SRM-01 小巧、便宜又实用,很不错。
显卡
我主要打算让这套系统无头运行,通过 SSH/Ansible 进行管理,但偶尔还是需要显示输出(例如在初次安装或不小心弄坏网络配置时)。我一开始以为可以使用主板的集成显卡支持,但实际上不行(见下文的配件回顾)。
由于我对 GPU 的要求不高,只想要一款便宜且评价不错的,所以我选择了 EVGA GeForce 8400 GS。
为这套系统专门买一台显示器没有意义,因为 99.99% 的时间我都是无头管理。剩下的 0.01% 时间,我只需钻到桌子底下,把主显示器的 HDMI 线从主力台式机拔下来插到虚拟机服务器上就行。
网卡
我原本打算直接使用主板自带的 1 Gbps 网卡,因为我的网络只有 1 Gbps。它在 Ubuntu 16.04 上确实能开箱即用,但我很快发现网速被限制在约 10 Mbps。稍作研究后,我发现 Ubuntu 16.04 并未包含正确的驱动,所以我不得不添加一个额外的 apt-get 源来安装 r8168-dkms 包。我照做了,但在重启后,Ubuntu 却无法检测到网卡……
到这时,我已经厌倦了折腾板载网卡,于是直接买了一块据说在 Ubuntu 上开箱即用的 PCI 网卡:Broadcom BCM5751 Netxtreme。它无需任何折腾就能达到 1 Gbps 的速度,所以花 23 美元,我觉得不值得再花时间去排查板载网卡的问题。
另外值得注意的是:板载网卡与 ESXi 6.5 不兼容,而这块博通网卡则兼容。
最终配件清单
| 类别 | 组件 | 价格 |
|---|---|---|
| CPU | AMD Ryzen 7 1700 | $323.66 |
| 主板 | ASRock AB350M-HDV | $69.99 |
| 硬盘 | Samsung 850 EVO - 250GB | $99.99 |
| 内存 | G.SKILL Flare X Series 32GB (2 x 16GB) F4-2400C15D-32GFXR | $224.99 |
| 电源 | EVGA 430 W1, 80+ WHITE 430W 100-W1-0430-KR | $29.99 |
| 显卡 | EVGA 512-P3-1300-LR GeForce 8400 GS | $29.99 |
| 网卡 | Broadcom BCM5751 Netxtreme | $22.95 |
| 机箱 | Rosewill Micro ATX SRM-01 | $21.99 |
| 总计 | $823.55 |
组装
配件到齐后,就该开始组装了!
这是组装前的所有组件。图片中没有网卡和显卡,因为直到实际尝试运行系统时,我才意识到需要它们。
这是组装好所有配件后的服务器。没什么复杂的,因为组件本身就不多。特别省心的是,由于唯一的硬盘是直接连接在主板上的 M.2 SSD,无需处理硬盘的电源线或 SATA 线。
由于公寓空间有限,我想要一台可以藏起来不被看见的服务器。我决定把它放在书桌抽屉后面,紧挨着书桌。它在物理上仍然和我的主力台式机一样触手可及,但在视线中基本隐藏了起来:
组装完成
安装宿主机操作系统
虚拟机服务器的宿主机操作系统应该尽可能轻量。它只需要承载 hypervisor,几乎不需要其他功能。宿主机上安装的软件越多,需要保持更新以维持服务器稳定的软件包就越多。
我尝试了几种不同的 Linux 发行版,但在我的硬件上只有 Ubuntu Server 能开箱即用(成功测试了 16.04 和 17.04)。我认为是 Ryzen 的 SMT 功能导致了其他发行版安装失败。我猜可以通过在 BIOS 中禁用 SMT、安装其他发行版,然后将内核升级到 >= 4.10,再重新启用 SMT 来绕过这个问题,但由于 Ubuntu 16.04 Server 是我最熟悉的发行版,我决定就直接用Ubuntu 16.04 Server。
运行虚拟机
KVM
作为 hypervisor,我选用了 KVM。它是一款相当成熟且使用广泛的产品,这样在我需要通过 Google 搜索支持答案时会很有帮助。一些更面向企业的 hypervisor 即使软件本身免费也需要许可证密钥,但 KVM 没有这个问题,因为它是免费且开源的。
Kimchi
我喜欢能够通过网页界面管理基础设施,所以我安装了 Kimchi,这是一款基于 HTML5 实现的 KVM 管理界面。
我会把 Kimchi 评价为“还不错”。有些仪表盘相当精美:
Kimchi 网页界面截图
它在某些方面也做得非常好,比如创建桥接网卡(这在命令行上弄清楚有点麻烦)。
缺点主要在于用户体验。做一些简单的事情需要大量点击,而且我经常遇到页面更新(例如客户机虚拟机完成关机)导致上下文菜单消失、迫使用户重新开始整个流程的情况。这些缺点不算太严重,随着使用增多,调整自己的操作习惯来避开这些 UX 问题也变得更容易了。
备选:ESXi 6.5
实际上,我最初计划在这个项目中使用 VMware vSphere Hypervisor,即 VMware 提供的免费 hypervisor 产品。它看起来是一款更成熟、用户群更大的产品(因此 presumably 更容易找到支持)。然而,它最终与我主板的网卡和 Ryzen CPU 都不兼容。在安装了博通网卡并在 BIOS 中禁用了 CPU 的 SMT 之后,我终于能够运行它,但到那时我已经使用了几天 Kimchi 并习惯了它。
vSphere 似乎并未提供比 Kimchi 明显更好的体验。它的界面要精致得多,但也有非常笨拙的流程,一旦出错就得从头完全重启整个多步骤流程。如何访问 shell 以便在命令行上直接执行我想要的操作也不太直观(我确信是可以的,只是我没有深入研究去找到答案)。
对我来说决定性的因素是,登录时 vSphere 会醒目地显示一条警告,称除非输入 VMware 注册密钥,否则软件将在 60 天后停止工作。VMware 免费提供许可证密钥,但当 Kimchi 无需任何许可检查且提供了与 vSphere 大致相当的体验时,我不想再去折腾注册密钥。
自动化服务器配置
我非常喜欢 Ansible,所以我编写了一个 Ansible playbook 来自动配置我的虚拟机服务器。它会执行以下操作:
- 将内核更新到兼容 Ryzen SMT 功能的版本
- 安装 KVM 和 Kimchi
- 挂载用于存储虚拟机镜像的 NFS 共享
你可以通过安装 Ansible并运行以下命令,使用同一个 playbook 来配置你的服务器:
VM_SERVER=vmaster # Replace with your VM server's hostname
echo "${VM_SERVER}" > hosts
wget https://mtlynch.io/files/provision-vm-host.yml
# Replace the extra-vars with the values for your NFS share
ansible-playbook provision-vm-host.yml \
--extra-vars "cifs_share=/nas-hostname/VMs" \
--extra-vars "cifs_username=foo" \
--extra-vars "cifs_password=bar"
回顾我的选择
回顾:CPU
我最值得商榷的选择是 CPU。它运行速度确实很快,但可能也有些性能过剩,因为即使同时运行五个虚拟机且其中几个在执行 CPU 密集型任务,我也从未见过总 CPU 使用率超过 35%。
Ryzen 的缺点是目前非常前沿,兼容性还不稳定。我尝试安装 Fedora 25 Server、Debian 8.7、CentOS 7 和 ESXi 6.5,它们都在安装过程中失败,因为与 Ryzen 不兼容。如果我在 BIOS 中为 CPU 禁用 SMT(多线程),其中一些倒是能成功安装,但这会把它从 16 线程降为 8 线程,让人有些遗憾。唯一能成功安装的操作系统是 Ubuntu(成功安装了 16.04 和 17.04)。
Ryzen 还限制了我能购买的内存条。主板支持最高 3200 MHz 的 DDR4 内存,但 Corsair 没有经测试兼容该主板的内存。G.SKILL 有,但没有比 DDR4 2400 MHz 更快的。
回顾:主板
总体来说我对主板的选择还是比较满意的。它小巧紧凑,同时为所有组件提供了足够的空间。
我唯一的遗憾是没有仔细阅读板载显卡支持的说明。其“板载显卡芯片组”规格写道:
集成于 A 系列 APU 中的 AMD Radeon R7/R5 系列显卡,支持 HDMI,最高分辨率可达 4K x 2K (4096x2160) @ 24Hz / (3840x2160) @ 30Hz
所以我想:“太好了!它自带显卡,少装一样东西。”我没理解的是,这句话的意思其实是“仅在你拥有 AMD A 系列 APU 时才支持显卡”。APU 是 AMD 的 CPU/GPU 二合一芯片,而 Ryzen 并不属于其中,所以我无法使用板载显卡。
如果再来一次,我会选择 GIGABYTE GA-AB350M-Gaming 3,仅仅是为了拥有板载 GPU 带来的简便性。
回顾:内存
32GB 起初似乎有些过剩,但随着我为各种任务添加更多虚拟机,内存使用量已超过 18GB,所以我很庆幸当初选择了 32GB 而不是 16GB。
回顾:电源
电源的功率足以满足这套系统,而且相当安静。30 美元的价格性价比也不错。
唯一的缺点是它采用非模组化线缆。我的系统非常精简,只需要 24 针主板线和 8 针 CPU 线。其余的线都是多余的,不过它们可以比较整洁地藏在机箱中 5.25 英寸的光驱位里(在我的机箱里显然是空的)。
如果重来一次,我会考虑半模组或全模组电源,这样就可以去掉多余的电源线了。
结论
这台 Homelab 虚拟机服务器运行得非常好。知道我的虚拟机一直在运行非常方便,这样我只需通过 SSH 连接或在浏览器中查看,而无需在 VirtualBox 中启动任何东西。
一个意外的好处是,我不再需要对客户机操作系统的 CPU/内存资源分配过于保守。我的主力台式机是 8 核 i7,配有 32GB 内存。过去我不想让虚拟机抢占主操作系统的资源,所以通常只给客户机分配 1 个 CPU + 1GB 内存,只有在看到资源吃紧时才会增加。而有了这台 Homelab 虚拟机服务器,资源对大家来说都绰绰有余!我的标准客户机操作系统模板使用 4 核和 4GB 内存,这对我的大多数环境来说都是足够的上限。这意味着我不用再浪费时间手动管理客户机操作系统的资源了。
如果你从事的软件项目需要多种开发或预发布环境,我强烈建议在虚拟机中工作,并使用一台专用的虚拟机服务器。
随机一篇博客










