版本 1(2023 年 12 月)
- 作者:
Alvaro Hernandez、Gabriele Bartolini、Patrick McFadin、Raffaele Spazzoli、Tom Prohofsky、Xing Yang - 审阅者:
Donna Reineck-Wehan、Josh Berkus、Mark Lavi、Max Jonas Werner、Melissa Logan、Michelle Au、Robert Hodges、Victor Lu
本白皮书是 CNCF TAG 存储和 Kubernetes 数据社区之间的合作成果。
根据 2022 年 DoK(Data on Kubernetes) 调查,Kubernetes 上的数据对组织产生了变革性影响,表明运行 DoK 与在收入和生产力方面取得巨大进步之间存在直接联系。调查显示,Kubernetes 上的数据工作负载包括数据库、分析、AI/ML 和流处理/消息队列。
本文档的目的是描述在 Kubernetes 上运行数据的模式,重点是数据库应用程序。我们将描述存储系统的属性是什么以及它们如何影响数据库应用程序,不同的存储堆栈如何影响这些属性,在 Kubernetes 内部和外部运行数据有什么区别,Kubernetes 的哪些特性有利于在 Kubernetes 上运行数据,以及我们从在 Kubernetes 上运行数据中学到的最佳实践和经验教训是什么。
为了描述存储系统的属性以及它们如何影响数据库应用程序,我们将参考我们之前的白皮书,包括 CNCF 存储全景白皮书、云原生灾难恢复白皮书 和 性能白皮书。
以下是本文档的目标和非目标。
- 描述存储系统的属性及其如何影响数据库应用程序。
- 描述在
Kubernetes上运行数据的好处。 - 描述在
Kubernetes上运行数据的模式,重点关注数据库应用程序。- 这可能包括影响数据库应用程序和非数据库应用程序的常见模式。
- 这也可能包括数据库应用程序独有的模式。
- 非数据库应用程序不会是本文档的重点,但可能会在未来的版本中添加。
在 存储全景白皮书 中,我们讨论了存储系统属性,包括可用性、一致性、可扩展性、持久性和性能。除此之外,可观察性和弹性也是云原生环境中的重要属性。所有这些都会对在 Kubernetes 上运行数据产生影响。在本节中,我们将简要介绍这些属性,然后讨论存储堆栈如何影响它们。
可用性可以通过在故障条件下访问数据的能力来定义。它定义了在故障条件下如何继续访问数据,以及在访问数据的节点不可用的情况下如何将数据访问故障转移到另一个访问节点。对于云原生数据库,可用性可以基于副本的数量。主/备用数据库的用户通常希望故障转移(failover)在 Kubernetes 中完全自动化。
存储系统的一致性属性是指在提交后访问新创建的数据或对其更新的能力。在读取操作返回最新数据之间有延迟,和/或在提交后所有数据受到保护之前有延迟的系统被定义为“最终一致的”。如果没有延迟,系统被定义为“强一致的”。一些数据库系统实现同步复制来控制这一点,甚至在单个事务的级别。
请注意,“一致性”的定义在 CAP 定理(关于一致性、可用性和分区容忍度)和 ACID(原子性、一致性、隔离性、持久性)数据库事务属性的上下文中有不同的含义。有关更多详细信息,请参阅 存储全景白皮书。
存储系统的持久性是指影响数据集持久能力(而不仅仅是可访问性)的存储系统属性。持久性会受到数据保护层、系统冗余级别、存储介质的耐久性特征以及检测数据损坏并从中恢复的能力的影响。
请注意,“持久性”在 ACID(原子性、一致性、隔离性、持久性)数据库事务属性的上下文中有不同的定义。它保证一旦事务提交,即使在系统发生故障的情况下也将保持提交状态。大多数数据库系统依靠一种称为预写日志 (WAL, write-ahead log) 的技术来实现数据持久性,方法是确保更改首先存储在数据库事务日志中。请参阅 存储全景白皮书 中的更多详细信息。对于云原生数据库,持久性可以基于副本数量,以及是否存在可靠的备份系统,该系统可将事务信息持续存储在安全位置。数据丢失事件要求所有副本和备份都丢失。
可扩展性是指增加存储系统资源的能力,以便满足日益增长的使用量。衡量可扩展性的标准包括扩展客户端数量、吞吐量(例如 MB/秒)、容量等的能力。扩展可以垂直或水平进行。
垂直扩展是指通过增加 CPU 等资源来扩展单个服务器。它也可以添加单独的卷,以在同一节点上实现并行 I/O,并充分利用表空间和表分区等功能。
水平扩展是指通过增加服务器数量进行扩展。云原生数据库通常使用分片来促进水平扩展。例如,已经毕业的 CNCF 项目 Vitess 具有内置的分片功能,可以水平扩展 MySQL。
可扩展性能够处理大量流量。性能与应用程序响应时间/速度有关。
可以使用吞吐量指标(如每秒 I/O 数和每秒传输的兆字节数)来衡量存储系统的性能,但这些指标可能会因工作负载的不同而有很大差异。传输大小、顺序访问、读/写比率等因素都会影响存储性能。在处理给定工作负载时,存储系统的响应时间可以用一段时间内的平均和最大延迟来表征。诸如 FIO 之类的基准测试工具可以测量持久卷的存储性能。Prometheus node-exporter 是一种能够监视平均延迟的工具。
数据局部性是指底层存储与使用持久卷声明的 pod 或服务的距离。当计算和存储无意中分离时,不必要或隐藏的延迟可能会减慢应用程序的响应时间。使用 pod 亲和性属性使编排器能够优化应用程序进程的放置。
有效监控 IT 基础设施对于确保最佳性能和最大限度地减少停机时间至关重要。在现代计算环境中,尤其是在分布式应用程序中,监控每个组件对于维持高服务水平至关重要。任何服务或系统的监控失败,即使是短时间的监控失败,也可能对整个系统造成严重后果,因此监控是构建和维护云原生应用程序的关键方面。分布式环境中不同服务之间的相互依赖性可能会产生复杂的故障场景,因此拥有全面的可观察性功能就显得更加重要。
在数据系统中,由于数据量大,监控基础设施的流量和状态至关重要。高效的监控系统可以为潜在问题提供早期预警,帮助运营商避免代价高昂的停机并确保信息的持续流动。构建包含监控、日志记录和跟踪功能的强大基础设施可观察性框架对于了解基础设施的各个方面至关重要。这样可以识别可能影响整个系统性能的潜在瓶颈、故障和错误。总之,可观察性是现代 IT 基础设施的一个重要方面,实施有效的监控系统是确保云原生应用程序和数据系统的最佳性能、可靠性和可用性的关键一步。
在现代计算环境中,弹性是基础设施管理的一个关键方面。虽然可扩展性侧重于增加资源以满足需求,但弹性更进一步,可以在不再需要资源时释放资源。此功能允许组织优化其资源利用率,确保他们只为所需的服务和资源付费。快速扩容和缩容的能力是弹性基础设施(也称为按需基础设施)的决定性特征。在资源有限的环境中,例如私有数据中心,弹性对于高效的资源分配和利用至关重要。
在数据管理中,弹性意味着能够通过回收不再需要的存储来优化存储空间的使用。这可能涉及将旧数据移动到较便宜的存储层或将其存档到长期存储以释放空间用于更关键的数据。对使用的每种资源收费的云基础设施可以从此功能中受益匪浅,因为它有助于防止运行不再需要的服务而产生不必要的成本。能够快速响应需求变化并相应调整资源分配的弹性基础设施是现代 IT 系统的重要组成部分,使组织能够保持最佳性能、可扩展性和成本效益。
有多个存储堆栈(层)会影响存储系统属性,包括编排器、主机和操作系统、存储拓扑、数据保护层、存储系统提供的附加数据服务以及物理非易失性层。
- 在将存储解决方案集成到协调环境中时,通常会在数据访问接口上叠加或插入许多虚拟化和访问层,这些虚拟化和访问层会影响整个端到端解决方案的可用性、可扩展性和性能。
- 存储拓扑描述了存储和计算资源的排列以及它们之间的数据链接。这包括
集中式、分布式、分片式和超融合拓扑。 - 存储系统通常具有增加冗余的数据保护层。这指的是
RAID、纠删码和副本。 - 存储系统通常除了核心存储功能(包括
复制、快照、克隆等)外,还提供数据服务。增量快照的能力对于支持高效备份和减少备份恢复时间至关重要。 - 存储系统最终将数据保存在通常是非易失性的物理存储层上。它会影响整体性能和长期耐用性。
对于无状态工作负载,灾难恢复相对容易,但对于有状态应用程序,灾难恢复变得更加复杂,因为我们必须解决如何在工作负载的各个实例之间同步状态的问题。
通常,必须为运行给定故障域(通常是数据中心或云区域)的每个工作负载定义从灾难中恢复的策略。该策略还应包括管理工作负载之间的可能依赖关系。我们将只关注针对单个工作负载的策略。
衡量灾难恢复的主要指标如下:
- 恢复时间目标 (RTO):恢复服务所需的时间。
- 恢复点目标 (RPO):为了在恢复站点中获得一致的数据,我们必须从灾难发生时回溯到多久以前。
从高层次上讲,我们有两种方法可用于灾难恢复策略:
- 主动/被动策略
- 主动/主动策略
使用主动/被动策略,一个故障域接收所有请求,而被动站点在灾难发生时处于待命状态。有时可以配置备用站点来处理读取请求,但一般来说,备用站点要么是热的(工作负载在那里,但没有做任何事情),要么是冷的(工作负载将在灾难发生时部署)。
这些是主动和被动之间的主要状态同步方法:
备份和恢复。执行定期备份。发生灾难时,数据将在被动位置恢复。此方法仅适用于冷被动站点。此方法的 RPO 等于备份频率。某些数据库管理系统支持在其他位置中继预写日志 (WAL) 文件,从而进一步降低 RPO;它们还控制 WAL 文件的存档频率(例如,最多每 5 分钟一次)。异步卷复制:存储配置为将写入复制到被动位置上的有状态工作负载卷。复制是异步的。这意味着写入请求的响应速度更快,但这也意味着如果写入速度快于同步速度,则可能会有无限数量的更改排队等待同步。此 RPO 取决于请求写入与同步写入的相对速度。此方法适用于热恢复站点(至少存储必须处于打开状态)。同步卷复制:存储配置为将写入复制到被动位置上的有状态工作负载卷。复制是同步的。这意味着写入请求的响应速度会变慢,因为必须考虑写入远程位置的延迟。但与此同时,RPO 正好为零。这种方法适用于热恢复站点(至少存储必须处于打开状态)。数据库级复制。一些数据库管理系统有一种本机的数据复制方式,通常基于预写日志,可用于通过网络在主动和被动站点的实例之间同步数据。这也称为主/辅助设置。根据主动和被动站点之间的延迟,复制可以是异步的或同步的,在后一种情况下保证RPO为零。一些数据库管理系统通过WAL文件传送启用异步复制,而无需在不同站点之间建立流式连接。这种方法适用于热恢复站点。
对于主动/主动策略,我们需要设计为具有多个可接收写入的主动实例的工作负载。这些也称为有状态分布式工作负载。有状态分布式工作负载可以分布在多个故障域中。这些工作负载理论上可以无限水平扩展。这是通过分区或分片(数据空间)的概念实现的。可用性是通过副本的概念实现的。同一分片的副本之间的内部“闲聊”协议可确保所有副本都看到相同的状态。
CAP 定理控制分布式工作负载在一致性、可用性和网络分段容忍度方面的属性。根据 CAP 定理,分布式有状态工作负载(即对网络分段具有容忍度的工作负载)可以是一致的,也可以是可用的。这会产生两类分布式工作负载:最终一致性(选择可用的工作负载)和强一致性(选择一致的工作负载)。
如果配置正确,任何类型的工作负载在发生灾难时都会继续工作,但一致性方面的保证会有所不同。特别是,最终一致性工作负载实例在一段时间内可能会看到不同的状态。相反,如果灾难过于严重以至于剩余的工作实例无法形成法定人数,则强一致性工作负载可能会变得不可用。
有关此主题的更多信息,请参阅 云原生灾难恢复 白皮书。
在本节中,我们将讨论运行数据库的选项,而不讨论一般的存储选项。
数据库通常是复杂的软件,需要高级编排才能部署,也需要高级维护操作(所谓的“第 2 天操作”)。因此,在没有适当自动化的情况下部署和操作数据库(我们可以称之为“在本地或裸云实例上手动安装”)是一种遗留模式,应该避免,因为它容易出错并且成本高昂。
因此,还有两种替代方案:数据库托管服务 (DBaaS) 和在 Kubernetes 上运行它们。如果堆栈的其余部分要在 Kubernetes 上运行,则应该选择在 Kubernetes 上运行数据库:否则,在 Kubernetes 上运行平台的好处将被忽略:用户将无法配置完整的环境,或者 CI/CD 管道将需要外部服务依赖项才能运行,而不是所有平台都是独立的。
但在 Kubernetes 上运行数据库也有内在优势:部署简单、由相同的编排工具管理整个堆栈、自动修复和自动重新配置故障容器,从而提高可用性。例如,如果运行数据库的某个节点发生故障,Kubernetes 将自动进行自我修复,将工作负载重新安排到另一个节点上。通过与 数据库管理 软件的协作,它可能会选出一个在先前存在的副本上运行的新数据库主节点,并将新节点重新初始化为新副本,所有操作均自动完成。但还有其他更重要的原因让您希望在 Kubernetes 中运行数据库。
大多数公司都希望将数据库作为 DBaaS(“数据库即服务”)来运营。自行配置可自我修复的数据库,包括备份和监控。虽然大多数云提供商都提供此功能,但使用 Kubernetes 自行执行此操作可以节省大量成本,并提供其他功能,例如多云和云可移植性。还有一些数据库系统和数据库系统版本,没有任何云提供商以 DBaaS 形式提供。
这些功能通过 Kubernetes Operators 提供。Operators 是 Kubernetes 的特定于应用程序的扩展,可对部署和操作自动化进行编码,同时向用户公开简单的界面。高级数据库 Kubernetes Operator 带来了以下好处:
- 部署和更新的声明式方法,使其
100% GitOps友好,非常适合任何使用CI/CD的公司。运维人员定义CRD(自定义资源定义),它们是高级对象 — 通常以简单的YAML文件形式交互 — 允许以简单的方式部署和管理复杂的数据库架构。 - 自动化“第二天操作”:包括
部署、高可用性、备份和监控;还包括打补丁、真空处理(清理被标记为无效的行或过期数据,释放存储空间,同时更新统计信息以优化查询计划)、膨胀清理(移除由于数据更新和删除操作导致的存储膨胀)、重建索引等运维操作。运维人员可以将这些操作编码到 CRD(自定义资源定义)中,即 YAML 文件中,从而实现这些操作的自动化。请参阅此处 的数据库运维示例。 - 将数据库功能外部化到第三方知名的
Kubernetes组件,如Envoy 代理;Prometheus 和 Grafana 用于监控; Cert Manager 用于 SSL 证书管理;或 Open Telemetry Collector 用于可观察性。数据Operator可以依赖这些组件来卸载数据库功能,减少用户操作它们的认知知识,因为它更熟悉,并获得更高级的功能。
在 Kubernetes 上运行数据库不仅是未来,也是现在,正如 Goldman Sachs、Zalando 等领先公司所展示的那样。与任何技术一样,在部署生产工作负载之前应进行仔细和客观的评估。
在本节中,我们将描述在 Kubernetes 上运行数据时常用的模式和功能。将讨论以下主题:
Kubernetes Operator容器存储接口(CSI)Kubernetes 工作负载 API拓扑感知调度Pod 中断预算资源管理控制平面和数据平面分离默认安全
Kubernetes Operator 通常用于促进在 Kubernetes 上运行数据。Operator 是 Kubernetes 的软件扩展,它利用自定义资源(CRD)来管理应用程序及其组件。
Operator 模型支持声明式自动化。与更传统的命令式自动化相比,声明式自动化提供了一些优势,因为使用声明式自动化,用户指定意图,系统不断验证当前状态并将其与所需状态进行比较,然后执行任何必要的更正。这消除了配置漂移的任何可能性。
Operator 是 Kubernetes 中的代理,负责协调当前状态和期望状态。
以下是编写Operator时的一些注意事项(有关更详细的讨论,请参阅Operator 白皮书):
- 决定哪些配置旋钮应该对用户可见。灵活性和复杂性之间总是需要权衡。
- 区分配置阶段和配置阶段。
Operator通常用于部署软件以及使用单个意向声明(Kubernetes中的自定义资源)对其进行配置。应该考虑将两者保持不同并允许对部署和配置使用不同的CR的可能性。除了提供良好的职责分离之外,这还开启了配置Operator不一定部署的工作负载的用例。 - 尤其是对于有状态的工作负载,
Operator应该负责工作负载所需的一些定期操作(例如重新索引、备份/恢复、存储压缩等)。 Operator应该支持优雅地发展他们管理的CRD的用例。这允许用户无缝地加入较新的CRD版本。Operator应该支持升级他们管理的软件的用例。- 对
Operator本身的更新不应造成破坏。
尽管在 Kubernetes 上运行数据时,Operator 模式被广泛使用,但仍存在许多挑战,包括缺乏标准。DoK 社区 正在开发一个 Operator 功能矩阵,该项目试图为管理有状态工作负载的各种 Kubernetes Operator 创建标准化、与供应商无关的功能矩阵。
许多操作符使用持久卷在 Kubernetes 中存储数据。这些持久卷通常由 CSI 驱动程序配置。
容器存储接口(CSI) 是一种行业标准,用于定义一组存储接口,以便存储供应商可以编写一个插件并使其在包括 Kubernetes 在内的一系列容器编排系统上工作。Kubernetes CSI 自 Kubernetes v1.13 发布以来一直处于 GA 状态,并且已经发展到支持 Kubernetes 中的数据库工作负载。CSI 具有控制器、节点和身份 gRPC 服务。身份服务提供插件的信息和功能。控制器服务支持创建和删除卷、创建和删除快照、附加和分离卷以及扩展卷。节点服务支持挂载和卸载卷以及扩展卷。
这里要强调的一个特性是 CSI 拓扑,它对于分布式数据库工作负载来说是一个非常重要的特性。它允许 Kubernetes 进行智能调度,以便在可以运行 pod 的最佳位置动态配置卷。因此,我们可以跨故障域部署和扩展工作负载,以提供高可用性和容错能力。
还有一个 CSI 容量跟踪功能,允许 Kubernetes 调度程序在调度期间考虑容量。
另一个有用的功能是原始块模式。它允许 pod 直接通过原始块设备而不是文件系统访问存储。这对于一些需要高性能和低延迟的数据库非常重要。
CSI 快照功能提供了支持 Kubernetes 中数据保护的基本构建块。您的数据非常宝贵,因此我们希望能够在发生灾难时恢复它。尽管数据库通常具有本机的备份和恢复方式,但卷快照可以使用常见的 Kubernetes API 和通用机制备份和恢复不同类型的数据库应用程序。但是,Operator 有机会通过利用 Kubernetes 在卷快照上提供的标准 API 来扩展数据库本机的备份和恢复方式,甚至可以克隆持久卷。例如,卷快照和克隆不仅可以减少恢复时间,还可以通过更短的扩展时间来提高弹性,并满足超大型数据库 (VLDB) 的需求。
还有一个新的 CSI 组控制器服务,它增加了对卷组快照操作的支持。有关 CSI 的更多详细信息,请参阅此处 的规范。
有状态工作负载可以使用标准 Kubernetes 工作负载 API 来运行。这些 API 通常由 Operator 用来运行数据库应用程序。
由于每个有状态工作负载通常都有自己的身份,因此 StatefulSet 通常最能满足此类应用程序的需求。使用 StatefulSet 时,使用卷声明模板来确保每个实例都有自己单独的存储卷,并使用 Headless Service 来确保每个实例在 Kubernetes DNS 中收到特定条目,从而允许其对等实例发现它,这可能会很有用。请注意,也存在直接管理持久卷声明而不使用 StatefulSet API 的Operator。
通常,所有工作负载最好分布在不同的故障域中,以提高其可用性。对于存储工作负载来说更是如此,因为它们通常对其他工作负载至关重要。Kubernetes 集群可以跨多个故障域构建,Kubernetes 控制平面提供了一种功能来确保工作负载分布在这些故障域中。这可以通过 拓扑感知调度功能 实现。
使用此功能时,可以指示要用作拓扑键的节点标签。所有具有该标签相同值的节点都被视为位于同一故障域中。调度程序将努力在不同的故障域中平均分配 Pod。
请注意,在大多数 Kubernetes 发行版中,节点会自动贴上以下标签:“topology.kubernetes.io/region”和“topology.kubernetes.io/zone”。这些标签通常是拓扑键的良好候选。
建议安装在 Kubernetes 上的存储工作负载使用此功能。Operator、Helm Chart 和其他安装方式应在它们创建的 Pod 中设置拓扑约束字段。
此外,通过适当的标记或利用污点和容忍度,一些 Kubernetes 工作节点(无论是虚拟的还是裸机的)可以声明性地专用于运行特定的数据库工作负载,甚至依赖于本地存储。
Kubernetes 集群将需要进行维护。在这些维护期间(通常是集群更新),可能需要将节点脱机或重启。Kubernetes 为工作负载提供了一种机制,用于通知控制平面在计划维护期间需要多少个实例才能使工作负载正常工作。此信息可以通过 PodDisruptionBudget 资源 提供。
建议安装在 Kubernetes 上的存储工作负载使用此功能。Operators、helm chart 和其他安装方式应创建 pod 中断预算。主/备用系统可能会为主系统和副本提供不同的 pod 中断预算,以确保至少有一个主系统始终在运行。
在 Kubernetes 上部署工作负载时,最佳做法是指定给定工作负载所需的资源类型(CPU、内存、GPU)和数量。 Kubernetes 利用这些信息以适当的名称调度工作负载,并决定在节点资源紧张的情况下取消调度哪些工作负载。
根据容器的资源规范为 Pod 分配 服务质量 级别。在 资源压力 情况下决定要驱逐哪些 Pod 时,服务质量是一个主要决策标准。
可用于取消调度 Pod 的另一个标准是 Pod 优先级。
一般而言,对于有状态工作负载,建议创建具有保证 QoS 和高于正常 pod 优先级的 pod。
工作负载可能会出现负载峰值,以至于当前部署的工作负载实例无法应对这种情况。对于无状态工作负载,配置水平 pod 缩放器相对简单,它可以动态添加或删除实例。并非所有有状态工作负载都可以配置为以动态方式水平扩展,因为所有实例都必须相互了解,并且对等发现机制可能不支持对等数量的动态变化。
对于这些情况,应该考虑 垂直 pod 自动缩放器。此自动缩放器将动态调整 pod 的大小以响应负载峰值。
Kubernetes 平台提供了控制平面和数据平面架构,可在控制平面和数据平面之间明确划分职责。控制平面管理计算资源的编排和管理,而数据平面处理和管理数据流。Kubernetes API 服务器充当数据平面请求计算资源的接口,而控制平面负责将这些请求映射到底层 IaaS 平台。这种架构为整个系统提供了高度的灵活性、可扩展性和弹性。Kubernetes 中普遍存在的控制平面和数据平面分离也可以应用于数据库管理。在数据库系统中,数据平面由公开用于客户端访问和分布式数据库中节点之间通信的端口组成。控制平面包括用于管理和指标收集的接口,以及用于操作维护任务的工具。大部分功能都可以通过 Kubernetes Operator模式实现,该模式定义自定义资源 (CRD) 和控制循环来观察这些资源的状态并采取行动将它们移向所需状态。这种方法支持使用特定于域的逻辑扩展 Kubernetes,从而更轻松地在现代 IT 环境中管理和扩展数据库系统。
Kubernetes 具有默认网络模型,可为容器化应用程序提供安全的环境。默认情况下,端口不可从外部访问,必须明确公开才能启用外部访问。此默认安全模型可确保应用程序免受未经授权的访问,为部署和管理容器化应用程序奠定坚实的基础。这种方法还鼓励仔细考虑如何公开每个控制平面和数据平面接口以及应通过 Kubernetes 服务提供哪些接口。
除了默认安全的网络模型之外,Kubernetes 还提供了机密管理设施,可用于共享加密密钥和配置管理帐户。机密用于存储敏感信息,例如密码、访问令牌和 API 密钥,通常由应用程序在运行时访问。Kubernetes 提供了一个用于管理机密的 API,使用户能够安全地存储和分发整个集群中的敏感信息。通过利用这些机密管理功能,组织可以确保其应用程序和数据免受未经授权的访问,并以安全且合规的方式管理敏感信息。
是管理现代分布式系统的一个关键方面,Kubernetes 提供强大的可观察性功能,帮助开发人员监控和排除应用程序故障。可观察系统的三大支柱是日志记录、指标和跟踪,Kubernetes 通过将每个容器的日志公开给第三方日志聚合解决方案提供了一个很好的起点。借助这些日志,开发人员可以深入了解其应用程序的行为并快速诊断问题。Kubernetes 还通过 Kubernetes Metrics Server 提供对指标收集的内置支持,该服务器为集群中的所有对象提供性能指标。这使开发人员能够监控资源使用情况并识别可能影响其应用程序性能的瓶颈。此外,Kubernetes 通过 OpenTelemetry 项目支持分布式跟踪,允许开发人员跟踪跨多个服务的请求并可视化请求在其系统中的流程。通过利用 Kubernetes 中的这些可观察性工具,开发人员可以全面了解他们的系统,更有效地识别和修复问题,并优化性能以提供更好的用户体验。对于数据基础设施,重点关注以下领域:
- 运行系统:部署在
Kubernetes内部的数据工具可能是一个复杂的分布式系统。向Kubernetes Metric Server公开的系统特定指标和日志可以为整个堆栈提供统一的视角。了解每个系统如何提供可观察性是成功的关键部分。 - 控制平面:数据基础设施与弹性等概念结合使用时,会快速消耗资源。突破计算、网络和存储的硬性限制将使您的系统保持平稳运行。
- 安全性:尽管
Kubernetes部署的这一方面应尽可能实现自动化,但仍应验证关键的安全活动。这些包括入口和出口流量、密钥轮换和访问日志记录。
安全性是使用 Kubernetes 的基石之一。多年构建基础设施的经验告诉我们一个关于安全性的事实:安全性通常被留到最后。在构建数据基础设施部署时,Kubernetes 允许使用工具将安全性放在首位并使其变得简单。
安装数据基础设施时,元素之间会产生大量通信,从而导致高流量。在 Kubernetes 中构建虚拟数据中心会产生节点间和外部网络流量,应使用 x.509 证书通过传输层安全性 (TLS) 和安全套接字层 (SSL) 对其进行加密。证书颁发机构 (CA) 是该系统的重要组成部分,它充当受信任的第三方,通过对证书进行数字签名来建立两个实体之间的信任链。
静态加密是在存储中对未使用的数据进行加密的做法。Kubernetes 提供了加密机制来保护持久存储中的数据,例如机密(Secret)、ConfigMap 和 etcd 数据。它使用行业标准加密算法,并且加密密钥会自动轮换。
验证/授权与 Kubernetes 的集成允许开发人员管理对 Kubernetes 集群中资源的访问。Kubernetes 支持各种身份验证方法,包括 X.509 客户端证书、静态令牌和 OpenID Connect 令牌。它还提供基于角色的访问控制 (RBAC),从而实现对 Kubernetes 资源访问的细粒度控制。通过将身份验证/授权集成到 Kubernetes 基础架构中,开发人员可以有效地保护其应用程序中的资源。
Operators 通常用于自动化第 2 天运维(运行阶段运维)。在本节中,我们将讨论以下主题:
- 升级
- 备份和恢复
- 增加/减少存储容量
- 数据迁移
升级涉及存储产品本身的升级以及部署存储产品的 Operator(如果存在)。
应该可以触发 Operator 的升级,而不会影响 Operator 控制的产品实例。
应该可以单独升级存储产品实例,而不必将它们一起升级。此外,如果存储产品允许,升级应该在不中断服务的情况下进行。
Operator 和产品实例的架构应能够经受住 Kubernetes 集群升级,这可能涉及逐个使节点下线。
最后,Operator 管理的 Kubernetes 资源将随着时间的推移而发展。Operator 应该管理 CRD 版本转换,为这些工件提供平稳升级。
许多有状态的工作负载和数据库通常需要能够备份和恢复数据。 主要有两种备份(和相应的恢复):
- 卷级备份(又名崩溃一致性备份)
- 应用程序级备份(又名逻辑备份)
前者在存储/卷级别执行,在 Kubernetes 中可以通过快照 API 辅助。可以添加钩子,在备份之前使应用程序处于静止状态,并在备份之后取消静止,以确保应用程序的一致性。
后者必须通过调用特定的存储产品功能来执行,并且通常在 Operator 级别进行管理。
在 Kubernetes 数据保护工作流白皮书 中,有更多关于如何在 Kubernetes 中进行备份和恢复以及存在哪些差距的详细信息。
有几种产品提供通用的崩溃一致性备份,一些更先进的有状态工作负载 Operator 还提供与卷快照的集成,用于备份/恢复以及逻辑备份。
持久卷声明通常用于为有状态工作负载提供存储卷,并配置初始容量。该存储的使用量可能会增长到达到初始容量的限制。对于这种情况,Kubernetes 提供了 扩容存储卷 的可能性。相反,不支持缩小存储卷。
许多分布式有状态工作负载还提供了另一种增加可用存储量的方法:简单地扩展 - 添加新实例(每个实例都有自己的新存储卷)最终会为整个系统增加容量。具体有多少容量(需要考虑复制逻辑)取决于实际的存储产品。
数据迁移有很多种场景。对于数据库,当数据库架构发生变化时,通常需要进行迁移。在 Kubernetes 中运行数据时,我们可以使用 Kubernetes 构造来促进这一点。Operator 可以使用 Kubernetes init-containers 和 Jobs 内置迁移数据库的功能。Job 会创建一个或多个 Pod,并将继续重试执行 Pod,直到指定数量的 Pod 成功终止。可以在跟踪任务成功完成情况的 Job 中指定数据库迁移逻辑。Init 容器是专用容器,在 Pod 中的应用容器之前运行。Init 容器可以包含应用映像中不存在的实用程序或设置脚本。Init 容器中的脚本可以检查迁移状态,以确保在数据库应用程序启动之前成功完成。
数据迁移可能也是必要的,因为托管数据库的存储基础架构需要更改。应用程序需要从一个 Kubernetes 集群迁移到另一个 Kubernetes 集群,或者从一个云迁移到另一个云,等等。可以使用 Operator 提供的备份和恢复功能来促进数据迁移。例如,如果两个集群都连接到同一个备份目标,则可以从源 Kubernetes 集群备份应用程序并将其恢复到目标 Kubernetes 集群中。
