接下来我计划写一个小系列,聊聊如何把一个简化过的私有云环境部署在笔记本里,以满足低成本、低功耗、低延时的实验环境。

过程中,将尽可能使用主流的开源软件和技术栈来完成功能,尽量保持日常使用的云服务的基础功能体验(如:存储、网络、监控、容器、通知)。但是,众所周知笔记本资源有限,所以许多选择、和软件配置上需要进行取舍和牺牲一定的 HA。

如果你对上面聊到的内容感兴趣,那么不妨搬个小板凳,订阅这个系列慢慢看。

写在前面

几个月前,在《廉价的家用工作站方案:前篇》一文中,我提到了使用笔记本作为小型的家用服务器的可能性,文章记录了自2015年以来的一些尝试,以及背后的“沉默成本”、“性价比”、“体验上的不同”、“使用过程中的小坑”。

在最近三个月里,一边写代码、一边打游戏、一边整理服务的过程中,我将其中一台设备完全“腾了出来”,虽然之前生产环境里比较抵触 ALL IN ONE,但是如果是开发环境,其实问题不大啊,还能够更好的加深细节的理解,于是就有了本次的“为了不折腾的折腾的事情” 。

硬件环境

《AMD 4750u 及 5800u 笔记本安装 Ubuntu 20.04》一文中,我提到了我购入了一台搭载 Zen3 处理器的新笔记本,这台设备的硬件规格是这样的:

  • CPU: AMD Ryzen 7 5800U,8C16T
  • GPU: AMD Radeon RX Vega 8 (R4000/5000, 15W)
  • 存储:支持双盘位,目前磁盘是 500G + 1T 的两块SSD
  • RAM: 1x 8GB DDR4, 3200 MHz + 1x 32GB DDR4, 3200 MHz
  • 网络环境:千兆有线、千兆无线

相比较之前那台可以扩展到 64GB 内存的笔记本而言,这台内存容量少了20GB,但是在CPU性能、存储容量上则有了更大的资源冗余,还是比较适合折腾的。

接下来的实践,就将围绕这个硬件环境展开。

当然,如果你手头有更充裕的资源,也可以参考本文接下来的配置进行一定的扩展,以获得更好的体验。如果你的资源比文章中的还少,那么可以再次进行适当的配置调整,试试运气(问题不大)。

虚拟化环境

传统云厂商,除了水平扩展物理机的数量之外,其实也会使用虚拟化来提高整体利率和收益(超售)。我们日常听的用的最多的 EC2 / ECS 便是基于 KVM 虚拟化方案提供的标准算力规格的虚拟化产品。

一个不严谨的关于虚拟化的等式

如果你想进一步了解“虚拟化”的特点和优势,可以移步 RedHat 的专题页面

前文提到,因为实现环境限定在一台笔记本上,而不是多台物理设备,所以我们也需要使用虚拟化技术来解决一些现实问题:

  • 不同职能的服务之间需要有一定的隔离性,确保运行过程中互不干扰,确保服务运行更加稳定、数据准确不受扰动。
  • 相比较生产环境中,我们可能使用多台设备来完成业务上云架构,这里只有一台笔记本,所以要尽可能提高资源的综合利用率。
  • 我们需要将运行过程中的硬件环境确定,包括硬盘额度、读写速率限制、以及网卡、IP地址,以确保环境可以轻松重建,以及在需要的时候,能够进行相对轻松的进行快速迁移。

选择基础虚拟化方案

对于个人或者小团队而言,相对靠谱的“开箱即用”的虚拟化产品选择其实不多,其中 Proxmox VE 和 ESXi 都可以考虑,我曾写过两篇关于他们的文章,可以根据自己的喜好选择。

本文将使用 ESXi 环境,在实际环境中其实和 PVE 差别不大,根据自己喜好来就是了。

来回折腾的虚拟化环境

为了方便读者选择,展开聊聊两者在一些细节体验上的差异。

ESXi 和 Proxmox VE 细节体验差异

先聊聊大家最关注的费用问题,两者虽然同为付费软件,但是均可免费使用:前者安装之后即可免费使用,后者则需要先进行免费许可的申请,不过 ESXi 提供了两个月的试用期,这个时间足够我们申请免费许可了。

再来看看同为免费版本的软件功能差异,对于小型的虚拟化场景而言,两者在提供功能上几乎没有差别。免费版的 ESXi 存在一个每台虚拟机最多使用8个虚拟核心的限制。

在扩展定制能力上,PVE 远胜于 ESXi,你可以将前者视为安装了 QEMU 虚拟机和 KVM 内核的标准 Debian 系统,而后者则是一套经过精简的定制系统。ESXi 仅提供商业产品和硬件的支持,所以不少消费级产品的硬件设备会存在缺少驱动的问题,举几个例子:核显、指纹识别、摄像头、触摸板、有线或者无线网卡。这个情况在完全开放的标准 Linux 环境下会有好转,比如我们之前通过更新内核,来解决 Ubuntu Desktop 版本下的 AMD GPU 的支持问题;比如我们之前通过自己编译 Realtek 网卡驱动来解决无线网卡不工作的问题。

