这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

声明式配置

基础设施即代码,用声明式配置描述整个环境,幂等剧本自动调整。

如果您只有一分钟,请记住这张图:

flowchart LR
    subgraph Imperative["❌ 传统命令式"]
        direction TB
        I1["yum install postgresql..."]
        I2["initdb..."]
        I3["配置 postgresql.conf..."]
        I4["配置 pg_hba.conf..."]
        I5["配置 Patroni/HAProxy/监控..."]
        I6["启动服务..."]
        I7["需要 DBA 专家<br/>耗时 2-3 天"]
    end

    subgraph Declarative["✅ Pigsty 声明式"]
        direction TB
        D1["# pigsty.yml 配置文件"]
        D2["pg-test:<br/>  hosts:<br/>    10.10.10.11: primary<br/>    10.10.10.12: replica"]
        D3["# 一条命令创建<br/>bin/pgsql-add pg-test"]
        D4["🎉 10 分钟完成!"]
    end

    Imperative --> |转型升级| Declarative

核心价值:不用写脚本,不用记命令。只需用 YAML 描述"想要什么样的集群",Pigsty 自动帮你实现。


本章内容

章节 说明 核心问题
IaC 原理 声明式配置与幂等性的设计理念 为什么比手工操作更好?
配置清单 pigsty.yml 配置文件结构详解 配置文件怎么写?
配置示例 各类集群的声明式配置示例 有哪些现成的模板?

为什么需要声明式配置?

flowchart LR
    subgraph Problems["❌ 传统运维的问题"]
        direction TB
        P1["手工操作<br/>每次从头来,步骤遗漏,人为失误"]
        P2["环境不一致<br/>开发/测试/生产配置不同"]
        P3["不可追溯<br/>谁改了什么?什么时候?为什么?"]
        P4["灾难恢复困难<br/>机房故障后如何重建?"]
    end

    subgraph Solutions["✅ 声明式配置的优势"]
        direction TB
        S1["一份配置,随处运行<br/>YAML 描述完整环境"]
        S2["幂等执行,重复安全<br/>跑 100 遍结果都一样"]
        S3["Git 版本控制<br/>所有变更有记录,随时回滚"]
        S4["10 分钟灾难恢复<br/>配置 + 服务器 = 完整环境"]
    end

    Problems --> |转型| Solutions

工作原理

声明式 vs 命令式

特性 声明式(Pigsty) 命令式(传统)
关注点 期望状态(What) 执行步骤(How)
表达方式 “我要三节点高可用集群” “先装PG,再配复制,然后…”
可重复性 高,幂等 低,依赖执行顺序
可审计性 高,配置即文档 低,依赖日志和记忆
版本控制 容易,纯文本 困难,命令历史
学习曲线 学配置格式 学每个命令细节

执行流程

flowchart TB
    subgraph Step1["1️⃣ 编写配置清单"]
        Config["📄 pigsty.yml<br/>├── 全局配置<br/>├── 集群定义<br/>└── 实例定义"]
    end

    subgraph Step2["2️⃣ 执行剧本"]
        Cmd["🚀 bin/pgsql-add pg-test"]
        Cmd --> Read["读取配置"]
        Read --> Calc["计算目标状态"]
        Calc --> Compare["对比当前状态"]
        Compare --> Execute["执行必要操作"]
    end

    subgraph Step3["3️⃣ 系统达到期望状态"]
        R1["✅ PostgreSQL 主从复制"]
        R2["✅ Patroni 高可用"]
        R3["✅ HAProxy 负载均衡"]
        R4["✅ 监控告警"]
        R5["✅ 备份恢复"]
    end

    Step1 --> Step2 --> Step3

配置层次

Pigsty 采用三级配置覆盖机制:

flowchart TB
    subgraph Global["🌍 全局配置 (all.vars)"]
        G1["适用于所有集群的默认值"]
        G2["例如:pg_version: 17"]
    end

    subgraph Cluster["🏢 集群配置 (pg-test.vars)"]
        C1["该集群的特定配置"]
        C2["例如:pg_version: 16"]
    end

    subgraph Instance["💻 实例配置 (host.vars)"]
        I1["该实例的特定配置"]
        I2["例如:pg_role: primary"]
    end

    Global --> |覆盖| Cluster
    Cluster --> |覆盖| Instance

    Priority["📋 优先级:实例 > 集群 > 全局"]

