在Kubernetes上部署自托管CockroachDB的完整指南

本文是一份详细的开发者指南,全面介绍了如何从零开始在Kubernetes(包括本地Minikube和生产环境GKE)上部署、配置、备份、扩展和安全管理分布式SQL数据库CockroachDB。

在Kubernetes上部署你自己的CockroachDB实例 [开发者完全指南]

开发者是聪明、了不起的人,也是你见过的最有逻辑的思考者之一。但我们在命名方面却相当糟糕 😂 比如,全世界有那么多可能的名称,他们怎么就决定用一个字面意义上的“蟑螂”来命名数据库呢?🤣 我明白:蟑螂以坚韧著称,开发者们可能是想表达“我们的数据库永远不会死”……但即便如此……用蟑螂? 抛开名字不谈,在众多数据库中,你可能会问为什么选择 CockroachDB?如果你确实选择了它,在尝试托管和部署时又该从哪里开始呢?你会选择托管的云服务吗?还是可以真正做到自我管理? 如果你曾想过自己动手——也许是在开发环境中,或者甚至将它引入公司——你会怎么做呢? 好吧,先别紧张 😄 在这本书中,我们将探讨在 Kubernetes 上部署和管理 CockroachDB 所需了解的一切。我们将深入探讨:

  • 了解 CockroachDB 的无主(多主)架构实际是如何工作的
  • 在 Kubernetes 集群上设置和部署 CockroachDB
  • 使用 CockroachDB 集群中的几个查询自动备份到 Google Cloud Storage
  • 安全管理服务账户和身份验证
  • 调整 CockroachDB 的内存设置以获得稳定的性能
  • 在不中断服务的情况下水平和垂直扩展集群
  • 像专业人士一样监控和维护数据库

到最后,你不仅会理解 CockroachDB 的工作原理,还会有足够的信心部署和管理你自己的、具有韧性的、可用于生产环境的实例。🚀

目录

CockroachDB 到底是什么?🤔

在我们深入设置 Kubernetes 集群和部署 CockroachDB 集群之前,让我们先了解一下 CockroachDB 到底是什么。(因为如果你不理解其背后的原因和方式,实现和实操部分就会感觉像变魔术一样 😅。)

简单定义

CockroachDB 是一个分布式 SQL 数据库。这意味着它提供了关系型数据库的特性(表、SQL 查询、JOIN、事务),但会将数据复制到多个副本(服务器、节点、实例)。无需手动分片。😃 它被设计成能够承受故障、易于扩展(相比其他 SQL 数据库),并且无论发生什么情况都能保持数据一致性(跨越所有实例)。

谁创建了 CockroachDB?什么时候发布的?

CockroachDB 由 Cockroach Labs 创建,公司由 Spencer Kimball、Peter Mattis 和 Ben Darnell 创立。这个想法大约在 2014 年开始成形,到 2015 年 Cockroach Labs 正式成立。 其 1.0 “生产就绪”版本于 2017 年发布,标志着它从测试版过渡到适合现实世界使用的阶段。

CockroachDB 试图解决什么问题?

传统的关系型数据库很棒,但当你的应用程序增长时会遇到真正的挑战。CockroachDB 就是为了解决这些问题而构建的。以下是关键痛点以及 CockroachDB 如何应对它们:

痛点 通常会发生什么 CockroachDB 如何解决
单主节点瓶颈 只有一个 “主”节点处理写入、更新和删除。该节点在不中断服务的情况下可能难以扩展(适应数据库使用量) CockroachDB 是多主的,意味着每个节点都可以接受读取和写入。整个集群没有单一的“主”节点。
手动分片复杂性 你必须手动拆分数据(分片),决定哪个部分放在哪里,并处理跨分片查询,很多麻烦 😖。 CockroachDB 自动将数据分割成更小的单元(称为范围)并移动它们以平衡负载。
故障转移停机时间 如果主节点故障,你需要提升一个副本(只读实例)并进行切换。在此期间,你的应用程序可能会宕机。 因为没有单一的主节点,如果其中一个实例故障,其他实例会无缝接管(通过共识)而不会造成大的中断。
地理扩展和延迟 为不同地区的用户提供服务很困难——要么数据很远(慢),要么你必须构建复杂的复制逻辑。 CockroachDB 允许你跨区域分布节点。你可以在保持全局一致性的同时提供本地读/写服务。

因此,与其在数据库增长时与之对抗,不如让 CockroachDB 为你处理大部分繁重的工作。

