总结

总结

总结

客户要求我建立一个强大的系统来在他们的局域网内运行容器化的微服务。

限制:他们给了我 2 台机器和 6 个数据磁盘。没有更多的硬件。我必须在这里打造“我能做到的最好的东西”。

我担心的是存储和可用性。速度/性能是不是一个问题。

我在想:

  • 在每台机器上使用 3 个数据磁盘构建 RAID-5,在每台机器中产生一个数据卷。例如 ZFS。
  • 将两台机器与分布式文件系统绑定在一起。例如 GlusterFs。
  • 然后使用 Kubernetes 创建一个由 2 个节点组成的集群,将其持久卷指向分布式 FS。
  • 事实上,kubernetes 集群与分布式文件系统在相同的硬件上运行只是一个偶然现象。

问题是:考虑到客户端的限制,有没有更好的解决方案?

阅读上下文以了解更多信息。

语境

我正在为一家广播电台设计一个服务器架构,用于在本地运行 30 个微服务。没有 AWS,没有云。我们说的是本地服务器。

对于整个场景来说,速度不是问题(流量很低)。这里的业务驱动因素是:

  • 数据持久性(最大限度地降低丢失数据的风险)。
  • 高可用性(最大限度地降低停机风险)。

如果它们在任何时候不兼容,那么避免数据丢失就优先于高可用性:在极限情况下,我可以让记者停止工作几分钟;但我们不能丢失今天早上录制的采访。

他们目前正在运行什么(请不要哭!!)

它们现在都在一台服务器上运行,没有容器,除了备份之外没有数据冗余。他们在 2018 年经历了一场灾难,花了整整两天的时间才恢复。电台不得不停止所有员工的工作,重新安装完整的操作系统,手动重新安装所有应用程序,从备份中恢复所有数据,测试所有内容,然后让记者“回去写新闻”。

当然,这在当时是不可接受的(即使在 2018 年也是不可接受的)。

他们为这个项目准备的硬件

为了解决这个问题,他们最近购买了 2 台服务器,每台服务器有 1 个系统磁盘 + 3 个数据磁盘(总共 6 个数据磁盘)。他们对数据磁盘的最初想法是在每个服务器的 3 个数据磁盘上创建一个本地软件 RAID-5。

调用服务器alphabeta。两台机器的 CPU、RAM 和系统磁盘以及 3 个数据磁盘都相同。因此,这些计算机是完全相同的克隆。它们都将运行 Ubuntu Linux。

主从(客户的想法)与集群(我的建议)

想法他们必须将其用alpha作主服务器,并使其beta成为“克隆”,alpha这样如果它死了,他们可以转变客户端beta 在半小时内通过手动重新配置客户端以指向另一个 IP。

尽管如此我认为当前的技术应该能够让我创建某种集群,让它们都处于活动状态并完全同步,这样如果其中任何一个发生故障,客户端都会体验到零停机时间。

他们的请求

该电台最初要求我alpha通过 ZFS 在 上构建一个 RAID,然后通过 ZFS 在 上构建另一个 RAID 。使用beta设置一堆 docker,然后将服务的客户端(在各自的记者 PC 上运行)指向(可以将新闻写作、图片上传、录音、节目安排、网络发布、媒体转码、本地直播流传输到云端等服务视为此类服务)。alpha--restart=alwaysalpha

关于存储,他们最初的想法是:

  • 对于照片和音频,定期从alpha到备份beta
  • 对于 MySQL 来说,有一个主-主服务器alpha-beta因此beta主要充当从服务器,但可以在出现故障时立即使用alpha

然后,如果 alpha 中断,则将所有客户端切换为beta

我特别感兴趣的是贮存故事的一部分。

我的想法

我考虑使用Kubernetes创建一个由 2 个工作节点组成的集群。由于我无法使用单独的硬件来充当“kubernetes 主节点”,因此我考虑同时创建alpha两个beta冗余的 kubernetes 主节点作为工作节点。

因此,对于和节点来说,alpha这将是一个 kubernetes master ,对于和来说,这将是一个 kubernetes冗余master 。alphabetabetaalphabeta

到目前为止没有问题。

直到我们到达仓库。

存储、持久卷、GlusterFs 和 ZFS