快速示例

最简三节点集群

# pigsty.yml
pg-test:
  hosts:
    10.10.10.11: { pg_seq: 1, pg_role: primary }
    10.10.10.12: { pg_seq: 2, pg_role: replica }
    10.10.10.13: { pg_seq: 3, pg_role: replica }
  vars:
    pg_cluster: pg-test
bin/pgsql-add pg-test   # 一条命令创建

10 分钟后,您将拥有

  • ✅ 三节点流复制集群
  • ✅ 自动故障切换(RTO < 30s)
  • ✅ 读写分离与负载均衡
  • ✅ 完整监控告警
  • ✅ 自动备份恢复

带数据库和用户的集群

pg-app:
  hosts:
    10.10.10.21: { pg_seq: 1, pg_role: primary }
    10.10.10.22: { pg_seq: 2, pg_role: replica }
  vars:
    pg_cluster: pg-app
    pg_databases:
      - { name: appdb, owner: dbuser_app }
    pg_users:
      - { name: dbuser_app, password: 'SecurePass123', roles: [dbrole_readwrite], pgbouncer: true }

金融级安全集群

pg-finance:
  hosts:
    10.10.10.31: { pg_seq: 1, pg_role: primary }
    10.10.10.32: { pg_seq: 2, pg_role: replica }
    10.10.10.33: { pg_seq: 3, pg_role: replica }
  vars:
    pg_cluster: pg-finance
    pg_conf: crit.yml           # 同步复制,零数据丢失
    pg_rpo: 0
    pgbackrest_method: minio    # 远程备份
    pg_vip_enabled: true        # 启用 VIP
    pg_vip_address: 10.10.10.30/24

与 Kubernetes 的对比

概念 Kubernetes Pigsty
配置格式 YAML CRD YAML 清单
控制器 Operator Ansible 剧本
资源抽象 Pod/Service/… 集群/实例/服务
执行方式 持续调谐 按需执行
运行环境 容器 裸机/虚拟机
性能 有容器开销 原生性能
复杂度 需要 K8s 集群 仅需 SSH

Pigsty 的理念类似 K8s 的 CRD + Operator,但在裸机上实现:

  • 配置清单 ≈ Custom Resource Definition
  • Ansible 剧本 ≈ Operator Controller
  • 幂等执行 ≈ Reconciliation Loop

参数体系

Pigsty 提供 400+ 个可配置参数,覆盖所有组件:

类别 参数数量 说明
INFRA 100+ 基础设施:监控、DNS、NTP、CA
NODE 50+ 节点配置:软件包、内核参数、用户
PGSQL 200+ PostgreSQL:版本、配置、用户、HBA
REDIS 30+ Redis 集群配置
ETCD 20+ Etcd 集群配置
MINIO 20+ MinIO 配置

好消息:所有参数都有良好的默认值。零配置即可获得开箱即用的数据库。


适用场景

场景 IaC 优势
大规模部署 管理 100+ 集群,配置复用
多环境管理 开发/测试/生产配置一致
合规审计 配置变更可追溯
灾难恢复 10 分钟重建整套环境
团队协作 配置代码评审,知识共享
持续集成 与 CI/CD 流水线集成

最佳实践

配置管理

  1. 使用 Git 管理配置:版本控制、代码评审
  2. 分环境配置文件pigsty-dev.ymlpigsty-prod.yml
  3. 敏感信息单独管理:密码使用环境变量或 Vault

变更管理

  1. 先在测试环境验证:配置变更先测试
  2. 增量变更:避免大规模同时变更
  3. 保留回滚能力:Git 版本随时可回滚

团队协作

  1. 配置即文档:配置文件就是最好的文档
  2. 代码评审:配置变更走 PR 流程
  3. 知识沉淀:最佳实践沉淀到配置模板

接下来

深入了解声明式配置的细节:

相关话题:

1 - IaC 原理

声明式配置与幂等性的设计理念。

基础设施即代码(Infrastructure as Code)是一种将基础设施管理代码化的实践,让您可以像管理应用代码一样管理基础设施。