你应该了解的关键术语(用通俗语言)

  • 节点: 你的数据库的副本。这些也称为副本。它们可以是只读的(只能从中读取数据的数据库,例如使用 SELECT 语句),或者读写的(可以从中读取、创建、更新和删除数据的数据库)。
  • 复制: 在多个节点上创建数据副本。如果一个节点故障,其他节点仍然拥有数据。
  • Raft(共识算法): 一种确保副本以安全、可靠的方式就变更达成一致的系统。例如,当你想写入数据时,Raft 确保大多数副本在数据被接受之前达成一致。
  • 分片 / 范围: CockroachDB 不是将所有数据放在一个大块中,而是将其分割成称为范围的小块。每个范围都被复制,并且可以在节点之间移动。
  • 分布式事务: 一个可能触及存储在不同节点中的数据的事务(一系列操作)。CockroachDB 管理这一点,因此你仍然可以获得 ACID(原子性、一致性、隔离性、持久性)属性。

为什么叫 “CockroachDB”?😅

你可能会想:为什么用一个蟑螂的名字来命名数据库?乍一听很奇怪,但有一个原因: 蟑螂以在恶劣条件下生存而闻名:辐射、自然灾害等等。创始人想要一个感觉“几乎不可能被杀死”的数据库,能够在节点故障、中断和网络分区中幸存下来。这个名字是对其韧性的一个幽默调侃。

为什么选择 CockroachDB 而不是 PostgreSQL 或 MongoDB?🤷🏾‍♂️

让我们比较一下经典设置(Postgres / MongoDB)和 CockroachDB,特别是为什么你可能想选择 CockroachDB,以及它如何帮助简化扩展。我也会解释一些术语以确保你能跟上。

在许多设置中,当你使用 Postgres 或 MongoDB 时,通常会有一个“主”节点处理所有写入(即插入、更新、删除)。 然后你有多个“只读副本”,它们复制主节点的数据并处理读请求(查询)。这没问题——读取可以分散开来——但所有写流量都流向那个单一的主节点。 通常,当写入量增长时(例如,更多客户在你的平台上创建账户和产品),主节点最终会承受压力。 你可以添加更多只读副本(读的水平扩展,例如客户尝试查看他们的账户或网站上之前创建的产品),但扩展主节点要困难得多。 要扩展主节点,你通常会升级其资源(CPU、RAM、磁盘)——这是垂直扩展——这通常需要停机(关闭主数据库,增加其 CPU 和 RAM,然后重新启动它)。 或者你必须手动分片(拆分)数据到多个主节点,仔细路由流量,并管理复杂性。

PostgreSQL 和 MongoDB 如何处理容错

当你尝试在自我管理的设置中使 Postgres(或 MongoDB)高可用和容错时,你通常需要两个或更多只读副本和一个主节点。 棘手的部分是处理当主节点故障(或暂时停机升级)时会发生什么。你需要一个可以自动将副本提升为主节点的工具。 在 Postgres 领域,这通常由 Patroni 或 repmgr(处理集群管理、故障转移、领导者选举等工具)来处理。 在 MongoDB 中,这种逻辑是副本集行为的一部分:它会在副本之间进行自动选举。 以下是该经典模型的一些核心挑战:

  • 每次写入都必须发送到单一的主节点。如果该主节点故障或过载,你的整个系统都会受到影响。
  • 扩展读取很容易(添加更多副本),但扩展写入很困难。
  • 垂直扩展(给一个服务器更多资源)有其缺点。如果主节点需要更多资源,你在扩展它时可能会遇到一些停机时间。
  • 手动分片很混乱:你需要决定哪部分数据去哪个分片,处理跨分片查询,并构建路由逻辑。这需要大量维护,如果处理不当可能导致意外问题。

通常的模式是:

  • 一个服务(或负载均衡器/代理)指向主节点(用于所有写查询)。
  • 另一个服务或路由逻辑处理读查询,并可以在副本之间分配读取。
  • 你可能对 Postgres 使用 HAProxy、pgpool-II 或 pgBouncer 来路由流量,进行读写分离,或管理连接池。这些都是你需要配置的外部(不属于数据库核心)工具。

所以当主节点故障时,Patroni(或 repmgr 等)会检测到它并将一个只读副本提升为新的主节点。 但那次提升、重新配置和流量重路由通常会导致短暂的停机窗口(当你的主数据库节点变得不可用时)。

