构建Homelab虚拟机服务器

2020-11-12 12:10:23

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

三年前,我构建了自己的家庭实验室服务器来托管我所有的虚拟机,从而使事情更上一层楼。这是一项非常棒的投资,因为它加快了无数的开发任务,并提高了可靠性。

在过去的几个月里,我开始达到我的虚拟机服务器的极限。我的项目变得更加需要资源,而且我在第一次构建时犯的错误又回来咬我了。我决定在2020年打造一台全新的家庭实验室虚拟机服务器。

如果你对这个项目的“为什么”不感兴趣,你可以直接跳到构建。

最初,我使用VirtualBox从我的Windows桌面运行虚拟机。这在一段时间内还不错,但重新启动成了一个巨大的麻烦。

在从Windows更新强制重启、自愿重启以完成软件安装,以及偶尔出现操作系统崩溃之间,我不得不每月重启我的整个开发虚拟机套件三到五次。

一台专用的虚拟机服务器让我不必重启。虚拟机主机运行的软件最少,因此很少出现崩溃和强制重启的情况。

云服务器可以提供相同的功能,省去了我的麻烦(有趣!)。维护我自己的硬件,但它贵得令人望而却步。对于与我的家庭实验室服务器类似的虚拟机资源,AWS EC2实例每年的成本将超过6000美元:

我可以根据需要打开和关闭云实例,从而大幅降低成本,但这会给我的工作流程带来摩擦。使用本地VM服务器,我可以随时保持10-20个VM可用和就绪,而无需担心微观管理我的成本。

我2017年的版本对我很有帮助,但在使用它的三年中,我逐渐认识到了几个亟待改进的关键领域。

我的Synology NAS有10.9TB的存储容量。有了这么多的网络存储空间,我想,“为什么要在服务器上投入比启动主机操作系统所需的最少空间更多的磁盘空间呢?”

首先,在网络存储上运行虚拟机会对磁盘服务器产生严格的依赖关系。Synology每隔几个月发布一次操作系统升级,他们的补丁总是需要重新启动。由于我的虚拟机运行在Synology的存储上,在应用Synology的任何更新之前,我不得不关闭我的整个虚拟机群。这与我在Windows桌面上运行虚拟机时遇到的重启问题相同。

其次,网络上的随机磁盘访问速度很慢。在我第一次构建的时候,我的大部分开发工作都是在后端的Python和Go应用程序上进行的,它们并没有执行大量的磁盘I/O。从那时起,我就扩展到了前端Web开发。现代的Web框架都使用Node.js,所以每个项目的依赖树中都有10k-200k的随机JavaScript文件。Js构建涉及大量的随机磁盘访问,这对网络存储来说是最糟糕的情况。

对于我的第一台服务器,我评估了两种虚拟机管理选项:泡菜和VMWare ESXi。VMware要完美和成熟得多,但泡菜以其斗志和开源的本质迷住了我。

随着时间的推移,泡菜的缺点变得越来越明显。我经常不得不多次点击虚拟机的“克隆”或“关机”按钮才能与其合作。还有一些令人恼火的用户界面错误,按钮在我点击之前消失或移动了位置。

如果你读了上面的文章,你会想,“泡菜只是个软件而已。”为什么迈克尔必须建造一台全新的服务器,才能安装一个不同的虚拟机管理器?这是因为我没有预见到远程管理的重要性。

我的虚拟机服务器只是一台放在办公室角落里的PC,没有连接显示器或键盘。当我可以通过SSH登录或使用Web界面时,99%的时间都可以。但在1%的时间里,当服务器启动失败或我想安装新的主机操作系统时,这是一个巨大的痛苦。我必须把服务器拖到我的办公桌上,断开我的桌面键盘和显示器,修复任何需要修复的东西,然后将我办公室里的一切恢复到原来的配置。

在我的下一次构建中,我想要一个虚拟控制台,只要机器一开机,它就可以进行物理级访问。我想的是戴尔的iDRAC或惠普的iLO。

我的第一台VM服务器的CPU是Ryzen 7 1700。它拥有8个内核和16个线程,是当时炙手可热的新CPU。但是,当我展示我在Reddit的HomeLab子社区/r/HomeLab上的构建时,他们嘲笑我是一个肮脏的休闲者,因为我使用了消费者部件。酷孩子们用的是企业用具。

我决心再也不让/r/homelab取笑我了,于是我冒险进入了企业服务器硬件领域。我甚至想入非非,选择构建一个有两个物理CPU的系统。

为了让我的钱物有所值,我把搜索范围限制在四到八年前发布的二手CPU。对于每个候选人,我在PassMark上查找基准分数,然后在eBay上查看该CPU型号在二手状态下最近的销售情况。