声明式配置

什么是声明式

声明式配置关注"期望状态",而非"执行步骤"。

命令式(传统方式):

# 执行一系列命令
yum install postgresql
systemctl start postgresql
createdb mydb
createuser myuser

声明式(IaC 方式):

# 声明期望状态
pg_databases:
  - name: mydb
pg_users:
  - name: myuser

优势

  1. 可读性:配置即文档,一目了然
  2. 可重复:相同配置产生相同结果
  3. 可审计:配置变更可追踪
  4. 可版本控制:使用 Git 管理配置历史

幂等性

什么是幂等性

幂等性意味着:多次执行相同操作,结果与执行一次相同

# 第一次执行:创建集群
./pgsql.yml -l pg-test

# 第二次执行:检查并调整到期望状态(无变化则不操作)
./pgsql.yml -l pg-test

# 结果相同:pg-test 集群处于期望状态

为什么重要

  • 安全重试:失败后可以安全地重新执行
  • 配置漂移修复:自动将系统调整回期望状态
  • 增量变更:只修改需要变更的部分

配置层次

Pigsty 采用三层配置覆盖机制:

┌─────────────────────────────────────────────────┐
│              全局配置 (all.vars)                 │
│         适用于所有集群的默认值                    │
└─────────────────────┬───────────────────────────┘
                      │ 覆盖
┌─────────────────────▼───────────────────────────┐
│            集群配置 (cluster.vars)               │
│         特定集群的定制配置                        │
└─────────────────────┬───────────────────────────┘
                      │ 覆盖
┌─────────────────────▼───────────────────────────┐
│            实例配置 (host.vars)                  │
│         特定实例的精细配置                        │
└─────────────────────────────────────────────────┘

示例

all:
  vars:
    pg_version: 16              # 全局默认:PG 16

  children:
    pg-oltp:
      vars:
        pg_conf: oltp.yml       # 集群级别:OLTP 模板
      hosts:
        10.10.10.11:
          pg_seq: 1
          pg_role: primary
        10.10.10.12:
          pg_seq: 2
          pg_role: replica
          pg_conf: tiny.yml     # 实例级别:覆盖为 tiny 模板

剧本机制

Ansible 剧本

Pigsty 使用 Ansible 剧本实现声明式配置:

./pgsql.yml     # PostgreSQL 模块剧本
./infra.yml     # 基础设施模块剧本
./node.yml      # 节点模块剧本
./etcd.yml      # ETCD 模块剧本

执行流程

1. 读取配置清单(pigsty.yml)
           ↓
2. 解析变量和主机分组
           ↓
3. 按任务顺序执行
           ↓
4. 检查当前状态 vs 期望状态
           ↓
5. 仅执行必要的变更
           ↓
6. 报告执行结果

最佳实践

版本控制

# 初始化 Git 仓库
cd ~/pigsty
git init
git add pigsty.yml
git commit -m "Initial configuration"

# 记录每次变更
git add pigsty.yml
git commit -m "Add pg-test cluster"

环境分离

pigsty/
├── pigsty.yml          # 当前环境配置
├── conf/
│   ├── prod.yml        # 生产环境
│   ├── staging.yml     # 预发环境
│   └── dev.yml         # 开发环境

配置验证

# 语法检查
ansible-playbook pgsql.yml --syntax-check

# 干运行(不实际执行)
ansible-playbook pgsql.yml --check

# 差异对比
ansible-playbook pgsql.yml --diff

2 - 配置清单

pigsty.yml 配置文件结构详解。

配置清单(Inventory)是 Pigsty 的核心配置文件,使用 YAML 格式描述整个基础设施的期望状态。


文件结构

默认配置文件为 pigsty.yml,位于 Pigsty 根目录:

---
# 全局配置
all:
  vars:
    # 全局变量...

  children:
    # 基础设施集群
    infra:
      hosts: { ... }
      vars: { ... }

    # ETCD 集群
    etcd:
      hosts: { ... }
      vars: { ... }

    # PostgreSQL 集群
    pg-meta:
      hosts: { ... }
      vars: { ... }

    pg-test:
      hosts: { ... }
      vars: { ... }
...

层次结构