不过开放灵活背后的代价就是“稳定性”,这点需要自行掌握平衡。

额外有一个小细节是,如果我们使用笔记本作为虚拟化宿主机,PVE 可以通过调整 Debian 引导参数、添加启动脚本来实现屏幕的自动休眠,避免烧屏。而 ESXi 则无法直接在应用软件层面实现这个功能,长时间开着屏幕用,一来费电(10w以内),二来会存在硬件损耗(烧屏)。解决的方法也不是没有,官方社区曾有人也做过一些尝试,比如拆卸屏幕,制作开关;比如将显卡和显示器直通给一台虚拟机,然后在虚拟机里设置休眠;把屏幕和键盘面闭合,让屏幕断电,再设置笔记本合盖不休眠等等。

当然,有一个更省事的方法,一般笔记本在接近闭合的时候,会自行断电,所以可以考虑拿一些东西支撑在屏幕和键盘之间,这样既无需设置合盖休眠、又无需拆卸屏幕排线、还不用折腾设备直通虚拟机,节约了不少机器资源。当你需要的时候,打开屏幕,还能够直接通过笔记本操作 ESXi 管理终端,非常方便。

规划基础环境

折腾完基础虚拟化环境后,接下来聊聊虚拟机的具体功能规划问题。

前文提到了我的硬件资源池只有8C16T,以及40GB左右的内存,以及1.5TB的磁盘,想要实现一个简化过的私有云还是挺紧张的。

虚拟机列表

为了维护和使用的方便,我对资源进行了这样的分配:

  • Base:2核心4GB内存200G磁盘
  • Monitor:2核心4GB内存200G硬盘
  • Database:2核心4GB内存200G硬盘
  • Storage:2核心4GB内存200G硬盘
  • Node1~Node3:2核心8GB内存100G硬盘

上面的虚拟机分别提供“偏基础、通用服务”、“监控服务及日志存储”、“应用数据库”、“对象存储”、“应用集群运行环境”。考虑到运行稳定性,我将监控和数据库的持久化放置在一块磁盘,将剩余的机器持久化到另外一块磁盘中。

如此分配下来,基本不存在“超售”的情况,即使设备全部资源跑满,也会空闲出两个线程保证 ESXi 的运行和虚拟机的调度。因为我使用的硬盘类型是 SSD,所以我分别预留了 50G、200G 的磁盘剩余空间,避免磁盘接近写满时的性能骤降问题。

批量创建虚拟机

因为我使用的是免费版的 ESXi ,无法使用 vCenter。但是批量创建虚拟机并非 vCenter 特权。PVE 有模版创建方案,ESXi 则默认支持通过批量复制虚拟机,然后在“存储库”中选择注册虚拟机,来完成批量创建。

除此之外,还有两个可以参考的选择。

复古党的选择:KickStart

很早之前,Ubuntu 官方就在 WIKI 中分享了一个方案:Kickstart

The Ubuntu installer supports automating installs using Kickstart files, as designed by Red Hat for use in their Anaconda installer. This method is not as flexible as the preconfiguration file method above, but it requires less knowledge of how the installer works.

不过,随着 Ubuntu 版本的更新迭代,在适合 Kickstart 使用的官方镜像下载页面,你会收到旧版镜像停止维护的提示。国外有一位同学记录和分享了他在过程中遇到的问题。所以是否继续使用这个方案,你可以自行确定。

紧跟时代的选择:Cloud-Init

Cloud Init 在 Ubuntu 18.04 中被实装,官方在文档中有提到它该如何使用。不过不得不吐槽,官方 YAML 看起来简洁,但是一套配置下来,快赶上 K8S 配置文件了。

但是好处是,几乎你知道的云服务商,都可以和它配合使用

额外的细节处理:vm-agent

有一个小细节,如果你使用的是 ESXi,它会自动帮你在安装的时候安装 VM-Tools,而如果是 PVE,则需要自行安装 qemu-guest-agent,虚拟机中的这个 agent 软件还是蛮有用的,能够帮你正确的处理关机,以及实时提供虚拟机网络状态。

网络地址固定

在虚拟机系统安装完毕之后,可以先整理一下虚拟机的地址,方便我们后续的操作。

路由器中 DHCP 监听到的新地址

在路由器中,使用 DHCP 分配的 IP 地址会随着设备停止使用而被回收,所以为了稳定使用,我们还需要进行网络地址固定,绑定的方式有两种,你可以使用 DHCP 配置来声明对于指定 MAC 地址要分配的 IP 地址。

使用 DHCP 配置绑定地址

也可以随遇而安,路由分配什么地址,给他手动分配绑定死了就行。