Persistent Volumes在 Kubernetes 中,Kubernetes 用户启动 Pod/容器时需要依赖数据不会丢失一些系统管理员(在本例中是我)需要“构建”下面的冗余以确保卷“存在”且包含正确的数据。

所以我的想法是这样的:

1. 本地 ZFS 层

  • 在操作系统alpha(系统原生,暂时忘掉 kubernetes)中,使用 ZFS 在 3 个数据磁盘(大小相等)上创建 RAID。因此,如果每个磁盘为 1TB,则有 3TB,其中 2TB 可用于数据卷,1TB 用于冗余。我们将磁盘称为 A1、A2 和 A3。我们将 ZFS 卷称为 A。

  • 在 中beta,复制结构。磁盘 B1、B2、B3。我们将其称为 ZFS 卷 B。

到目前为止,我已经拥有 2 台独立服务器,每台服务器都针对单个磁盘的单一故障提供保护。没有针对 2 个磁盘同时故障的保护。没有针对全节点宕机的保护。

2. 分布式 GlusterFs 层

  • alpha然后在 ZFS 卷上创建 GlusterF beta。我知道 GlusterFs 必须给我某种mirroring配置,因此 ZFS 卷 A 和 B 是另一个的一个镜像。因此,如果 A 是 2TB,B 也是 2TB,则“总可用存储空间”也是 2TB。

  • 因此,此时加上 GlusterFs 和 ZFS,在总硬件容量 6TB 中,有 2TB 可供用户使用,因此 4TB 充当冗余。

到目前为止,我应该有一个“分布式磁盘”,它具有更多的冗余度并且允许 2 个磁盘和节点故障。

我发现 2 个磁盘的保护以下列方式失效:

  1. 如果两个磁盘属于不同的卷(例如 A2 和 B3 发生故障),则每个 NFS 都会单独防止这种情况发生,并且 ZFS 卷 A 和 B 都不会中断(GlusterFs 看不到任何变化)。
  2. 如果发生故障的 2 个磁盘属于同一节点,则整个卷都会发生故障。例如,A2 和 A1 发生故障会导致 A 损坏。但 GlusterFs 应该能够平衡使用“仅 1 个节点”,直到另一个节点可用(在这种情况下“仅使用 B,直到 A 再次恢复”)。

3.服务集群的 Kubernetes 容器运行时 + Kubernetes 持久卷。

  • 最后,使用 Kubernetes持久卷将指向 GlusterFs 卷。

  • 如果我有 4 台机器,我可能会使用 2 台作为 kubernetes 节点,2 台作为存储,充当集群的网络存储。

  • 但是我们只有 2 台物理机器,因此 kubernetes 会将“持久卷”指向“GlusterFs”,就像它们“在另一台远程机器上”一样,这使得这些卷是否物理上位于同一节点无关。

问题

我以前从未实际建造过这样的结构。从纸面上看,它是可行的。我想知道现实是否有所不同。

鉴于限制(2 台机器,6 个数据磁盘),问题是:

  • 这种拓扑结构是否是为客户端创建零停机和数据冗余的微型集群的最佳方式?
  • 如果不是,我应该应用哪些更改以及为什么。

答案1

当你这样做聚类,您必须考虑裂脑。为此,您需要 3 个节点。

在 ZFS 的情况下,我更喜欢 RAID10 而不是 RAID5(RAIDZ),主要是为了提高性能。

对于 MySQL/MariaDB,我会使用加莱拉用于复制的插件。

您将需要一个集群管理软件,例如ClusterLabs 起搏器

对于存储我也会考虑头孢

但是这个设置还有另一个方面。复杂性。你在哪里测试它?你打算自动化安装吗?自动化是否允许为虚拟机安装设置?你打算如何配置击剑? 您会使用存储 VLAN 吗?

您是否计划使用负载均衡器(例如HAProxy)?

网络冗余?LACP、生成树、OSPF/BGP...

服务器负载如何?也许您可以在虚拟机中安装所有设置。您仍然需要 3 个物理主机,但您将拥有更大的灵活性。

您需要写下各种故障情况的文档和脚本,包括由人为错误导致的故障情况。

如果只有 2 台机器,对于写入的数据(存储、数据库),最好进行主从配置,即仅在主服务器上写入,而将从服务器作为备份。对于无状态服务,您可以在主动-主动模式下配置它们。

相关内容