全局级别(all.vars)

适用于所有主机和集群的默认配置:

all:
  vars:
    # 版本与区域
    version: v3.3.0
    region: default

    # 基础设施
    admin_ip: 10.10.10.10

    # PostgreSQL 默认配置
    pg_version: 17
    pg_conf: oltp.yml

集群级别(cluster.vars)

特定集群的配置,覆盖全局默认值:

pg-test:
  vars:
    pg_cluster: pg-test
    pg_version: 16              # 覆盖全局版本
    pg_conf: crit.yml           # 使用关键业务模板
    pg_databases:
      - name: testdb
    pg_users:
      - name: testuser

实例级别(host.vars)

特定实例的精细配置,最高优先级:

pg-test:
  hosts:
    10.10.10.11:
      pg_seq: 1
      pg_role: primary
    10.10.10.12:
      pg_seq: 2
      pg_role: replica
      pg_conf: tiny.yml         # 此实例使用 tiny 模板

集群定义

必需参数

每个集群必须定义以下参数:

参数 说明 示例
pg_cluster 集群名称 pg-meta
pg_seq 实例序号 1, 2, 3
pg_role 实例角色 primary, replica

完整示例

pg-test:
  hosts:
    10.10.10.11: { pg_seq: 1, pg_role: primary }
    10.10.10.12: { pg_seq: 2, pg_role: replica }
    10.10.10.13: { pg_seq: 3, pg_role: replica }
  vars:
    pg_cluster: pg-test
    pg_version: 17

    # 数据库定义
    pg_databases:
      - name: testdb
        owner: testuser
        extensions:
          - postgis
          - pg_stat_statements

    # 用户定义
    pg_users:
      - name: testuser
        password: DBUser.Test
        roles: [dbrole_readwrite]

    # 连接池
    pg_default_services:
      - { name: primary, port: 5433, dest: primary }
      - { name: replica, port: 5434, dest: replica }

变量覆盖规则

优先级从低到高:

1. 角色默认值(roles/xxx/defaults/main.yml)
       ↓
2. 全局变量(all.vars)
       ↓
3. 集群变量(cluster.vars)
       ↓
4. 实例变量(host.vars)
       ↓
5. 命令行变量(-e "key=value")

示例

all:
  vars:
    pg_version: 17              # 全局默认 PG 17

  children:
    pg-legacy:
      vars:
        pg_version: 15          # 此集群使用 PG 15
      hosts:
        10.10.10.21:
          pg_seq: 1
          pg_role: primary
          pg_version: 14        # 此实例使用 PG 14(特殊需求)

多环境管理

环境分离

为不同环境创建独立配置文件:

pigsty/
├── pigsty.yml              # 当前环境(软链接)
├── conf/
│   ├── prod.yml            # 生产环境
│   ├── staging.yml         # 预发环境
│   ├── dev.yml             # 开发环境
│   └── demo.yml            # 演示环境

切换环境

# 方式一:使用软链接
ln -sf conf/prod.yml pigsty.yml

# 方式二:使用 -i 参数
./pgsql.yml -i conf/prod.yml -l pg-test

配置验证

语法检查

# YAML 语法检查
python3 -c "import yaml; yaml.safe_load(open('pigsty.yml'))"

# Ansible 语法检查
ansible-playbook pgsql.yml --syntax-check

查看变量

# 查看特定主机的变量
ansible -i pigsty.yml 10.10.10.11 -m debug -a "var=hostvars[inventory_hostname]"

# 查看集群变量
ansible -i pigsty.yml pg-test -m debug -a "var=group_vars"

干运行

# 检查模式(不实际执行)
./pgsql.yml -l pg-test --check

# 差异对比
./pgsql.yml -l pg-test --diff

最佳实践

配置组织

  1. 全局变量精简:只放真正全局的默认值
  2. 集群变量完整:包含集群特有的所有配置
  3. 实例变量最少:只放必需的身份标识

命名规范

# 集群名:模块-用途
pg-meta          # PostgreSQL 元数据库
pg-order         # 订单服务数据库
redis-cache      # Redis 缓存集群

# 实例名:集群名-序号
pg-meta-1        # 集群 pg-meta 的第 1 个实例
pg-order-2       # 集群 pg-order 的第 2 个实例