手动绑定地址

Base 虚拟机设置

前文中提到了,我将一台机器作为 “Base”,提供一些基础服务,比如 APT 软件缓存、SSO 等,所以为了方便后续其他服务使用,我先在 DHCP 中将一些域名指向配给了这台机器。

address=/base.lab.com/10.11.12.189
address=/.lab.com/10.11.12.189
address=/*.lab.com/10.11.12.189

在这台机器上,我目前只运行了一些简单的应用:

a87d66da9689   dist.lab.com                 0.00%     7.316MiB / 3.844GiB   0.19%     2.06kB / 0B       6.47MB / 0B      3
e1ff56206ca3   traefik                      0.03%     17.2MiB / 3.844GiB    0.44%     1.19GB / 1.19GB   63.1MB / 0B      9
99c5f8430237   sso-traefik-forward-auth-1   0.00%     1.785MiB / 3.844GiB   0.05%     1.78kB / 0B       7.99MB / 0B      4
77e914ee4d3e   login.console.lab.com        0.00%     16.07MiB / 3.844GiB   0.41%     1.78kB / 0B       39.8MB / 0B      7
d5db9d9a6f47   docker.lab.com               0.00%     3.633MiB / 3.844GiB   0.09%     3.33kB / 0B       61.4kB / 0B      3
9d0474ecbb86   docker-registry.lab.com      0.05%     10.3MiB / 3.844GiB    0.26%     8.72kB / 2.42kB   19.3MB / 0B      9
e3d01fa870cd   cache.lab.com                0.00%     229.9MiB / 3.844GiB   5.84%     6.11MB / 1.19GB   240MB / 16.4kB   4
^C

上面的程序中,包含一个能够提供服务发现的 traefik 网关、一个用于提供静态资源下载的 Nginx 服务、一套 SSO 认证程序、一个 APT 软件包缓存服务、一套容器仓库。

这里部分内容,我曾在之前的文章中提到过。至于完整的部署细节,我将在后续的文章中逐步展开。

快速初始化其他虚拟机

不论你选择使用什么方式进行系统安装,系统安装完毕之后,我们需要对它们进行一些初始化操作,安装一些基础运行环境,以及常用软件。

相比较安装过程中的解压缩、配置等本地计算过程,远程下载会浪费非常多时间。所以这里可以通过一个小技巧,来节约时间,提升使用体验:《使用容器搭建 APT Cacher NG 缓存代理服务》

在搭建完毕第一台虚拟机系统之后,你便可以选择在 Cloud-Init、Kickstart 安装过程中配置脚本、软件源,或者也可以采取在系统安装完毕之后,使用 SSH 批量远程执行类似下面的脚本。

apt update && apt upgrade -y
apt install language-pack-zh-hant language-pack-zh-hans -y
apt install git zsh wget curl unzip vim -y
curl http://dist.lab.com/docker.gpg  | apt-key add -
add-apt-repository "deb http://cache.lab.com/mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
apt install -y docker-ce
curl -L http://dist.lab.com/docker-compose -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
mkdir -p /etc/docker && touch /etc/docker/daemon.json
cat <<EOF > /etc/docker/daemon.json
{
    "registry-mirrors": [
        "https://YOUR.MIRRORS"
    ]
}
EOF

在生产环境中,我们在内网中,软件的下载和安装速度一般在百兆到千兆之间,但是因为我们这些虚拟机都在一台机器上,实际使用过程中,IO 速度可以达到 500MB/s 以上(毕竟有一层虚拟化,如果不是直通模式,性能肯定会有影响)。

还说的过去的磁盘性能

所以,如果你在系统安装的时候,已经将软件源配置使用 APT Cacher NG ,那么上面的脚本执行下来,十来二十多秒左右,你的系统中的软件就都升级到了最新版本,并且支持使用 Docker 的方式来运行软件。

其他:关于噪音和散热

我们知道,服务器运行的环境一般是加装了隔音环境,温度相对“寒冷”的空调房,如果我们在笔记本上运行规划的软件,会不会导致笔记本温度过高暴毙,或者运行声音非常吵闹呢?

其实并不会,观察下面的图片,可以看到,除了虚拟机启动时,以及有具体任务运行的时刻外,CPU 的负载其实非常低。

CPU 历史使用率

加上笔记本本身的风扇就相对静音,负载在 20%~30% 的时候,基本是没有声音的。(风扇该清理了,或者型号比较老、发热比较高的设备除外)

最后

本篇文章里的许多内容,在过去几年里的文章中有所提及的,在此就不过多展开赘述了。

文章中的配置会随着文章更新,逐步更新到我的 GitHub 仓库中,所以,如果你想使用现成的配置,那么可以晚些时候围观我在 GitHub 上的提交记录。

下一篇内容,我们将聊聊如何折腾“监控”,以及为什么要折腾“监控”。

–EOF