CockroachDB 如何处理(不同之处)

CockroachDB 改变了规则:

  • 所有副本对于读取和写入都是平等的。你没有专门处理写入的特殊“主”节点。集群中的每个节点都可以接受写请求。
  • CockroachDB 将你的数据分解成小块(范围)并在节点间复制它们。如果你添加一个新节点,数据会自动移动以平衡负载。
  • 每次写入都会自动复制到其他副本,一致性由协议(Raft)管理,所以你不需要自己构建这个。
  • 不需要手动分片。因为数据库处理数据如何分割和移动,你不需要手动决定如何分片。
  • 你不需要特殊的服务来路由写查询与读查询。任何节点都可以同时接受读取和写入。
  • 在扩展期间,你不必担心哪个节点是主节点——因为没有主节点。
  • 你可以逐个节点扩展(滚动升级方式)。当一个节点正在升级时,其他节点继续处理流量。你不会仅仅因为扩展“主节点”而遇到停机窗口。
  • 因为没有副本提升逻辑需要处理,所以没有需要将副本“提升”为主节点的时刻——所有节点都只是继续服务。

CockroachDB 幕后工作原理 ⚙️

在 CockroachDB 中,幕后有许多活动部分。但它们协同工作,所以你不需要一直盯着它们。我们已经大致谈到的核心思想是:

  • 将数据分割成小块(范围)
  • 保留每个块的多个副本(副本/复制)
  • 通过 Raft 共识确保所有副本达成一致
  • 移动块以平衡负载(自动重新平衡/分发)
  • 协调可能触及许多块的事务

让我们逐一讲解。

范围:数据的小块

想象你有一本巨大的食谱书。如果你试图携带整本书,它很重。所以你把书分成更小的册子,每本涵盖一定范围的餐食:早餐、午餐、晚餐、甜点。 在 CockroachDB 中,数据被分割成范围,就像那些更小的册子:

  • 每个范围涵盖某个数据块(比如“所有 ID 为 1-1000 的用户”)
  • 当一个范围变得太大时(比如一个册子里有太多食谱),它会被切割/分割成两个更小的范围。这使得每个部分更易于管理。
  • 如果两个相邻的范围变得非常小(食谱很少),它们可能会合并(连接)在一起,这样你就不会保留太多小册子。
  • 这些分割和合并在幕后自动发生,因此随着事物增长或收缩,数据库保持平稳。

这种切分在很多方面帮助系统:移动块、复制它们、平衡负载、从节点故障中恢复变得更容易。

复制:多个副本保障安全

没人喜欢丢失工作,所以你保留备份副本。CockroachDB 也为数据做这件事。 对于每个范围,通常有 3 个副本存储在不同的机器(节点)上。如果一台机器宕机,你还有其他副本。并且这些副本始终保持同步:当你写入某些内容时(例如插入或更新),变更会传播到其他副本。 数据库也能容忍故障。如果一个节点宕机,系统会检测到并最终在其他地方创建一个新副本来替换它。因此目标副本数量得以维持。这为你提供了容错能力:即使系统部分故障,你的数据也能保持安全。

Raft 共识:所有副本如何达成一致

拥有副本很有用,但你还需要它们彼此同意——就像你所有的食谱册子副本都有相同的内容。Raft 协议是一种确保可靠发生的方式。 用简单的术语描述 Raft 的工作原理:

  • 每个范围都有一组副本。其中一个副本充当领导者。其他是追随者。
  • 对该范围的所有写请求都通过领导者处理。领导者收到请求,然后告诉追随者记录相同的变更。
  • 一旦大多数副本(多数)说“是的,我们收到了”,变更就被视为最终确定(提交)。然后领导者告诉客户端“完成”。
  • 如果领导者停止工作(机器宕机或网络故障),追随者会注意到(它们停止收到定期的“我还活着”消息),然后它们会举行选举选出新的领导者,一切继续。

这样,系统确保每个人都拥有相同的最终数据,并且不会发生冲突的变更。

MultiRaft:在扩展时保持 Raft 高效

当你有很多范围(很多册子块)时,每个范围都有自己的 Raft 组。这可能意味着节点之间有很多“你还活着吗?”消息,以及大量开销。MultiRaft 是 CockroachDB 用来提高效率的技巧。 MultiRaft 将许多共享节点的范围的 Raft 工作分组在一起,从而减少了开销。它发送捆绑的心跳(你还活着吗?)消息,而不是为每个范围发送单独的消息。 这减少了网络 chatter 和资源浪费,并帮助数据库在你拥有大量数据和许多数据块时平稳扩展。