性价比最高的似乎是英特尔至强E5 v3系列,尤其是2600机型。我选择了E5-2680 v3。它的平均基准是15618,在eBay上使用的价格约为130美元。

作为背景,我之前构建的Ryzen 7的基准测试是14,611。因此,有了双E5-2680,我的处理能力将比我的旧服务器高出一倍以上。

双CPU系统的缺点是限制了我对主板的选择。只有少数主板支持双英特尔2011-v3 CPU。它们的价格从300美元到850美元不等,这远远超过了我在主板上的预期花费。

我选择了超微MBD-X10DAL-I-O,它的价格比同类主板低320美元,但仍然是我上一块主板价格的五倍。

对于服务器内存,似乎有很多不那么知情的选择。对于消费类硬件,很多网站都会发布对不同内存条的评论和基准测试,但我没有看到任何类似的服务器内存条。

我选择了关键的CT4K16G4RFD4213 64 GB(4x16 GB),因为我信任这个品牌。我之所以选择64 GB,是因为我之前的版本是32 GB,而我的一些工作流正在接近这个限制,所以我想在接下来的几年里,将RAM翻一番就可以满足我的需求。

我喜欢M.2固态硬盘,因为它们体积小,性能出众,而且整齐地藏在主板上,没有任何线缆。遗憾的是,MBD-X10DAL不支持M.2接口。

取而代之的是,我坚持使用传统的SATA。我买了一台1TB的三星860EVO。我通常为每个虚拟机分配40 GB的空间,因此1 TB会给我足够的空间。如果我以后需要升级,我总是可以买更多的磁盘。

选择电源单元(PSU)并不是那么有趣,所以我再次选择了主要受信任的品牌,海盗船CX550M 550W 80加青铜。

我所有组件的功率加起来是400W,所以450W就足够了。但550瓦版本的价格只高出10美元,对于额外100瓦的呼吸空间来说,这似乎是一个公平的价格。

对我来说,唯一的另一个重要特征是半模块化布线。在我的上一次构建中,我犯了一个错误,使用了非模块化布线,这意味着所有的PSU电缆都保持永久连接。我的服务器几乎没有任何内部组件,所以多余的电源线造成了混乱。使用半模块化布线,我可以通过从PSU上移除不用的电缆来保持东西整洁。

双CPU版本使得冷却成为一个意想不到的挑战。MBD-X10DAL在两个CPU插座之间没有留下太多空间,所以我仔细寻找了足够薄的风扇,以便并行工作。一双更酷的Master Hyper 212正好符合要求。

我的服务生不显眼地坐在办公室的角落里,所以我不想要一个面板清晰或灯光耀眼的箱子。

Fractal Design Meshify C Black得到了积极的评价,似乎是一个简单、安静的案例。

对于无头服务器来说,显卡并不重要。它仍然是必要的,这样我就可以在初始安装和偶尔的调试过程中看到屏幕,所以我选择了MSI GeForce GT 710,作为一个便宜、简单的选择。

我研究了远程管理解决方案,他们的昂贵让我大吃一惊。起初,我想我应该使用戴尔iDRAC,但远程控制台需要300美元的企业许可证,并且将我的构建限制在戴尔组件上。我研究了KVM over IP解决方案,但它们甚至更贵,从600美元到1000美元不等。

为了实现远程管理,我采用了一种不同寻常的方法,用Raspberry PI构建我自己的KVM over IP设备。我叫它TinyPilot。

TinyPilot捕获HDMI输出,并从浏览器转发键盘和鼠标输入。它提供的访问权限与物理连接真正的键盘、鼠标和显示器时的访问权限相同。该软件是完全开源的,如果你想自己构建一个,我可以提供一体机工具包。

在泡菜烧了我的最后一个版本之后,我不愿意尝试另一个免费的解决方案。Proxmox已经存在12年了,所以我觉得他们是一个足够安全的赌注。在图形方面,它比泡菜有了很大的进步,但在流畅度上落后于ESXi。

我最欣赏的Proxmox部分是它的脚本化。我经常执行的任务之一是从模板创建一个新的虚拟机,然后使用Ansible安装其他软件。使用ESXi时,如果不是每次都手动点击web用户界面中的按钮,我无法找到一种方法来做到这一点。有了Proxmox,他们的CLI就足够强大,我可以把它写成./create-vm Whatgodo-dev,我的脚本可以创建一个全新的完成了什么的开发VM。

我最大的抱怨是Proxmox不直观。我甚至不知道如何安装它,直到我找到了Craft Computing的安装教程。但是一旦你熟悉了你的方法,它就很容易使用了。

在我停用旧的VM服务器之前,我收集了常见工作流的简单基准来衡量性能提升。

我的大多数旧虚拟机都运行在网络存储上,因为它的本地SSD只有几个虚拟机的空间。在下面的基准测试中,我比较了三种不同场景下的性能:

2020服务器:所有虚拟机都在本地固态硬盘上运行,因此没有NAS与固态硬盘。

我采用的第一个基准测试是配置一个新的虚拟机。我有一个标准的Ubuntu 18.04 VM模板,我几乎所有的VM都使用它。每次需要新的虚拟机时,我都会运行一个执行以下步骤的Shell脚本:

我的新服务器为这个工作流程带来了巨大的加速。克隆一个虚拟机在我的旧服务器上只用了15分钟,而在新服务器上只用了不到4分钟。

如果我跳过包升级步骤,加速效果就不那么令人印象深刻了。新服务器在NAS存储上的性能仍然令人叹为观止,从8分钟降至略低于2.5分钟。固态硬盘到固态硬盘,它的性能逊于我之前的服务器。克隆一个虚拟机可能是受磁盘限制的,而且我的旧M.2固态硬盘比我的新SATA固态硬盘更快。

从我打开虚拟机的那一刻起,我需要多长时间才能看到登录提示?

我的旧虚拟机在48秒内启动。我的旧系统上的几个SSD虚拟机做得稍好一些,在32秒内就显示了登录提示。我的新服务器在18秒内就启动了一台虚拟机。

我每周一次的日志应用What Good Done已经完成了自动测试,可以端到端地运行它的功能。这是我最多样化的工作流程之一--它包括编译Go后端、编译Vue前端、构建一系列Docker容器,以及自动化Chrome来运行我的应用程序。这是耗尽我的旧虚拟机上资源的工作流之一,所以我预计这里会有很大的收益。

令人惊讶的是,这两台服务器之间没有显著的性能差异。冷启动(下载所有Docker基础镜像),新服务器比旧服务器慢2%。当基本Docker镜像在本地可用时,我的新服务器比我的旧服务器好,但仅高出6%。看起来瓶颈主要是磁盘和浏览器的交互,所以新的服务器没有太大的不同。

我有一个经常使用的工作流程,那就是为酮类节食者提供的资源是不是Keto?我使用Gridome(Vue的静态站点生成器)生成站点。

我预计这里会有显著的加速,所以当我的构建速度变慢时,我感到很惊讶。在我的旧服务器上,构建似乎主要是受CPU限制的,但是在我的新服务器上加倍CPU资源并没有起到任何作用。我的下一个猜测是它是受磁盘限制的,所以我尝试将文件移动到RAM磁盘,但构建速度保持不变。

我的假设是,工作流是受CPU限制的,但是并行性很差。我的旧服务器的CPU核心较少,但每个核心都更快。如果构建被限制为五六个线程,它就不能利用我的新服务器的48个核心。

Zestful是我的基于机器学习的API,用于解析食谱成分。每隔几个月,我就会根据新的数据对其进行培训。这是我的CPU最密集的工作流,所以我很想看看新系统将如何处理它。

最后,我的48个CPU内核大放异彩!新的服务器彻底颠覆了旧的服务器,只用了不到一半的时间就训练好了模型。不幸的是,这是一个我一年只运行几次的工作流程。

尽管/r/homelab可能永远不会尊重我,但在我的下一次构建中,我计划回到消费类硬件。

我认为服务器组件的最大优势是它们与服务器软件有更好的兼容性。早在2017年,我就无法安装ESXi,直到我禁用了CPU上的多线程,这大大降低了性能。但这是Linux内核中的一个限制,后来的更新修复了它。

服务器硬件因其更高的可靠性而备受推崇。对于面向用户的服务,此特性很有意义,但在开发服务器上就没那么重要了。开发服务器上偶尔出现的崩溃或位翻转不应该毁了您的一天。

这是我第一次建造双CPU计算机。这是一次有趣的经历,但我认为不值得这么麻烦。

根据我的基准,CPU很少是我工作流程中的限制因素。最确凿的证据是Proxmox的CPU使用率随时间变化的图表。在过去的几个月里,我从未将CPU负载提升到11%以上,所以我被过度配置了。

对双CPU的要求大大提高了主板的成本,限制了我的选择。只有为数不多的Mobos支持英特尔2011-v3双CPU,所以我在其他主板功能上没有太多选择。

在我使用TinyPilot管理我的服务器之前,我并没有意识到我是多么厌恶改变。更改任何BIOS或网络设置都有可能损失我生命中接下来的几个小时,因为我需要在机器上四处走动,并重新连接外围设备来调试和修复问题。知道这一点后,我再也不想修改这些设置了。

拥有虚拟控制台让我有了失败的自由,也让我更愿意尝试不同的操作系统。安装和学习一个新的操作系统总是需要付出巨大的努力,但知道我不必来回拖拽机器,这让我对它更加开放。如果我没有创建TinyPilot,我可能会坚持认为ESXi“足够好”,而不是冒险选择Proxmox。