multigres/multigres-operator

GitHub: multigres/multigres-operator

Multigres Operator 是一个 Kubernetes operator,用于自动化部署、扩展和管理跨多个故障域的水平分片 PostgreSQL 集群,提供统一的拓扑编排与高可用能力。

Stars: 77 | Forks: 8

# Multigres Operator **[Multigres](https://github.com/multigres/multigres) Operator** 是一个 Kubernetes operator,用于管理跨多个故障域(可用区或区域)的分布式、分片 PostgreSQL 集群。它提供了统一的 API 来定义数据库系统的拓扑结构,处理 `shards`、`cells`(故障域)和 `gateways` 的复杂编排。 ## 目录 - [功能特性](#features) - [安装](#installation) - [工作原理](#how-it-works) - [配置与默认值](#configuration--defaults) - [备份与恢复](#backup--restore) - [可观测性](#observability) - [Webhook 与证书管理](#webhook--certificate-management) - [GitOps 与 Webhook 默认值](#gitops--webhook-defaults) - [池复制与 Quorum](#pool-replication--quorum) - [约束与限制](#constraints--limits-v1alpha1) - [扩展阅读](#further-reading) ## 功能特性 - **全局集群管理**:整个数据库拓扑的唯一事实来源 (`MultigresCluster`)。 - **自动化分片**:将 `TableGroups` 和 `Shards` 作为一等公民进行管理。 - **直接 Pod 管理**:直接管理单个 Pod 和 PVC(无 StatefulSets),支持针对性的退役、带主节点感知的滚动更新以及细粒度的 PVC 生命周期控制。 - **故障转移与高可用性**:在定义的 Cells 之间编排主节点/备用节点的故障转移。 - **模板系统**:只需定义一次配置(`CoreTemplate`、`CellTemplate`、`ShardTemplate`)即可在整个集群中复用。 - **分层默认值**:智能覆盖逻辑,支持全局默认值、命名空间默认值和细粒度的覆盖。 - **外部网关暴露**:通过带有可配置 `externalIPs` 的 `spec.externalGateway` 提供可选的外部网关支持,并由 `GatewayExternalReady` 条件进行跟踪。 - **外部管理 Web 暴露**:通过 `spec.externalAdminWeb` 提供对 multiadmin-web Service 的可选外部暴露,镜像网关模式并带有 `AdminWebExternalReady` 条件。 - **PostgreSQL 配置**:通过分片模板上的 `postgresConfigRef` 引用用户创建的、包含 `postgresql.conf` 覆盖配置的 ConfigMap。ConfigMap 内容的更改会触发自动滚动更新。 - **集成证书管理**:内置用于验证 webhook 的自签名证书生成和轮换,并可选支持 `cert-manager`。 ## 安装 ### 前置条件 - Kubernetes v1.25+ ### 快速入门 安装内置自签名证书管理的 operator: ``` kubectl apply --server-side -f \ https://github.com/multigres/multigres-operator/releases/latest/download/install.yaml ``` 这会将 operator 部署到 `multigres-operator` 命名空间中,包含: - 所有 CRD(MultigresCluster、Cell、Shard、TableGroup、TopoServer 及模板) - RBAC 角色和绑定 - 带有自签名证书(自动轮换)的 Mutating 和 Validating webhook - operator Deployment - 指标端点 operator 运行后,请尝试部署一个示例集群: ``` kubectl apply -f https://raw.githubusercontent.com/multigres/multigres-operator/main/config/samples/minimal.yaml ``` 有关更多示例配置,请参见 [samples 目录](config/samples/README.md)。 ### 部署选项 | 选项 | 描述 | 指南 | | :--- | :--- | :--- | | **自签名证书**(默认) | 零配置 TLS — operator 生成并轮换其自身的 CA。 | *(已在上方安装)* | | **cert-manager** | 通过 cert-manager 进行外部证书管理。 | [Cert-Manager 演示](demo/cert-manager/) | | **可观测性堆栈** | 全套指标、追踪和仪表盘(Prometheus、Tempo、Grafana)。 | [可观测性演示](demo/observability/) | ## 工作原理 Multigres Operator 遵循 **父/子** 架构。您(用户)管理 **根** 资源 (`MultigresCluster`) 及其共享的 **模板**。operator 会自动创建并协调所有必需的子资源(`Cells`、`TableGroups`、`Shards`、`TopoServers`),以匹配您的期望状态。 ### 资源层级结构 ``` [MultigresCluster] 🚀 (Root CR - User Editable) │ ├── 📍 Defines [TemplateDefaults] (Cluster-wide default templates) │ ├── 🌍 [GlobalTopoServer] (Child CR) ← 📄 Uses [CoreTemplate] OR inline [spec] │ ├── 🤖 MultiAdmin Resources ← 📄 Uses [CoreTemplate] OR inline [spec] │ ├── 💠 [Cell] (Child CR) ← 📄 Uses [CellTemplate] OR inline [spec] │ │ │ ├── 🚪 MultiGateway Resources │ └── 📡 [LocalTopoServer] (Child CR, optional) │ └── 🗃️ [TableGroup] (Child CR) │ └── 📦 [Shard] (Child CR) ← 📄 Uses [ShardTemplate] OR inline [spec] │ ├── 🧠 MultiOrch Resources (Deployment) └── 🏊 Pools (Operator-managed Pods + PVCs) 📄 [CoreTemplate] (User-editable, scoped config) ├── globalTopoServer └── multiadmin 📄 [CellTemplate] (User-editable, scoped config) ├── multigateway └── localTopoServer (optional) 📄 [ShardTemplate] (User-editable, scoped config) ├── multiorch └── pools (postgres + multipooler) ``` **重要提示**: * **仅** `MultigresCluster`、`CoreTemplate`、`CellTemplate` 和 `ShardTemplate` 允许用户编辑。 * 子资源(`Cell`、`TableGroup`、`Shard`、`TopoServer`)为**只读**。对它们的任何手动更改都将被 operator 立即还原,以确保系统与根配置保持同步。 ## 配置与默认值 operator 使用 **4 级覆盖链** 来解析每个组件的配置。这允许您在保持 `MultigresCluster` spec 简洁的同时,在需要时维持完全控制。 ### 1. 默认层级结构 在确定某个组件(例如 Shard)的配置时,operator 会按以下顺序查找配置: 1. **内联 Spec / 显式模板引用**:在 `MultigresCluster` YAML 中直接定义在组件上。 2. **集群级别模板默认值**:在 `MultigresCluster` 的 `spec.templateDefaults` 中定义。 3. **命名空间级别默认值**:在同一命名空间中名为 `"default"` 且类型正确的模板(例如,`ShardTemplate`)。 4. **Operator 硬编码默认值**:内置到 operator Webhook 中的回退值。 ### 2. 模板与覆盖 模板允许您定义标准配置(例如,“标准高可用性 Cell”)。然后,您可以在模板之上应用特定的**覆盖**。 **示例:使用带有覆盖的模板** ``` spec: cells: - name: "us-east-1a" cellTemplate: "standard-ha-cell" # <--- Uses the template overrides: # <--- Patches specific fields multigateway: replicas: 5 # <--- Overrides only the replica count ``` **关于覆盖的注意事项**:在使用 `overrides` 时,如果被覆盖的部分是一个指针,则必须提供该部分的完整结构体。对于像 resources 这样的特定字段,如果合并行为不能满足您的细粒度需求,更安全的做法是确保提供完整的上下文(目前,解析器执行的是深度合并)。 ### 3. 模板更新行为 对于希望进行受控推出的生产环境,请考虑**按名称对模板进行版本控制**: ``` # 不再就地编辑 "standard-shard"... apiVersion: multigres.com/v1alpha1 kind: ShardTemplate metadata: name: standard-shard-v2 # <--- New version = new resource spec: # ... updated configuration ``` 然后在准备就绪时单独更新每个集群的 `templateRef`: ``` spec: templateDefaults: shardTemplate: "standard-shard-v2" # <--- Opt-in to the new version ``` ## 备份与恢复 operator 集成了 **pgBackRest** 用于自动备份、WAL 归档和时间点恢复 (PITR)。支持两种存储后端:**S3**(推荐用于生产和多单元集群)和 **Filesystem**(基于 PVC,用于开发/单节点)。备份配置是完全声明式的,并从集群级别向下传播到各个分片。 主要特性: - **基于副本的备份** — 在副本上运行备份以避免影响主节点 - **S3 凭证选项** — IRSA、静态凭证或 EC2 实例元数据 - **自动生成的 TLS** — pgBackRest 节点间 TLS 自动管理,并支持可选的 cert-manager 📖 **完整文档:** [备份与恢复指南](docs/backup-restore.md) ## 可观测性 operator 内置支持**指标**、**告警**、**分布式追踪**和**结构化日志**。 - **指标** — 包含 8 个 operator 专用指标 + controller-runtime 框架指标的 Prometheus 端点 - **告警** — 10 个预配置的 PrometheusRule 告警,附带专用的运维手册([查看运维手册](docs/monitoring/runbooks/)) - **Grafana 仪表盘** — Operator 仪表盘、每个集群的拓扑仪表盘以及数据面操作仪表盘 - **分布式追踪** — 支持 OpenTelemetry OTLP,默认禁用,关闭时零开销 - **结构化日志** — JSON 日志格式,自动注入 `trace_id`/`span_id` 以实现日志与追踪的关联 📖 **完整文档:** [可观测性指南](docs/observability.md) · [可观测性演示](demo/observability/) ## Webhook 与证书管理 operator 包含一个 Mutating 和 Validating Webhook,用于执行默认设置和数据完整性校验。 ### 自动证书管理(默认) 默认情况下,operator 使用通用的 `pkg/cert` 模块管理其自身的 TLS 证书。这实现了 **Split-Secret PKI** 架构: 1. **引导**:在启动时,证书轮换器生成一个自签名的根 CA(ECDSA P-256)和一个服务器证书,并将它们存储在两个独立的 Kubernetes Secrets 中。 2. **CA Bundle 注入**:reconcile 后的 hook 会自动为 `MutatingWebhookConfiguration` 和 `ValidatingWebhookConfiguration` 打补丁以注入 CA bundle。 3. **轮换**:后台循环每小时检查一次证书。临近过期(或由已轮换的 CA 签名)的证书将自动续期,不会造成停机。 4. **所有者引用**:这两个 secret 都归 operator Deployment 所有,因此在卸载时会被垃圾回收。 ### 使用外部 Cert-Manager 如果您倾向于使用 `cert-manager` 或其他外部工具,请使用 cert-manager overlay (`install-certmanager.yaml`) 进行部署。此 overlay 会: 1. 创建一个 `Certificate` 和 `ClusterIssuer` 资源供 cert-manager 管理。 2. 将 cert-manager 预配的 secret 挂载到 `/var/run/secrets/webhook`,以便证书在启动时存在于磁盘上。 operator 会在启动时**自动检测**证书管理策略: - 如果证书已存在于磁盘上,且 operator 先前未管理过它们(无 cert-strategy 注解),它会假定存在外部提供者(如 cert-manager)并跳过内部轮换。 - 如果磁盘上不存在证书,或者 operator 先前已对 ValidatingWebhookConfiguration 进行了注解,则会启用内部证书轮换。 📖 **Cert-Manager 演练:** [Cert-Manager 演示](demo/cert-manager/) ## GitOps 与 Webhook 默认值 operator 的 Mutating Webhook 会将所有默认值(镜像、副本、资源、备份配置等)直接物化到存储在 etcd 中的 `MultigresCluster` spec 中。这意味着 `kubectl get multigrescluster -o yaml` 始终显示完整的有效配置 — 没有隐藏的内存默认值。 某些字段(如分片上的单元分配)被有意保持动态,并在 reconcile 时解析。解析后的值在子 CR(`Shard`、`TableGroup`)上可见。 如果您使用 GitOps 工具(ArgoCD、Flux),webhook 物化的字段可能会导致 Git 清单与实时状态之间产生差异。文档涵盖了建议的缓解措施。 📖 **完整文档:** [Webhook 默认值与 GitOps 指南](docs/gitops-and-webhook-defaults.md) ## 池复制与 Quorum Multigres 使用可配置的**持久化策略**来控制同步复制 quorum。默认策略为 `AT_LEAST_2`,这要求每次写入至少被 2 个节点(主节点 + 1 个同步备用节点)确认。对于多 AZ 集群,`MULTI_CELL_AT_LEAST_2` 强制执行跨可用区 quorum。这对您在 `readWrite` 池中每个单元应运行的副本数量有影响。 | 每单元副本数 | 配置 | 滚动升级行为 | | :--- | :--- | :--- | | **1** | 1 个 pod(仅主节点,无备用节点) | **升级期间会停机。** 没有备用节点来维持 quorum。 | | **2** | 1 个主节点 + 1 个备用节点 | **升级期间会停机。** 排空备用节点后会导致零个同步备用节点,违反了 `AT_LEAST_2` 要求。上游 multigres 会拒绝 `UpdateSynchronousStandbyList REMOVE` 操作,因为这会使同步备用节点列表变空。 | | **3**(推荐) | 1 个主节点 + 2 个备用节点 | **零停机升级。** 可以排空一个备用节点,同时由另一个备用节点维持 quorum。 | operator 强制执行每个单元**最少 1 个**副本的硬性要求(CRD 会拒绝 `replicasPerCell: 0`)。对于少于 3 个副本的池,webhook 会返回一个**准入警告**(而非拒绝),解释 quorum 限制。 📖 **完整文档:** [持久化策略](docs/durability-policy.md) ## 约束与限制 (v1alpha1) 请注意当前版本中的以下约束: * **数据库限制**:每个集群仅支持 **1** 个数据库。它必须命名为 `postgres` 并标记 `default: true`。 * **分片命名**:分片当前必须命名为 `0-inf` — 这是当前 Multigres 实现的一个限制。 * **命名长度**: * **TableGroup 名称**:如果组合名称 (`cluster-db-tg`) 超过 **28 个字符**,operator 会自动对数据库和 tablegroup 名称进行哈希处理,以确保生成的子资源名称(Shards、Pods、PVCs)保持在 Kubernetes 限制(63 个字符)之内。 * **集群名称**:建议保持在 **20 个字符**以下,以确保即使经过哈希处理,后缀也能舒适地容纳。 * **不可变**:Cell 定义中的某些字段(如 `zone` 和 `region`)在创建后是不可变的。 * **仅追加的 Pools 和 Cells**:无法重命名或从集群中移除 Pools 和 Cells。这可以防止产生孤立的 pod 和过期的 etcd 注册信息。 ## 扩展阅读 | 资源 | 描述 | | :--- | :--- | | [Operator 能力等级](docs/operator-capability-levels.md) | 针对 [Operator Framework 能力模型](https://operatorframework.io/operator-capabilities/)的成熟度评估 | | [Webhook 默认值与 GitOps](docs/gitops-and-webhook-defaults.md) | Webhook 如何物化默认值、动态单元解析以及 GitOps 兼容性 | | [持久化策略](docs/durability-policy.md) | 可配置的复制 quorum:`AT_LEAST_2`(默认)和用于跨 AZ 持久化的 `MULTI_CELL_AT_LEAST_2` | | [外部管理 Web](docs/external-admin-web.md) | multiadmin-web Service 的外部暴露 | | [PostgreSQL 配置](docs/postgresql-configuration.md) | 通过 ConfigMap 引用自定义 `postgresql.conf` 覆盖 | | [存储管理](docs/storage.md) | PVC 删除策略(Retain/Delete)和卷扩容 | | [配置参考](docs/configuration.md) | Operator 标志、环境变量和日志记录 | | [演示](demo/) | 引导式演练(webhook、cert-manager、可观测性) | | [开发者文档](docs/development/) | 内部架构、控制器模式、缓存策略 | | [贡献](CONTRIBUTING.md) | 开发环境设置、本地 Kind 部署、代码风格 | | [更新日志](CHANGELOG.md) | 发布历史 |
标签:EVTX分析, GitOps, Operator, PostgreSQL, PVC, Webhook, 分布式数据库, 分片, 力导向图, 多区域, 子域名突变, 拓扑编排, 故障转移, 数据一致性, 数据库分库分表, 数据库网关, 数据库集群管理, 日志审计, 测试用例, 滚动更新, 状态管理, 用户代理, 自动化运维, 自定义请求头