重新平衡:为了平衡而移动

当你的范围没有均匀分布在节点(机器)之间时,一些机器做了太多工作,而一些几乎没有。这不好。所以 CockroachDB 自动移动块来平衡事物。

  • 系统监视每个节点的繁忙程度(它持有多少范围,多少数据,多少读/写流量)。
  • 如果一个节点过载,它会将一些范围移动到其他节点。
  • 如果一个节点宕机,系统会注意到并确保该节点上的范围在其他地方被复制,以保持安全性(副本数量)。
  • 如果你添加一个新节点,系统开始将范围移动到新节点,以便利用其资源。

这在你无需手动决定“把这个移到这里,把那个移到那里”的情况下发生。

分布式事务:跨多个范围执行工作

通常,一个操作会触及多个范围。例如,“将钱从账户 A(在范围 1 中)转移到账户 B(在范围 2 中)”。这必须小心处理,以便要么两部分都成功,要么都不成功。 CockroachDB 支持分布式事务,这意味着单个事务可以跨多个范围工作。它使用“意向”写入(临时占位符),一旦一切准备就绪,它就提交事务使其成为永久性的。如果有任何失败,它会中止(取消)整个事务。系统确保原子行为:要么全部成功,要么全部失败。

这一切如何组合在一起:读取 + 写入流程(当你使用它时会发生什么)

让我们逐步描绘一次写入:

  1. 你的应用程序发送一次写入(例如“添加新用户”)到 CockroachDB 集群中的任何节点。
  2. 该节点确定涉及哪个(些)范围(哪些数据块包含你要写入的数据)。
  3. 对于每个范围,写入发送到该范围的领导者。
  4. 领导者将变更写入他们自己的副本,然后告诉追随者也这样做。
  5. 一旦大多数副本确认它们已接收变更,领导者就声明它“已提交”并告诉你的应用程序,“是的,写入完成。”
  6. 如果一个节点繁忙或宕机,其他节点仍然处理流量。

读取流程:

  1. 你的应用程序发送一次读取(例如“按 ID 获取用户”)到任何节点。
  2. 该节点检查其副本。如果它有一个新的副本,它就回答。如果没有,它会询问拥有副本的节点。

一切都正常运行,因此即使机器故障或网络延迟,数据也是正确、最新且可靠可用的。

为什么这一切很重要(用通俗语言解释)

所有这些调整之所以重要,有几个关键原因。首先,因为数据被分割成范围并复制,没有单一节点是瓶颈。此外,Raft 确保共识,因此你可以相信所有工作副本的数据是一致的。 除此之外,重新平衡是自动的,你不需要微观管理分片或担心节点负载过载。并且因为触及多个范围的事务是协调的,即使在分布式设置中,你也可以信任 ACID 属性。

在哪里(以及如何)托管 CockroachDB?☁️

并非只有一种“正确”的方式来托管 CockroachDB。你可以选择几条路径,每条都有其优缺点。你的选择取决于成本、控制、易用性和风险承受能力。 在本节中,我们将探讨:

  • Cockroach Labs 自己的托管云(CockroachDB Cloud)
  • “自带云”(BYOC)——让 Cockroach Labs 在你的云账户内管理它
  • 通过云市场托管(AWS、GCP、Azure)
  • 自我托管 / Kubernetes / 你自己的基础设施
  • 以及关于 DigitalOcean 支持的说明

让我们开始吧。

选项 1:CockroachDB Cloud(由 Cockroach Labs 完全托管)

这是卸载操作的最简单选择。你不管理节点(计算机、虚拟机等)、升级或备份,因为 Cockroach Labs 处理所有这一切。 它提供什么:

  • 你注册并点击“创建集群”。
  • 自动扩展、零停机升级和托管备份。
  • 它支持幕后多个云提供商(你选择区域)。
  • 你获得工具、API 和 Terraform 集成来自动化它。
  • 他们通常会提供免费额度让你开始。

权衡:

  • 你对底层基础设施的控制较少,例如虚拟机、网络、磁盘等(你为了便利性而牺牲控制)。
  • 你为托管服务溢价付费。
  • 你依赖 Cockroach Labs 的 SLA、正常运行时间和支持。

选项 2:自带云(BYOC)

