更新和重启的最佳实践
在现代世界中,让您的系统保持运行不仅仅是赌注——这是没有商量余地的。
当涉及到软件更新以及这对您的系统意味着什么时,那就更复杂了。一方面,安全是当今更新的主要驱动力,这也是不容商量的。需要尽快在所有系统中实施补丁,以保持最强的安全性。
这同样适用于包含重要错误修复、性能改进和增强功能的软件更新。它们也应该及时实施,以利用内部的改进。
但是停机时间呢?根据您的环境和操作流程,在应用安全补丁和软件更新时,您可能会因服务重启而导致轻微停机,并且您可能会引入错误代码导致重大停机,直到回滚或更新。如何在不停机的情况下及时更新和打补丁是一个难题,您需要做出正确的架构决策,否则您的环境就没有机会实现高可用性。
解决方案是依靠能够保证亚秒级重启时间的软件,即使跨数百个节点也是如此。这是我们投入巨资的领域,因此升级 MinIO,即使是大规模升级,也是无中断的。在这篇文章中,我们将概述我们方法背后的理念,并向您展示如何执行高可用性对象存储所需的无中断升级。
MinIO 专注于无中断重启,因为我们知道您的数据对您有多重要。数据是现代企业的血液。这意味着数据存储是核心。如果它停止,血液就会停止流动——好吧,不好的事情就会发生。由于应用程序、ETL、工作流、数据库、AI/ML——甚至 CDN——的一切都依赖于数据,因此数据存储系统必须始终可用——即使它消耗安全性和发布更新。未能实现无中断升级会累积技术债务并产生升级的负面激励,从而降低软件的实用性并增加数据隐私和持续业务运营的风险。
一般原则
对于 MinIO,就像时间一样,稳定性朝着一个方向发展。最新的 MinIO 版本将永远是最稳定的。面向现代 CI/CD 的开发人员会理解这一点,而老派架构师可能不会——但我们向你保证这是真的。MinIO 经常发布,但有意发布,每个发布都经过精心计划、开发和测试。我们始终鼓励我们的客户和社区使用最新版本。
发现的错误已修复,并与最新版本的上游合并。如果特定客户需要可以根据请求向后移植修复程序,这些是应用于旧版本的补丁程序。每周最新版本总是来自上游。因此,我们的客户和社区可以放心,最新版本具有您正在使用的当前版本所需的修复,无论该版本有多旧。
虽然每个人都应该使用最新版本,但我们也认识到我们的发布节奏和您的部署节奏以及必要的内部流程可能不一致。在每个人都运行大量软件包和开源框架的世界中,所有发布和部署节奏都很少发生重叠。
您的节奏不应影响您的停机时间——而使用 MinIO 则不会。
那么 MinIO 是如何处理这一切的呢?首先也是最重要的,MinIO 的最新二进制版本确保它向后兼容可能的最旧版本。如果数据以旧格式写入,例如使用以前的元数据结构,则新版本将具有读取它的逻辑并将该数据执行到新格式的就地升级。每个版本的迁移逻辑都融入了代码本身,因此您无需执行额外的更新步骤。
在 Linux 中,包管理器管理配置更改。但这可能会变得很麻烦,因为我们需要将每一个更改都告知包管理器。它是某人必须记住的所有更改和应用它们的脚本的链。
MinIO 的滚动升级速度很快,任何旧版本的兼容性的全部知识都由新版本处理。例如,最近一位客户使用的是 2.0.9 版本,他们想知道是否可以直接更新到 4.5.2 版本,还是必须完全重新安装或一次更新一个版本。我们建议他们直接升级到 4.5.2,他们很快就能启动并运行。MinIO 始终确保向后兼容性,我们永远不会让您感到困惑。
正如我们将在教程中展示的那样,您只需下载更新版本,将其放在旧二进制文件的位置并重新启动您的服务。您可以从版本 B 无缝跳转到版本 X。实际上,MinIO 通过依赖链确保功能,保证升级考虑到以前的版本,更重要的是,一次升级一个版本,如 B->C->D….X。从用户的角度来看,也许更重要的是从管理员的角度来看,连接的基础设施可以正常工作。MinIO 执行此迁移并处理兼容性的复杂性。
如果要求按顺序升级,就像那句格言(顺便说一下,这是假的),金门大桥需要两年的时间,但你必须每两年粉刷一次。关键是,如果你需要一个版本一个版本地顺序升级,你会把所有的资源都花在升级上,而没有留下任何改进、优化和定制的东西。
事实上,这就是较旧的遗留系统中发生的情况。它们失速,然后在自身重量下倒塌。
我们大多数拥有管理系统的人都知道这个练习。支持和依赖系统脱机。然后,为了尽量减少总停机时间,每个节点都被关闭,应用更新或安全补丁,节点重新启动,然后在下一个节点上重复整个循环。
如果您有 2-3 个节点,这不是什么大问题,但如果集群中有 50 个节点,这可能需要一整天(或一夜)。不仅是数据的数量,而且这些节点中的数据量也会使这个过程变得更长。同样,从业者知道这个过程是出了名的难以跟踪,如果没有准确的跟踪,他们就会冒着不知道每个节点处于哪种状态的风险。不完整升级的后果可能很严重。具有较旧二进制版本的现有 MinIO 服务器将接收请求,但不会理解包含新功能的请求。如果有集群负载均衡器,那么请求会随机发送到一个节点,因此很难控制请求的去向。
更新时间越长,您的 ETL 作业得到备份的时间就越长,它们恢复所需的时间也就越长。这就是我之前提到的累积的技术债务。作为一名前 DevOps 工程师,我对此有切身体会。有时整个系统需要整整 24 小时的周期才能恢复和稳定。当系统重新启动时,不可避免地会出现配置不匹配或设置更改,因为更新的性质和应用它所需的时间会导致进程到处中断。MinIO 缓解了这些问题,因为在下载二进制文件和重新启动服务之间,没有太多可能导致漂移的活动部件。
先说说MinIO究竟是如何让你实现不间断更新和快速重启的。稍后我们将通过有关在您的环境中升级和重启 MinIO 的教程向您展示如何执行此操作。这个 MinIO 升级过程可以扩展到一个 50 节点的集群,每个集群都运行一个 MinIO 二进制文件,监听端口 9000。
无缝、简单、即时
当发布新版本的 MinIO 二进制文件时,实际升级本身非常简单。我们将向您展示如何升级二进制文件以及 kubernetes 运算符。此过程将同时升级所有 50 个节点。升级的这种性质可以节省时间并激励您的 DevOps 团队更频繁地升级二进制文件,因为此任务可以轻松实现自动化。从架构上讲,所有内容都在一个二进制文件中,该二进制文件在单个进程 ID 中运行。
二进制文件就位后,我们将同时重启所有节点上的 MinIO 服务。同样,您不需要一次只对一个节点执行此操作,因为它们在后端都使用单一的二进制和数据格式。当新进程重新启动时,后端进程知道如何读取旧版本正在管理的驱动器,因为迁移逻辑也在新版本中进行了编码。重启发生得非常快,实际上是亚秒级的,因为 MinIO 是高效的。MinIO 几乎不使用任何 CPU 资源,并且整个代码库被捆绑到一个二进制文件中,使其保持流线型和直接,并且无需管理大量移动部件。
同时,我们建议您同时更新所有节点。传统上,无中断升级只能通过滚动更新来实现,因为每个节点都需要时间来更新,而且节点之间相互依赖,因此必须一次更新一个。更新 MinIO 集群时,随着每个 MinIO 节点的更新,集群将继续使用旧版本运行,直到集群中的所有节点都更新为止。这减轻了担心不同请求显示不同版本的负担,因为所有请求都转到相同版本,直到发生完全转换。
通过并行执行更新,我们以原子方式进行;要么所有节点都运行较新版本的二进制文件,要么所有节点都运行旧版本的二进制文件。MinIO 确保你不会遇到一些节点运行旧版本而一些节点运行新版本的潜在破坏性情况。
最好的部分是使用 MinIO 的应用程序不知道这个升级过程,因为 HTTP/API 调用甚至不知道服务器正在重启。我们不是在谈论需要节点通知其他节点和客户端它们正在重新启动的遗留应用程序或文件共享。MinIO 通过仍然在指定端口上接收请求来保持一致性,并且当服务重新启动时,它将请求路由到出现的较新版本。
无论您是在数据中心的物理服务器上还是在 Kubernetes 中运行的 Pod 上运行 MinIO,都可以使用这种升级和重启方法。在下一部分中,我们将向您展示一个简单的教程,教您如何在真实世界运行的基础架构中实时实现这些概念。
执行升级
执行实际升级本身相当简单。我们将向您展示两种升级方式:使用二进制文件和 Kubernetes Operator。
二进制
确保集群中运行的所有节点都是 MinIO 部署节点而不是其他 S3 兼容服务非常重要。
要在所有节点上更新 MinIO,请运行以下命令
mc admin update ALIAS
此命令更新 MinIO 部署中的所有服务器。更新后,它还将同时在所有 MinIO 部署节点上重启 MinIO 服务。MinIO 操作是原子的并且严格一致,因此重启过程不会中断应用程序。
这避免了 MinIO 节点的“滚动”重启,并符合 MinIO 方式的更新和重启精神。
Kubernetes 操作员
如果您正在运行 Kuberntes 操作员,您可以按如下方式升级。
在开始升级之前验证 Operator 中资源的状态
kubectl get all -n minio-operator
还要验证操作员的版本
kubectl get pod -l 'name=minio-operator' -n minio-operator -o json | jq '.items[0].spec.containers'
验证后,您可以使用 krew 插件进行升级,或者在这种情况下,我们将向您展示如何手动进行升级。
下载MinIO kubernetes插件,替换为系统路径中已有的on
curl https://github.com/minio/operator/releases/download/v4.5.8/kubectl-minio_4.5.8_linux_amd64 -o kubectl-minio chmod +x kubectl-minio mv kubectl-minio /usr/local/bin/
验证插件是否已安装在正确的路径中
kubectl minio version
以下命令是实际升级操作员的命令
kubectl minio init
再次运行之前的 jq 命令来验证新安装的 operator 的版本
kubectl get pod -l 'name=minio-operator' -n minio-operator -o json | jq '.items[0].spec.containers'
这也可以通过登录操作员控制台来验证
kubectl minio proxy
关于无中断升级的最终想法
现代企业永不止息。诚然,在一个相互关联的世界中,企业没有端到端的控制权——问问亚马逊自己就知道了。话虽如此,自我造成的停机时间需要被设计出来 - 并且使用 MinIO 的功能套件,这成为可能。
但是,不要相信我们的话,您自己看看吧。创建一个 MinIO 集群,然后下载 MinIO(50 个节点对于测试来说可能有点高 :))并执行升级 - 您将亲眼看到并行性、弹性和小到可以在一秒钟内重新加载的二进制文件的强大功能但强大到足以为地球上一些最大的企业提供动力。
未能立即实现无中断升级会导致技术债务的积累。这会产生连锁反应,为您的整个工程和 DevOps 团队增加额外的技术债务。维护之后,启动这些系统完全是另一回事。通常情况下,它们必须按正确的顺序启动,并需要进行大量测试,以确保它们的运行方式与脱机前的运行方式相同。
您可以确信每个 MinIO 版本都在您的环境中完美运行,无论是开发、QA、暂存还是生产。我们尽我们所能确保每个新版本都是改进,我们为您提供工具以在您的环境中快速验证这一点。
在以后的博文中,我们将详细介绍有关如何设置这些不同环境的建议。例如,如果您没有足够的节点来适应不同的环境,那么您可以在相同节点但不同端口上运行多个 MinIO 二进制文件;通过这种方式,您可以将数据重新用于生产并针对暂存环境端口对其进行测试,以确保在升级生产端口上运行的二进制文件之前一切正常。如果你有多个 MinIO 租户,那么你可以先升级免费层,当你建立信心时,你可以一次一个地把它推广到其他地区。