版本控制

# 初始化 Git
cd ~/pigsty
git init
git add pigsty.yml
git commit -m "Initial configuration"

# 每次变更都提交
git add pigsty.yml
git commit -m "Add pg-order cluster"

3 - 配置示例

各类集群的声明式配置示例。

本节提供常见场景的配置示例,帮助您快速上手声明式配置。


单节点部署

最简单的配置,单节点运行所有组件:

all:
  children:
    infra:
      hosts: { 10.10.10.10: { infra_seq: 1 } }
    etcd:
      hosts: { 10.10.10.10: { etcd_seq: 1 } }
    pg-meta:
      hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
      vars: { pg_cluster: pg-meta }

高可用集群

三节点 HA 集群

pg-test:
  hosts:
    10.10.10.11: { pg_seq: 1, pg_role: primary }
    10.10.10.12: { pg_seq: 2, pg_role: replica }
    10.10.10.13: { pg_seq: 3, pg_role: replica }
  vars:
    pg_cluster: pg-test
    pg_version: 17

    # 高可用配置
    pg_conf: crit.yml            # 关键业务模板,同步复制

    # 业务数据库
    pg_databases:
      - name: testdb
        owner: testuser

    pg_users:
      - name: testuser
        password: DBUser.Test
        roles: [dbrole_readwrite]

同步复制配置

pg-sync:
  hosts:
    10.10.10.21: { pg_seq: 1, pg_role: primary }
    10.10.10.22: { pg_seq: 2, pg_role: replica }
    10.10.10.23: { pg_seq: 3, pg_role: replica }
  vars:
    pg_cluster: pg-sync

    # 同步复制:至少一个同步从库
    synchronous_mode: true
    synchronous_node_count: 1

读写分离

使用服务定义

pg-rw:
  hosts:
    10.10.10.31: { pg_seq: 1, pg_role: primary }
    10.10.10.32: { pg_seq: 2, pg_role: replica }
    10.10.10.33: { pg_seq: 3, pg_role: replica }
  vars:
    pg_cluster: pg-rw

    # 服务定义
    pg_default_services:
      - name: primary    # 读写服务
        port: 5433
        dest: primary

      - name: replica    # 只读服务
        port: 5434
        dest: replica
        selector: "[]"   # 所有从库

      - name: offline    # 离线查询
        port: 5436
        dest: offline
        selector: "[? pg_role == `offline` || pg_offline_query ]"

离线查询实例

pg-analytics:
  hosts:
    10.10.10.41: { pg_seq: 1, pg_role: primary }
    10.10.10.42: { pg_seq: 2, pg_role: replica }
    10.10.10.43:
      pg_seq: 3
      pg_role: replica
      pg_offline_query: true    # 可用于离线查询
      pg_weight: 0              # 不承载在线流量
  vars:
    pg_cluster: pg-analytics

OLTP 与 OLAP

OLTP 集群

pg-oltp:
  hosts:
    10.10.10.51: { pg_seq: 1, pg_role: primary }
    10.10.10.52: { pg_seq: 2, pg_role: replica }
  vars:
    pg_cluster: pg-oltp
    pg_conf: oltp.yml           # OLTP 模板

    # 连接池优化
    pgbouncer_poolmode: transaction
    pg_default_hba_rules:
      - { user: all, db: all, addr: intra, auth: pwd, title: 'allow intranet access' }

OLAP 集群

pg-olap:
  hosts:
    10.10.10.61: { pg_seq: 1, pg_role: primary }
    10.10.10.62: { pg_seq: 2, pg_role: replica }
  vars:
    pg_cluster: pg-olap
    pg_conf: olap.yml           # OLAP 模板

    # 分析扩展
    pg_libs: 'pg_stat_statements, auto_explain, pg_analytics'
    pg_extensions:
      - pg_analytics
      - duckdb_fdw

扩展配置

PostGIS 地理空间

pg-gis:
  hosts:
    10.10.10.71: { pg_seq: 1, pg_role: primary }
  vars:
    pg_cluster: pg-gis

    pg_databases:
      - name: gisdb
        extensions:
          - postgis
          - postgis_topology
          - postgis_raster
          - pgrouting

    pg_extensions:
      - postgis35
      - pgrouting