这是一个中间地带:你保留你的云环境,但让 Cockroach Labs 管理数据库。它让你控制基础设施、计费、网络等,同时仍然卸载了操作复杂性。 运作方式:

  • 你在你的云账户(AWS、GCP 等)内运行 CockroachDB Cloud。
  • Cockroach Labs 仍然处理配置、升级、备份和可观测性。你管理角色、网络和日志。
  • 对于遵守法规、将数据保留在你的云文件夹/账户内以及使用你的云折扣很有用。

权衡:

  • 你仍然需要正确设置云方面(VPC、IAM、角色)。
  • 比纯托管更复杂,但控制也更多。
  • Cockroach Labs 需要访问你账户的某些部分(权限)。

选项 3:使用云市场(AWS、GCP、Azure)

如果你已经使用云提供商,有时最简单的方法是通过他们的市场产品进行部署。它为你提供了熟悉性、计费简便性等。

  • GCP 市场 – CockroachDB 可在 Google Cloud Marketplace 上使用,使其更容易在你的 GCP 环境中部署。
  • AWS 市场 – CockroachDB 也在那里列出。
  • Azure 市场 – 也支持 Azure 部署(SaaS/托管列表)。
  • DigitalOcean – 支持使用其基础设施在 DigitalOcean 上部署 CockroachDB。

这些选项让你停留在你的云控制台内,使用你现有的云账户,并与你已经拥有的其他资源集成。 但根据市场产品的配置方式,你仍然负责某些操作任务(网络、安全、监控、备份)。

选项 4(我最喜欢的 😁):自我托管 —— 特别是使用 Kubernetes

如果你自我托管 CockroachDB,你将获得完全控制。你是一切的主人:机器、存储、网络、备份、升级、监控——所有一切。 更棒的是,使用 Kubernetes 意味着你的设置不绑定到一个云提供商。你稍后可以在 AWS、GCP、Azure 甚至本地运行它,几乎不需要更改。Kubernetes 为你提供了一个“可移植基础设施”层。 托管 CockroachDB 服务会向你收取“维护、升级、备份等”的额外费用——这些都包含在价格中。但当你自我托管时,你承担了负担,但也避免了支付那额外的溢价。你为计算、磁盘、网络和你的时间/运维工作付费。 你也可以在云端自我托管(使用云虚拟机)但仍然管理每一层:磁盘、网络、安全等。使用 Kubernetes,有一个甜蜜的中间地带:你为虚拟机获得云可靠性,但你完全控制其上的一切。

为什么对于数据库来说 Kubernetes 胜过 Docker Swarm 或 Hashicorp Nomad 等工具

因为 CockroachDB 是一个有状态系统(它保存数据),你需要对“即使在 Pod 重启或移动时也保持不变的数据”有强大的支持。Kubernetes 为此设计并提供了良好的原语。其他工具在这方面并不总是表现出色。 用简单的术语进行比较:

  • Docker Swarm / Docker Compose: 对于无状态应用程序(Web 服务器、API)很好,但当涉及到数据库时,它就力不从心。Swarm 本身不支持集群级别的持久卷声明,因此如果容器(数据库副本)移动到不同的节点(VM),它可能会失去对其存储的访问权限。开发人员通常手动将容器固定到特定节点以避免这种情况。
  • Nomad: 在某些方面更灵活、更简单,但在连接性、存储管理和容器内置工具方面的功能不如 Kubernetes 丰富。它在混合工作负载中运行良好,但处理复杂的数据库通常意味着你需要构建额外的层。
  • Kubernetes: 它对有状态工作负载有内置支持:
    • StatefulSets(正确管理每个数据库的数据): 这确保每个 CockroachDB 副本(Pod)即使 Pod 重启也能保持其身份和存储完整。因此,当情况发生变化时,数据库副本不会丢失其“名称”或数据。
    • 持久卷和持久卷声明(外部磁盘): 这些就像附加到 Pod(数据库副本)的专用硬盘或磁盘。即使 Pod 移动、崩溃或重启,磁盘(数据)仍然保留。Kubernetes 确保数据安全。
    • StorageClasses(选择你的磁盘): 你可以自定义存储数据的磁盘类型,例如:
      • HDD(最实惠,但较慢),
      • 平衡磁盘(启用 SSD,在成本和速度之间取得平衡),
      • 快速 SSD(非常快,CockroachDB 团队推荐,但比平衡磁盘贵一点)。
    • 滚动更新、反亲和性(无停机、高可用性、容错): 反亲和性意味着你可以告诉 Kubernetes,“不要把多个 CockroachDB 副本放在同一个 VM 或物理机器上。” 这可以保护你,如果一个 VM 出现问题,其他副本是安全的。
    • 滚动更新让你一次更新一个副本(配置、版本、资源)而不会使整个集群宕机。当一个副本更新时,其他副本提供服务。这有助于避免停机。
    • Kubernetes 还通过 StatefulSets 为副本提供了有序的启动/停止,因此事情是可预测且安全的。

