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, 分布式数据库, 分片, 力导向图, 多区域, 子域名突变, 拓扑编排, 故障转移, 数据一致性, 数据库分库分表, 数据库网关, 数据库集群管理, 日志审计, 测试用例, 滚动更新, 状态管理, 用户代理, 自动化运维, 自定义请求头