向量搜索

pg-vector:
  hosts:
    10.10.10.81: { pg_seq: 1, pg_role: primary }
  vars:
    pg_cluster: pg-vector

    pg_databases:
      - name: vectordb
        extensions:
          - vector
          - pg_search

    pg_extensions:
      - pgvector
      - pg_search

时序数据

pg-timeseries:
  hosts:
    10.10.10.91: { pg_seq: 1, pg_role: primary }
  vars:
    pg_cluster: pg-timeseries

    pg_databases:
      - name: tsdb
        extensions:
          - timescaledb

    pg_extensions:
      - timescaledb
    pg_libs: 'timescaledb, pg_stat_statements'

多集群部署

完整生产环境

all:
  vars:
    version: v3.3.0
    admin_ip: 10.10.10.10
    pg_version: 17

  children:
    # 基础设施
    infra:
      hosts:
        10.10.10.10: { infra_seq: 1 }
        10.10.10.11: { infra_seq: 2 }
      vars:
        node_cluster: infra

    # ETCD 集群
    etcd:
      hosts:
        10.10.10.10: { etcd_seq: 1 }
        10.10.10.11: { etcd_seq: 2 }
        10.10.10.12: { etcd_seq: 3 }
      vars:
        etcd_cluster: etcd

    # 元数据库
    pg-meta:
      hosts:
        10.10.10.10: { pg_seq: 1, pg_role: primary }
      vars:
        pg_cluster: pg-meta
        pg_databases:
          - name: meta

    # 用户服务数据库
    pg-user:
      hosts:
        10.10.10.21: { pg_seq: 1, pg_role: primary }
        10.10.10.22: { pg_seq: 2, pg_role: replica }
        10.10.10.23: { pg_seq: 3, pg_role: replica }
      vars:
        pg_cluster: pg-user
        pg_conf: crit.yml
        pg_databases:
          - name: userdb

    # 订单服务数据库
    pg-order:
      hosts:
        10.10.10.31: { pg_seq: 1, pg_role: primary }
        10.10.10.32: { pg_seq: 2, pg_role: replica }
      vars:
        pg_cluster: pg-order
        pg_databases:
          - name: orderdb

备份配置

本地备份

pg-local-backup:
  hosts:
    10.10.10.101: { pg_seq: 1, pg_role: primary }
  vars:
    pg_cluster: pg-local-backup

    pgbackrest_enabled: true
    pgbackrest_repo:
      local:
        path: /pg/backup
        retention_full: 2
        retention_full_type: count

MinIO 备份

pg-minio-backup:
  hosts:
    10.10.10.111: { pg_seq: 1, pg_role: primary }
  vars:
    pg_cluster: pg-minio-backup

    pgbackrest_enabled: true
    pgbackrest_repo:
      minio:
        type: s3
        s3_endpoint: minio.pigsty
        s3_bucket: pgsql
        s3_key: pgbackrest
        s3_key_secret: S3User.Backup
        retention_full: 7
        retention_full_type: time

安全配置

严格安全模式

pg-secure:
  hosts:
    10.10.10.121: { pg_seq: 1, pg_role: primary }
  vars:
    pg_cluster: pg-secure

    # SSL 强制
    pg_ssl_enabled: true
    pg_ssl_mode: require

    # 强密码策略
    pg_pwd_enc: scram-sha-256

    # 严格 HBA
    pg_default_hba_rules:
      - { user: dbsu,      db: all, addr: local,     auth: ident, title: 'dbsu via local ident' }
      - { user: replicator, db: replication, addr: intra, auth: pwd, title: 'replication' }
      - { user: all,       db: all, addr: intra,     auth: ssl,   title: 'intranet ssl only' }

配置模板

Pigsty 内置多种配置模板,位于 conf/ 目录:

模板 说明
meta.yml 单节点元数据库
demo.yml 四节点演示环境
prod.yml 生产环境模板
full.yml 完整参数示例
dual.yml 双节点 HA
trio.yml 三节点 HA

使用模板:

# 复制模板
cp conf/prod.yml pigsty.yml

# 根据实际环境修改
vim pigsty.yml