垂直与水平扩展(之前的讨论——提醒) 你记得我们在前面的部分讨论过扩展:

  • 水平扩展意味着添加更多副本(更多 Pod,更多节点)以分散负载。
  • 垂直扩展意味着增加现有节点/副本的资源(CPU、RAM、磁盘)。

在像 Nomad 或 Docker Swarm 这样的工具中,垂直扩展往往更困难,通常涉及停止服务、关闭东西并重启 VM,这会导致停机。 Kubernetes 使得在 Pod 级别进行垂直和水平扩展更容易(你可以调整一个 Pod 的 CPU + RAM 大小)并管理滚动升级,这样你就不会一次关闭所有东西。 你也可以轻松地向集群添加更多数据库副本(以平衡负载并使数据库更快地处理查询),并且数据会自动复制到新的数据库副本(复制),特别是当你使用官方的 CockroachDB Helm Chart 时。

为什么其他工具(Swarm / Nomad / Docker Compose)在这里不匹配

Docker Swarm 和 Docker Compose 更简单易用,当你没有太多复杂性时很好。但它们缺乏稳定存储、副本的默认支持、有状态服务的垂直扩展、水平扩展等方面的强大功能。例如,Swarm 没有像 Kubernetes 那样的内置 StatefulSets 或动态卷供应。 Nomad 在某些方面比 Swarm 更灵活,但许多用户表示存储插件(CSI)比 Kubernetes 的弱。此外,对有状态应用程序的排序、滚动更新等功能内置支持较少。 因此,虽然这些工具对于更简单的应用程序(无状态服务、小型应用)运行良好,但当你拥有像 CockroachDB 这样的分布式有状态 SQL 数据库时,Kubernetes 为你提供了更多的安全性、更多的控制,减少了数据丢失或配置错误的机会。 正因为如此,在 Kubernetes 上运行 CockroachDB 为你提供了所需的内置工具,减少了你必须自己编写的定制管道数量。

权衡(需要注意的事项)

  • 你必须管理一切:备份、监控整个 CockroachDB 集群、承受故障(容错)和升级。这是工作 🥲。
  • 你需要了解基础设施(VM、磁盘、网络和节点间连接)和操作(或者有了解这些的队友——DevOps 工程师、云架构师、站点可靠性工程师)。
  • 使用托管的 Kubernetes(如 GKE、EKS、AKS)会有所帮助,因为你卸载了控制平面。你仍然管理节点、存储和更高层次。
  • 但即便如此,你避免了支付“数据库管理即服务”的溢价——你只支付基础设施加上你的时间。

设置本地环境 🧑‍💻

好了,到目前为止我们已经学了不少:CockroachDB 是什么,它幕后如何工作,以及你可以在哪里托管它。现在,是时候卷起袖子,亲自动手进行一些实际设置了。 在我们部署 CockroachDB 之前,我们需要一个安全的“游乐场”,在那里我们可以测试和实验,而无需接触云端或花费一分钱。

为什么选择这些工具?

在我们开始运行命令之前,先快速了解一下我们将使用哪些工具以及为什么:

  • Minikube: 一个在你的计算机上运行小型 Kubernetes 集群的工具。它为你提供了一个本地“迷你云”,你可以在其中部署和实验。
  • Kubectl: 你将用来与你的 Kubernetes 集群对话的命令行工具,用于部署应用程序、检查状态和管理资源。
  • Helm: Kubernetes 的包管理器。它帮助你安装复杂的应用程序(如 CockroachDB),减少手动步骤。

步骤 1:安装 Minikube

什么是 Minikube? Minikube 是一个轻量级工具,帮助你在个人计算机上运行一个小型 Kubernetes 集群。 将其视为你自己的迷你云环境,你可以在其中测试、部署和学习 Kubernetes(以及我们的情况,CockroachDB)。它非常适合在部署到云端之前进行学习和实验。

步骤 2:安装 kubectl

kubectl 做什么: kubectl 是让你与你的 Kubernetes 集群对话的命令行工具。使用它,你可以部署应用程序、检查集群健康状况以及管理集群内的资源。 当你使用 Minikube 以及稍后部署 CockroachDB 时,你会经常使用它。

步骤 3:安装 Helm

Helm 基本上是 Kubernetes 的包管理器。可以将其想象成你如何在计算机上使用 apt、yum 或 brew 来安装软件。Helm 对 Kubernetes 应用程序做类似的事情。 使用 Kubernetes,部署一个完整的应用程序通常意味着编写大量配置(清单——Deployments、Services、PersistentVolumes、ConfigMaps 等)。Helm 让我们将所有这些捆绑到一个单一的“包”(称为 chart)中,这样我们就不必逐个手动创建资源(这可能会管理起来很麻烦 😖)。 因为我们的目标是在 Kubernetes 上部署一个相当复杂的系统(CockroachDB)——包括有状态节点、持久存储、网络、SSL/TLS 等——使用 Helm chart 比从头开始制作数十个 YAML 文件要容易得多。 因此,在安装 CockroachDB 之前,我们将安装 Helm。这为我们提供了更轻松地部署和管理集群的工具包。

在 Minikube 上部署 CockroachDB(有趣的部分开始了!😁)

在去云端之前,我们将在本地 Minikube 上使用 Helm 部署 CockroachDB。 这个过程将帮助我们:

  • 了解 CockroachDB 如何在集群中运行
  • 学习 Kubernetes 如何管理数据库副本
  • 在部署到云端之前获得实践经验

步骤 1:访问 ArtifactHub

ArtifactHub 就像是 Kubernetes Helm Chart 的应用商店——一个庞大的开源 Helm chart 和软件包集合,你可以轻松安装。

步骤 2:探索 Helm Chart

你会注意到页面上有很多信息:

  • Default Values – 定义数据库如何运行的所有设置

如果看起来让人不知所措,别担心。我们会一起过一遍 😉

步骤 3:复制默认值

每个 Helm chart 都有一个默认配置文件。这些默认值通常对于本地设置来说太高级或太重,所以我们将创建自己的更轻量版本。但首先,让我们复制原始版本作为参考。

步骤 4:为我们的项目创建一个文件夹

我们将把所有内容组织在一个文件夹中。 mkdir cockroachdb-tutorial cd cockroachdb-tutorial

在这个文件夹内,创建一个新文件: nano cockroachdb-original-values.yml

现在粘贴你之前复制的所有默认值(使用 Ctrl+V 或右键单击 → 粘贴),然后保存并退出(在 nano 中按 Ctrl+O,然后按 Ctrl+X)。

步骤 5:理解关键配置

让我们分解一下你在文件中会注意到的几个重要值。

🧩 statefulset.replicas 这告诉 CockroachDB 在集群中运行多少个数据库节点(副本)。默认设置为 3,意味着你将拥有 3 个独立的数据库实例,它们都可以读写数据。

⚙️ statefulset.resources.requests 和 statefulset.resources.limits 这些设置告诉 Kubernetes 给 CockroachDB 多少 CPU 和内存。

  • requests: 保证的最小数量
  • limits: 允许的最大数量

CockroachDB 可能对内存有点贪心 😅,所以 limits 确保它不会占用所有内存而不给其他应用留空间。

💾 storage.persistentVolume.size 这定义了每个 CockroachDB 节点获得多少磁盘空间。例如,如果你将其设置为 10Gi 并且你有 3 个副本,则总使用量 = 30Gi。

💽 storage.persistentVolume.storageClass 这定义了要使用的磁盘类型:

  • standard: HDD(便宜但慢)
  • standard-rwo: SSD(更快且经济实惠)
  • pd-ssd 或 fast-ssd: NVMe(超快但昂贵)

🔐 tls.enabled 这控制 CockroachDB 是否需要 TLS 证书进行安全连接。 如果为 true,你需要为任何连接到集群的应用或客户端生成证书(而不是使用用户名和密码)。这强烈建议用于生产,但对于我们的本地 Minikube 设置,我们将禁用它,以便更容易地玩耍和测试连接。

步骤 6:为 CockroachDB Helm Chart 创建一个简化的值配置

我们现在将创建一个新的配置文件,为本地测试环境使用更轻的资源设置。 在同一文件夹中,创建: nano cockroachdb-values.yml

然后粘贴:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
statefulset:
  replicas: 3
  podSecurityContext:
    fsGroup: 1000
    runAsUser: 1000
    runAsGroup: 1000
  resources:
    requests:
      memory: "1Gi" # 你的设备上应该有 3GB+ 的 RAM 空闲;否则,你可以将其减少到 500Mi(这将使你的 PC 只需要 1.5 GB 的空闲 RAM)
      cpu: 1 # 与此相同,如果你没有 3 个 CPU 核心(1 个 CPU 核心 * 3 个副本),你可以将其减少到 500m CPU
    limits:
      memory: "1Gi"
      cpu: 1
  podAntiAffinity:
    type: ""
  nodeSelector:
    kubernetes.io/hostname: minikube

storage:
  persistentVolume:
    size: 5Gi # 确保你的本地机器上有 15GB+ 的空闲存储空间,如果没有,你可以将其减少到 2 - 3 Gi
    storageClass: standard

tls:
  enabled: false

init:
  jobs:
    wait:
      enabled: true

将 requests 和 limits 设置为相同的值可确保 Kubernetes 不会因高内存或 CPU 使用而终止 CockroachDB Pod。

YAML 值概述

现在,让我们一起理解 cockroachdb-values.yml 文件的内容。

podSecurityContext – 为什么你在 Minikube 上需要它:

1
2
3
4
podSecurityContext:
  fsGroup: 1000
  runAsUser: 1000
  runAsGroup: 1000

这个块设置了容器内 CockroachDB 进程运行的 Linux 用户和组 ID,以及挂载文件的组所有权。 简单来说为什么这很重要:

  • CockroachDB 进程在容器内以 UID 1000 运行。如果磁盘挂载(持久卷)由不同的 UID 拥有,Cockroach 就无法在那里创建文件并会因权限被拒绝而失败。
  • runAsUserrunAsGroup 使容器进程以 UID/GID 1000 运行。
  • fsGroup 使挂载的卷对该组可访问,因此进程可以写入 /cockroach/cockroach-data

简而言之,这些行确保数据库进程有权在挂载的磁盘(卷)上创建和写入文件,这在 Minikube 和其他本地设置中尤其重要,因为主机挂载的存储可能具有奇怪的权限。

podAntiAffinity 和 nodeSelector – 它们做什么:

1
2
3
4
5
podAntiAffinity:
  type: ""

nodeSelector:
  kubernetes.io/hostname: minikube

podAntiAffinity 是默认行为。通常这告诉 Kubernetes 将 Pod 分散到不同的节点(VM)上,这样副本就不会在同一台物理机器上运行。这对于高可用性有好处,因为一个节点故障不会杀死多个副本。 通过设置 type: ""(空),你禁用了那个分散规则,因此 Kubernetes 可以将多个 CockroachDB 副本放在同一个节点上。 nodeSelector 告诉 Kubernetes 仅调度 Pod 到与你设置的标签匹配的节点上(这里 kubernetes.io/hostname: minikube)。这强制所有 Pod 在名为 minikube 的节点上运行。

快速总结效果:

  • 适用于本地多节点 Minikube 集群测试,当只有一个节点具有正确挂载的可写存储时。
  • 不推荐用于生产,因为它将所有副本放在同一台机器上(单点故障)。

🚀 步骤 7:使用 Helm 安装 CockroachDB 集群

到目前为止干得漂亮!你已经创建了你的 cockroachdb-values.yml 文件并为 Minikube 设置了自定义配置。现在我们将实际部署集群。

我们要做什么: 我们将使用 Helm 通过我们的自定义值安装官方的 CockroachDB Helm chart。这将在本地启动你的 3 节点集群,以便你可以玩耍。

运行命令: helm install crdb cockroachdb/cockroachdb -f cockroachdb-values.yml

在这里:

  • crdb 是我们给这个发布版起的名称(如果你喜欢,可以选其他名称)。
  • cockroachdb/cockroachdb 告诉 Helm 使用哪个 chart。
  • -f cockroachdb-values.yml 告诉 Helm 使用我们的自定义文件而不是默认值。

命令运行后: 过了一会儿命令完成,你会看到输出告诉你创建了什么资源(Pod、服务、持久卷声明等)。

现在检查一切是否正常工作,这样做: kubectl get pods | grep -i crdb

这会过滤名称中包含“crdb”的 Pod

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计