跳转到内容

PostgreSQL on Kubernetes 运维面试题

30 道题
分类
Kubernetes
子分类
middleware-ops
题目数
30 道
已阅读 0 / 30 题
1 PostgreSQL on Kubernetes 的 Operator 生态总览

答案:

PostgreSQL on Kubernetes 由四款主流 Operator 构成生态,分别代表不同的架构理念与设计哲学。

Operator维护方GitHub Stars核心架构许可证
CloudNativePGEDB3.5k+Kubernetes Native OperatorApache 2.0
StackGresOnGres1.5k+All-in-One 平台AGPL v3
Zalando Postgres OperatorZalando4.5k+Spilo + Patroni + etcdMIT
Crunchy Data PGOCrunchy Data3k+Kubernetes Native OperatorApache 2.0

设计哲学对比:

graph TD
    subgraph CloudNativePG
        A1["纯 Kubernetes 原生设计"]
        A2["无外部依赖(无 Patroni/etcd)"]
        A3["Instance Manager 直接管理 PG"]
        A4["PVC 直接挂载,无 Operator 层"]
    end
    subgraph Zalando
        B1["Spilo 镜像封装 Patroni"]
        B2["依赖 etcd 作为 DCS"]
        B3["成熟的 HA 方案(Patroni)"]
        B4["需要 Operator + ConfigMap"]
    end

选型依据:

场景推荐 Operator
纯 Kubernetes 环境,追求原生体验CloudNativePG
需要完整平台体验(连接池 / 备份 / 监控一体化)StackGres
已有 etcd 基础设施,偏好 Patroni HAZalando
Red Hat OpenShift 环境Crunchy Data PGO
最小外部依赖,快速部署CloudNativePG
2 CloudNativePG 的架构与核心设计理念

答案:

CloudNativePG 以 Kubernetes 原生资源模型管理 PostgreSQL 集群,摒弃传统 DBA 工具链的外部依赖,将 PostgreSQL 生命周期完全融入 Kubernetes 控制循环。

核心架构:

graph TD
    K8sAPI["Kubernetes API Server"]
    K8sAPI -->|"Watch"| Controller["CloudNativePG Controller Manager"]
    Controller --> ClusterCtl["Cluster Controller"]
    Controller --> BackupCtl["Backup Controller"]
    Controller --> ScheduledCtl["ScheduledBackup Controller"]
    Controller -->|"管理"| PGPod["PostgreSQL Pod"]
    PGPod --> IM["Instance Manager"]
    IM --> Lifecycle["Lifecycle Manager"]
    IM --> WAL["WAL Archiver"]
    IM --> BackupMgr["Backup Manager"]
    PGPod --> PGEngine["PostgreSQL 17(Primary/Standby)"]
    PGPod --> PVC["~~~ PVC(PGDATA + WAL)~~~"]

设计理念:

原则说明
No External Dependencies不依赖 Patroni / etcd / Stolon,Operator 直接管理 PostgreSQL 进程
Instance Manager每个 Pod 内运行 sidecar 进程,负责生命周期、WAL 归档、备份
Declarative State通过 Cluster CRD 声明期望状态,Controller 驱动调和
PVC SeparationPGDATA 和 WAL 分别挂载独立 PVC,实现 I/O 隔离
Native Kubernetes RBAC通过 ServiceAccount 管理云存储凭证,不依赖 Secret 硬编码
Immutable Infrastructure配置变更通过 Pod 重建实现,遵循不可变基础设施原则
3 CloudNativePG 的 Cluster CRD 详解

答案:

Cluster CRD 是 CloudNativePG 的核心资源,完整定义 PostgreSQL 集群的拓扑、配置、存储、备份策略。

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: pg-production
spec:
  instances: 3
  imageName: ghcr.io/cloudnative-pg/postgresql:17.5
  primaryUpdateStrategy: unsupervised
  storage:
    size: 100Gi
    storageClass: premium-rwo
  walStorage:
    size: 20Gi
    storageClass: premium-rwo
  postgresql:
    parameters:
      shared_buffers: "4GB"
      max_connections: "500"
      pg_stat_statements.max: "10000"
      log_min_duration_statement: "1s"
  bootstrap:
    initdb:
      database: appdb
      owner: appuser
      secret:
        name: pg-credentials
  monitoring:
    enablePodMonitor: true
  backup:
    barmanObjectStore:
      destinationPath: s3://pg-backups/production
      endpointURL: https://s3.cn-north-1.amazonaws.com.cn
      s3Credentials:
        accessKeyId:
          name: s3-credentials
          key: access_key_id
        secretAccessKey:
          name: s3-credentials
          key: secret_access_key
      wal:
        compression: gzip
        encryption: AES256
      retentionPolicy: "30d"

关键字段说明:

字段说明建议值
instances期望的实例总数生产环境 >= 3
primaryUpdateStrategyPrimary 切换策略unsupervised(推荐)/ supervised
storage.sizePGDATA 卷大小根据数据量预估 + 30% 余量
walStorage.sizeWAL 卷大小max_wal_size * 3 计算
bootstrap初始化数据源initdb / recovery / pg_basebackup
postgresql.parametersPostgreSQL 配置参数映射 postgresql.conf
backup.barmanObjectStore备份目标配置兼容 Barman Cloud 的对象存储
enableSuperuserAccess是否启用 superuser生产环境设为 false
logLevelPostgreSQL 日志级别默认 info,调试用 debug5
affinityPod 亲和性 / 反亲和性强制跨节点 / 跨可用区分布
4 CloudNativePG 的 WAL 归档与 Point-In-Time Recovery

答案:

CloudNativePG 的 Instance Manager 持续将 WAL 段归档到对象存储,支持基于时间点或 WAL 位置的 PITR 恢复。

WAL 归档流程:

sequenceDiagram
    participant PG as PostgreSQL Process
    participant IM as Instance Manager
    participant OS as Object Storage

    PG->>PG: 生成 WAL 段(16MB default)
    PG->>IM: archive_command
    IM->>IM: 压缩 + 加密
    IM->>OS: 上传 WAL 段
    OS-->>IM: 确认写入
    IM-->>PG: 归档成功
    Note over PG,OS: .partial WAL(每 5min 或达到 10MB 时)
    PG->>IM: partial upload
    IM->>OS: 上传 .partial

PITR 恢复配置:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: pg-restored
spec:
  instances: 3
  storage:
    size: 100Gi
  bootstrap:
    recovery:
      source: pg-production-backup-20250801
      recoveryTarget:
        targetTime: "2025-08-01T14:30:00+08:00"
        exclusive: false
  externalClusters:
    - name: pg-production-backup-20250801
      barmanObjectStore:
        destinationPath: s3://pg-backups/production
        endpointURL: https://s3.cn-north-1.amazonaws.com.cn
        s3Credentials:
          accessKeyId:
            name: s3-credentials
            key: access_key_id
          secretAccessKey:
            name: s3-credentials
            key: secret_access_key

WAL 归档关键参数:

参数说明生产建议
wal.compressionWAL 段压缩算法gzip(兼顾速度与比例)
wal.encryptionWAL 段加密算法AES256
wal.maxParallel并发上传线程数4
wal.encryptionPassphrase加密密钥的 Secret 引用独立 Secret
retentionPolicy备份保留策略30d"COUNT 7"
5 CloudNativePG 的 Backup CRD 与 S3/GCS 备份

答案:

CloudNativePG 通过 Backup CRD 和 ScheduledBackup CRD 管理全量备份,底层基于 Barman Cloud 实现,支持 S3 / GCS / Azure Blob Storage。

Backup CRD 定义:

apiVersion: postgresql.cnpg.io/v1
kind: Backup
metadata:
  name: pg-manual-backup-20250801
spec:
  cluster:
    name: pg-production
  method: barmanObjectStore

ScheduledBackup CRD:

apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
  name: pg-daily-backup
spec:
  schedule: "0 2 * * *"
  immediate: true
  suspend: false
  cluster:
    name: pg-production
  backupOwnerReference: self

备份方法对比:

方法原理适用场景恢复方式
barmanObjectStorepg_basebackup 的热备上传到对象存储常规生产备份PITR 恢复(支持时间点)
volumeSnapshot基于 CSI 快照K8s 同集群快速恢复快照克隆(不支持 PITR)
6 CloudNativePG 的自动故障转移与 Leader 选举

答案:

CloudNativePG 不依赖 Patroni 或 etcd,直接在 Operator 层与 Instance Manager 之间协同完成故障检测与 Leader 切换。

故障检测与切换流程:

sequenceDiagram
    participant Op as Operator (Controller)
    participant PM as Instance Manager (Primary Pod)
    participant SB as Standby Pods
    Note over Op,SB: 时间线:T+0s ~ T+50s
    Op->>PM: Liveness Probe 探测 Primary
    PM-->>Op: 无响应
    Note over Op: T+5 确认 Primary 不健康
    Op->>SB: T+10 查询 Standby 复制状态
    SB-->>Op: LSN 位置 + 复制延迟
    Note over Op: T+15 选择 LSN 最超前的 Standby
    Op->>SB: T+20 发起 pg_ctl promote
    Note over SB: Promote
    Note over Op,SB: T+25 更新 Pod Label
role: primary→standby
role: standby→primary Note over Op,SB: T+30 更新 Service Endpoint
-rw → 新 Primary Op->>SB: T+35 其他 Standby 重新连接新 Primary SB-->>PM: streaming repl Note over PM: T+40 旧 Primary 重启为 Standby Note over Op,SB: T+50 集群恢复完整状态

选举策略:

策略说明
Best-Effort 切换选择 LSN 最高、延迟最小的 Standby
同步复制优先级优先选择 synchronous_standby_names 中的 Standby
Failover 限制failoverDelay 控制两次切换的最小间隔
PrimaryUpdateStrategyunsupervised:自动切换;supervised:需手动确认
7 CloudNativePG 的 Read-Only Replica 扩展

答案:

CloudNativePG 基于 PostgreSQL Physical Streaming Replication 实现只读副本,通过 Service 自动路由读写分离流量。

读写分离架构:

graph TD
    subgraph K8s["Kubernetes Service"]
        RW["pg-cluster-rw
(读写 Service)
--> Primary Pod"] RO["pg-cluster-ro
(只读 Service)
--> Standby Pods"] end RW -->|"路由"| Primary["Primary
(Read/Write)"] RO -->|"路由"| Standby["Standby-1 / Standby-2
(Read-Only)"] Primary -->|"Streaming Replication"| Standby

Service 自动生成规则:

Service 名称类型路由目标
<cluster>-rwClusterIPPrimary Pod(标签 role=primary
<cluster>-roClusterIPStandby Pods(标签 role=replica
<cluster>-rClusterIP所有 Pod(Primary + Standby)
<cluster>-anyClusterIP任意 Pod

扩缩容操作:

kubectl patch cluster pg-production \
  --type merge -p '{"spec":{"instances":5}}'

kubectl get cluster pg-production -o jsonpath='{.status.instancesStatus}'
8 CloudNativePG 的 Rolling Update 与在线升级

答案:

CloudNativePG 通过 Rolling Update 策略实现 PostgreSQL 的在线升级,确保更新过程中始终有 Primary 实例接受写入请求。

Rolling Update 流程:

graph LR
    subgraph S1["Step 1: 升级 Standby(C)"]
        PA1["Primary(A)
v16.2"] SB1["Standby(B)
v16.2"] SC1["Standby(C)
v16.4 (升级)"] end subgraph S2["Step 2: 升级 Standby(B)"] PA2["Primary(A)
v16.2"] SB2["Standby(B)
v16.4 (升级)"] SC2["Standby(C)
v16.4"] end subgraph S3["Step 3: Switchover"] SA3["Standby(A)
v16.2 (降级)"] PB3["Primary(B)
v16.4 (提升)"] SC3["Standby(C)
v16.4"] end subgraph S4["Step 4: 升级旧 Primary(A)"] SA4["Standby(A)
v16.4 (升级)"] PB4["Primary(B)
v16.4"] SC4["Standby(C)
v16.4"] end S1 --> S2 --> S3 --> S4

更新触发方式:

spec:
  imageName: ghcr.io/cloudnative-pg/postgresql:17.5

升级类型对比:

升级类型方法说明
小版本(16.2 → 16.4)修改 imageName 自动 Rolling UpdateOperator 自动执行
大版本(15 → 16)pg_upgrade 模式需配置 bootstrap.pg_upgrade
9 CloudNativePG 的 Physical Streaming Replication

答案:

CloudNativePG 基于 PostgreSQL 物理流复制实现主备数据同步,支持异步与同步复制两种模式。

复制架构:

graph LR
    subgraph Primary["Primary Pod"]
        PG1["PostgreSQL Primary"]
        Writer["WAL Writer"]
        Sender1["WAL Sender"]
        Sender2["WAL Sender"]
        PVC1["~~~ WAL PVC ~~~"]
    end
    
    subgraph Standby["Standby Pod"]
        PG2["PostgreSQL Standby"]
        Receiver["WAL Receiver"]
        Applier["WAL Apply"]
        Startup["Startup Process"]
        PVC2["~~~ WAL PVC ~~~"]
    end
    
    Writer -->|"Write"| Sender1
    Writer -->|"Write"| Sender2
    Sender1 -->|"TCP 5432"| Receiver
    Sender2 -->|"TCP 5432"| Applier
    Receiver --> Applier
    Applier --> Startup

同步复制配置:

spec:
  instances: 3
  postgresql:
    parameters:
      synchronous_standby_names: "ANY 1 (*)"
    synchronous:
      numberOfInstances: 1
      enabled: true
10 CloudNativePG 的 PVC 扩展与存储管理

答案:

CloudNativePG 将 PGDATA 和 WAL 分离到独立 PVC,通过 Kubernetes 存储抽象实现动态扩容、快照备份与灾难恢复。

存储架构:

graph TD
    subgraph Pod["PostgreSQL Pod"]
        PGDATA["PGDATA
/var/lib/postgresql/data"] PGWAL["PG_WAL
/var/lib/postgresql/wal"] end PGDATA -->|"目录"| Base["base/ (数据文件)"] PGDATA -->|"符号链接"| WalLink["pg_wal/"] PGDATA -->|"目录"| Stat["pg_stat/ (统计信息)"] PGDATA --> PVC1["PVC: pgdata-cluster-n
StorageClass: premium-rwo"] PGWAL -->|"目录"| Archive["archive_status/"] PGWAL -->|"文件"| WALFiles["*.wal"] PGWAL --> PVC2["PVC: wal-cluster-n
StorageClass: premium-rwo"]

PVC 扩容:

spec:
  storage:
    size: 200Gi
    storageClass: premium-rwo
    resizeInUseVolumes: true

  walStorage:
    size: 50Gi
    storageClass: premium-rwo
11 StackGres 的架构与 All-in-One 理念

答案:

StackGres 是 OnGres 开发的企业级 PostgreSQL 平台 Operator,提供数据库、连接池、备份、监控、日志的一体化方案。

All-in-One 架构:

graph TD
    subgraph Operator["StackGres Operator"]
        SGCluster["SGCluster Controller"]
        SGDistributed["SGDistributed Logs Ctl"]
        SGScript["SGScript Controller"]
    end
    
    Operator -->|"管理"| ClusterPod["StackGres Cluster Pod"]
    
    subgraph ClusterPod["StackGres Cluster Pod"]
        subgraph Patroni["Container: patroni"]
            PGCore["PostgreSQL Engine (custom build)"]
            PatroniHA["Patroni HA Manager"]
            Extensions["内建扩展 (150+ extensions)"]
        end
        
        subgraph Envoy["Container: envoy (Sidecar)"]
            Pool["连接池"]
            Traffic["流量管理"]
        end
        
        subgraph Util["Container: postgres-util"]
            Backup["pgBackRest / WAL-G 备份"]
            Exporter["postgres_exporter"]
            Fluent["fluent-bit (日志采集)"]
        end
        
        PVC["~~~ PVC ~~~"]
    end

核心 CRD 一览:

CRD职责
SGCluster定义 PostgreSQL 集群的拓扑与配置
SGInstanceProfileCPU / 内存资源配置模板
SGPostgresConfigPostgreSQL 参数配置模板
SGPoolingConfigPgBouncer 连接池配置
SGBackupConfig备份策略与保留策略配置
SGDistributedLogs分布式日志采集与查询
SGScriptSQL 脚本管理与执行
SGDbOps数据库运维操作(Vacuum / Repack / Benchmark)
12 StackGres 的 Envoy Sidecar 连接池

答案:

StackGres 在每个 PostgreSQL Pod 中以 Envoy Sidecar 容器提供连接池,实现应用到数据库的透明连接管理,无需额外部署 PgBouncer 实例。

Envoy Sidecar 架构:

graph LR
    subgraph App["Application Pod"]
        App2["Application
jdbc:postgresql://cluster:5432"] end subgraph SGPod["StackGres Cluster Pod"] subgraph Envoy2["Container: envoy"] Filter["PostgreSQL Filter
- 连接池
- 查询路由
- TLS 终止"] end subgraph Patroni2["Container: patroni"] PG2["PostgreSQL
(localhost:5432)"] end Filter -->|"转发"| PG2 end App2 -->|"TCP 5432"| Filter

Envoy 与 PgBouncer 对比:

维度Envoy Sidecar (StackGres)PgBouncer (独立部署)
部署模型Sidecar,与 PG 同 Pod独立 Pod 或 Server
配置管理SGPoolingConfig CRDConfigMap 或配置文件
连接模式Transaction PoolingSession / Transaction / Statement
负载均衡内建支持依赖 Service
TLSEnvoy 原生 TLSPgBouncer 需额外配置
监控Prometheus 指标通过 exporter 暴露
查询路由基于 SQL 前缀路由不直接支持
13 StackGres 的 Babelfish / Patroni / PgBouncer 集成

答案:

StackGres 在基础镜像中预置了 Babelfish(SQL Server 兼容层)、Patroni(HA 管理)和 PgBouncer(连接池),实现开箱即用的企业级功能集成。

Babelfish 集成:

Babelfish 是 AWS 开源的 SQL Server 协议兼容层,使 PostgreSQL 能够接受 TDS 协议连接,运行 SQL Server 的 T-SQL 语法。

apiVersion: stackgres.io/v1
kind: SGCluster
metadata:
  name: pg-babelfish
spec:
  postgres:
    version: "16.2"
    flavor: "babelfish"
  instances: 3

Patroni 集成:

StackGres 使用 Patroni 进行 HA 管理,Patroni 通过 Kubernetes API 作为 DCS(而非 etcd),避免引入外部依赖。

三者协同工作流程:

  1. 连接建立:客户端连接至 PgBouncer 端口,PgBouncer 复用数据库连接至 Patroni 管理的 PostgreSQL 实例。
  2. 故障切换:Patroni 检测 Primary 故障并触发 Leader 选举,PgBouncer 检测到连接断开后查询 Patroni REST API 获取新 Primary 地址并重连。
  3. 读写路由:通过 PgBouncer 配置将读请求路由至 Standby,写请求路由至 Primary(需应用侧配合)。
14 StackGres 的垂直 / 水平扩缩容

答案:

StackGres 通过 SGInstanceProfile 和 SGCluster.instances 分别管理垂直与水平扩缩容,支持在线调整与计划内变更。

垂直扩缩容(CPU / Memory):

apiVersion: stackgres.io/v1
kind: SGInstanceProfile
metadata:
  name: profile-production
spec:
  cpu: "8"
  memory: 32Gi
kubectl patch sginstanceprofile profile-production \
  --type merge -p '{"spec":{"cpu":"16","memory":"64Gi"}}'

水平扩缩容(Instance 数量):

apiVersion: stackgres.io/v1
kind: SGCluster
metadata:
  name: pg-production
spec:
  instances: 5
15 Zalando Postgres Operator 的架构

答案:

Zalando Postgres Operator 由 Zalando 开发维护,基于 Spilo 镜像与 Patroni HA 方案,依赖 etcd 作为分布式协调服务。

整体架构:

graph TD
    K8sAPI["Kubernetes API Server"]
    
    K8sAPI -->|"Watch postgresql CRD"| Operator["Zalando Postgres Operator"]
    
    subgraph Operator["Zalando Postgres Operator"]
        Sync["Sync Controller"]
        Connection["Connection Pooler"]
        Rolling["Rolling Update Manager"]
    end
    
    Operator -->|"创建 StatefulSet / Service / Secret"| SpiloPod["Spilo Pod"]
    
    subgraph SpiloPod["Spilo Pod (PostgreSQL)"]
        subgraph Patroni5["Patroni"]
            HA_Manager["HA Manager"]
            RestAPI3["REST API"]
            CallbackScript["Callback Script"]
        end
        
        subgraph PG["PostgreSQL"]
            PrimaryStandby["Primary / Standby"]
            Basebackup["pg_basebackup"]
            WALArch["WAL-E / WAL-G 归档"]
        end
        
        subgraph Etcd["etcd Cluster"]
            LeaderLock2["Leader 锁"]
            ConfigStore["配置存储"]
            MemberDiscovery["成员发现"]
        end
    end
    
    Patroni5 -->|"DCS Connection"| Etcd

核心组件职责:

组件职责
Operator监听 PostgreSQL CRD,创建/更新/删除 StatefulSet、Service、ConfigMap、Secret
Spilo封装 Patroni + PostgreSQL 的 Docker 镜像,内建备份工具链
PatroniHA 管理器:Leader 选举、自动 Failover、配置管理、REST API
etcd分布式协调后端(DCS),存储集群状态、Leader 锁、配置
WAL-E / WAL-GWAL 归档与备份工具,将 WAL 和 Base Backup 上传至 S3 / GCS

PostgreSQL CRD 示例:

apiVersion: "acid.zalan.do/v1"
kind: postgresql
metadata:
  name: pg-production
spec:
  teamId: "sre"
  numberOfInstances: 3
  postgresql:
    version: "16"
    parameters:
      shared_buffers: "4GB"
      max_connections: "500"
  volume:
    size: 100Gi
    storageClass: premium-rwo
  patroni:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
  resources:
    requests:
      cpu: 4
      memory: 8Gi
    limits:
      cpu: 8
      memory: 16Gi
16 Zalando Operator 的 Spilo 镜像与 Patroni 集成

答案:

Spilo 是 Zalando 维护的 PostgreSQL Docker 镜像,将 Patroni、PostgreSQL 核心、备份工具链、监控 exporter 等打包为一体。

Spilo 镜像分层结构:

graph TD
    subgraph Spilo["Spilo Docker Image"]
        subgraph AppLayer["Application Layer"]
            Patroni6["Patroni (HA Manager)"]
            WALG2["WAL-G (Backup & WAL Archive)"]
            PgBackRest["pgBackRest (可选)"]
            PgExporter["postgres_exporter"]
            PgBouncer2["PgBouncer (可选)"]
            Configure["configure_spilo.py (启动脚本)"]
        end
        
        subgraph EngineLayer["PostgreSQL Engine"]
            PG16["PostgreSQL 12/13/14/15/16/17"]
            Contrib["贡献扩展 (Contrib Extensions)"]
            PL["PL/Python / PL/Perl / PL/Tcl"]
            Plugins2["TimescaleDB / PostGIS / pg_cron"]
        end
        
        subgraph BaseLayer["Base OS Layer"]
            OS["Ubuntu / Debian"]
            Python["Python 3.x"]
        end
    end
    
    AppLayer --> EngineLayer --> BaseLayer

Patroni 启动流程:

flowchart TB
    Start["configure_spilo.py(启动入口)"]
    Start --> S1["1. 检测角色"]
    S1 -->|已有数据目录| Standby["Standby"]
    S1 -->|无数据目录| CheckDCS["检查 DCS 是否有 Leader"]
    CheckDCS -->|有 Leader| Pull["pg_basebackup 拉取数据"]
    CheckDCS -->|无 Leader| Init["initdb 初始化"]
    Pull --> S2["2. 配置 Patroni"]
    Init --> S2
    Standby --> S2
    S2 --> S2A["注入 postgresql 参数"]
    S2 --> S2B["设定 DCS 连接
etcd / Kubernetes / ZooKeeper"] S2 --> S2C["设定 REST API 监听"] S2A --> S3["3. 启动 Patroni"] S2B --> S3 S2C --> S3 S3 --> S4["4. Patroni 守护循环"] S4 --> S4A["每 loop_wait 秒检查 PostgreSQL 健康"] S4 --> S4B["通过 DCS 维护 Leader 锁"] S4 --> S4C["Leader 故障时触发 Failover"]
17 Zalando Operator 的 etcd 作为 DCS

答案:

Zalando Postgres Operator 依赖 etcd 作为分布式一致性存储(DCS),存储集群 Leader 锁、配置和成员信息。

etcd 在 HA 架构中的作用:

graph TD
    subgraph Etcd2["etcd Cluster"]
        Root["/service/scope/"]
        
        Root --> Leader2["leader - Leader 锁(TTL 续约)"]
        Root --> Members["members/ - 成员注册与状态"]
        Root --> Config3["config/ - 集群配置"]
        Root --> Init["initialize - 初始化标记"]
        Root --> History["history - 切换历史"]
        Root --> Optime["optime/ - 最近 Leader 墙钟时间"]
    end

Leader 选举与 Lock 机制:

T+0s   Standby: GET /service/scope/leader → 存在(Primary-0)
T+1s   Primary-0: PUT /service/scope/leader (renew TTL=30s)

--- Primary-0 故障 ---

T+30s  租约过期,Leader Key 自动删除
T+31s  Standby-1: GET /service/scope/leader → 不存在
T+32s  Standby-1: PUT /service/scope/leader (CAS, value=Standby-1)
        → 写入成功 → Standby-1 提升为 Primary
T+33s  Standby-2: PUT /service/scope/leader (CAS)
        → 写入失败(已被 Standby-1 持有)
T+34s  Standby-1: pg_ctl promote → 完成提升

etcd DCS vs Kubernetes DCS(CloudNativePG):

维度etcd DCSKubernetes DCS
额外组件需独立部署 etcd(3~5 节点)无(利用 K8s API)
故障域依赖 etcd 可用性依赖 K8s API Server 可用性
Leader 锁etcd Key TTL + CASConfigMap / Endpoints
配置管理etcd Key/ValueConfigMap / Secret
运维复杂度需管理 etcd 集群无额外运维
适用规模大规模(数百 PG 集群共享 etcd)小到中规模
18 PostgreSQL 在 K8s 上的备份策略

答案:

PostgreSQL on Kubernetes 的备份体系由物理备份、WAL 归档和快照三种方式组成,分别适用于不同恢复目标。

备份工具对比:

工具备份类型存储后端恢复能力Operator 集成
WAL-G物理 + WALS3 / GCS / Azure / Swift / FSPITR(任意时间点)Zalando / StackGres
pgBackRest物理 + WALS3 / GCS / Azure / NFS / POSIXPITR + 增量 / 差异备份CloudNativePG / StackGres(Barman Cloud)
Barman Cloud物理 + WALS3 / GCS / AzurePITR(barmanObjectStore)CloudNativePG 原生支持
pg_basebackup物理全量POSIX / tar / 流全量恢复基础工具
Volume Snapshot块级别快照CSI Snapshot快照点恢复CloudNativePG(VolumeSnapshot)

备份策略金字塔:

graph TD
    L1["异地灾备
跨区域备份
S3/GCS 跨区域复制
每周 1 次 / 保留 3 个月"] L2["快照
Volume Snapshot
每天 1 次 / 保留 7 天"] L3["全量 + WAL
barmanObjectStore / WAL-G
PITR 恢复
每天全量 + 持续 WAL / 保留 30 天"] L1 --> L2 --> L3
19 PostgreSQL 的复制槽(Replication Slot)管理

答案:

Replication Slot 是 PostgreSQL 保证 Standby 不丢失 WAL 的机制,在 Kubernetes 动态环境中需特别关注 WAL 堆积和 Failover 后的槽位处理。

复制槽类型:

类型用途创建方式
Physical SlotStreaming Replicationpg_create_physical_replication_slot()
Logical Slot逻辑复制 / CDCpg_create_logical_replication_slot()
Temporary Slot临时 Base Backuppg_basebackup -S(用完即删)

CloudNativePG 复制槽管理:

spec:
  replicationSlots:
    highAvailability:
      enabled: true
      slotPrefix: _cnpg_
    synchronizeReplicas: true
    updateInterval: 30

Failover 后的 Slot 清理流程:

1. 旧 Primary 故障
2. 新 Primary 提升(Standby 上的 Slot 变为可用)
3. 旧 Primary 恢复为 Standby
4. 新 Primary 创建与新 Standby 对应的 Slot
5. 旧 Primary 上的旧 Slot 通过 synchronizeReplicas: true 自动清理
20 PostgreSQL 的 Vacuum 与 AutoVacuum 在 K8s 下的调优

答案:

Vacuum 是 PostgreSQL MVCC 机制的核心维护操作,在容器化环境需要针对资源限制、I/O 节流和调度策略进行专门调优。

K8s 环境下的特殊考量:

问题原因解决方案
VACUUM 被 OOM Killmaintenance_work_mem 过高 + K8s memory limitmaintenance_work_mem <= memory limit 的 25%
I/O 争抢导致延迟VACUUM 产生大量 I/O,与其他查询竞争降低 cost_limit,提高 cost_delay
长事务阻塞 VACUUM存在未提交事务,VACUUM 无法回收旧版本监控 oldest xminidle_in_transaction_session_timeout = 300s
Insert-Only 表膨胀默认 VACUUM 只由 UPDATE/DELETE 触发PG13+ 设置 autovacuum_vacuum_insert_threshold
容器重启 VACUUM 中断重启后 Autovacuum 重新调度设置 autovacuum_naptime = 30s 缩短调度间隔

OverlayFS 等容器存储驱动可能导致大量 VACUUM FULL 操作性能下降。建议:

  • PGDATA 挂载 PVC 而非容器层,避免 Copy-on-Write 开销
  • 使用 local-ssd 或高性能 CSI 驱动减少 I/O 放大
  • 避免在容器镜像层存储数据库文件
21 PostgreSQL 的 PgBouncer / Odyssey 连接池在 K8s 下的部署

答案:

PostgreSQL 采用进程模型(每连接一个 Backend Process),在微服务和云原生架构中必须引入连接池来缓解连接数压力。

graph TD
    subgraph Apps["Application Pods (100+ instances)"]
        App1["App-1"]
        App2["App-2"]
        App3["App-N"]
    end
    
    Apps -->|"大量短连接"| PgBouncer3["PgBouncer Pod
(Connection Pool)
Sidecar 或独立 Pod"] PgBouncer3 -->|"少量长连接"| PG3["PostgreSQL Pod
max_connections: 200"]

K8s 部署模式对比:

模式优点缺点
Sidecar(与 App 同 Pod)低延迟,无额外网络跳池化收益分散,每 Pod 独立维护连接池
DaemonSet每节点一个,资源开销固定应用需配置 Node IP
独立 Service池化效果好,统一管理额外网络跳,需高可用
StackGres Envoy与 PG Pod Sidecar,零额外运维仅 StackGres 生态
22 PostgreSQL on Kubernetes 的监控与 Prometheus

答案:

PostgreSQL on Kubernetes 通过 postgres_exporter 或 CloudNativePG / StackGres 内建指标暴露,将运行指标接入 Prometheus 体系。

监控架构:

graph TD
    subgraph Stack["Prometheus Stack"]
        Prometheus["Prometheus
(Scrape + TSDB)"] Grafana["Grafana
(Dashboard + Alert)"] Prometheus --> Grafana end Prometheus -->|"Scrape /metrics"| Exporter2["postgres_exporter
:9187/metrics
Sidecar 容器"] Exporter2 -->|"SQL Query"| PG4["PostgreSQL"] subgraph PG4["PostgreSQL"] PgStatStatements["pg_stat_statements"] PgStatActivity["pg_stat_activity"] PgStatReplication["pg_stat_replication"] end

CloudNativePG 原生 Prometheus 集成:

spec:
  monitoring:
    enablePodMonitor: true

关键监控指标:

指标类别关键指标阈值建议
连接pg_stat_activity count> 80% max_connections 告警
复制延迟pg_stat_replication replay_lag> 30s 告警
长事务pg_stat_activity xact_start> 5min 告警
锁等待pg_locks granted=false> 10s 告警
慢查询pg_stat_statements mean_exec_time> 1s 告警
Dead Tuplepg_stat_user_tables n_dead_tup> 10M 或 > 20% 告警
WAL 堆积pg_replication_slots restart_lsn> max_wal_size 告警
磁盘使用cnpg_pgdata_size / PVC> 80% 告警
23 PostgreSQL 的 pgAudit 审计配置

答案:

pgAudit 是 PostgreSQL 的审计扩展,记录 DDL、DML、ROLE 等操作的详细日志,在 K8s 环境中通过 shared_preload_libraries 和 Cluster CRD 参数启用。

CloudNativePG 中的 pgAudit 配置:

spec:
  postgresql:
    parameters:
      shared_preload_libraries: "pg_stat_statements, pgaudit"
      pgaudit.log: "write, ddl, role"
      pgaudit.log_catalog: "off"
      pgaudit.log_level: "log"
      pgaudit.log_parameter: "on"
      pgaudit.log_relation: "on"

审计日志采集架构(K8s 环境):

graph TD
    PA["pgAudit"]
    CSV["csvlog → /var/lib/postgresql/data/pg_log/"]
    PVC["PVC (PGDATA)"]
    Sidecar["Sidecar: fluent-bit / filebeat"]
    Backend["Elasticsearch / Loki / Kafka"]
    PA --> CSV --> PVC
    CSV --> Sidecar --> Backend
24 PostgreSQL on Kubernetes 的逻辑复制与 CDC

答案:

PostgreSQL 逻辑复制(Logical Replication)基于发布 / 订阅模型,以表为单位选择性同步数据变更,是实现 CDC 的核心机制。

CloudNativePG 下的逻辑复制部署:

# 源集群(Publisher)
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: pg-source
spec:
  instances: 3
  postgresql:
    parameters:
      wal_level: "logical"
      max_replication_slots: "10"
      max_wal_senders: "10"

# 目标集群(Subscriber)
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: pg-target
spec:
  instances: 3
  postgresql:
    parameters:
      wal_level: "logical"
      max_replication_slots: "10"
      max_logical_replication_workers: "8"
      max_worker_processes: "16"

物理复制 vs 逻辑复制:

维度Physical ReplicationLogical Replication
复制粒度整个实例(块级别)表级别(行级别)
DDL 同步自动同步不同步
跨版本复制不可跨大版本可跨版本
写入能力Standby 为只读订阅端可写
复制协议WAL StreamingLogical Decoding + WAL Sender
使用场景HA / 读写分离 / 灾备CDC / 数据迁移 / 大版本升级
25 PostgreSQL on Kubernetes 的多租户隔离方案

答案:

PostgreSQL on Kubernetes 提供从数据库级到集群级的多层次多租户隔离方案。

隔离方案对比:

graph TD
    subgraph L0[Level 0: Schema 隔离]
        PG0[PostgreSQL Instance]
        PG0 --> TA[tenant_a]
        PG0 --> TB[tenant_b]
    end
    subgraph L1[Level 1: Database 隔离]
        PG1[PostgreSQL Instance]
        PG1 --> DA[db_tenant_a]
        PG1 --> DB[db_tenant_b]
    end
    subgraph L2[Level 2: Cluster 隔离]
        CA[Cluster A
namespace-A] CB[Cluster B
namespace-B] end subgraph L3[Level 3: Operator / Node 隔离] OA[Operator-A
NodeGroup-A] OB[Operator-B
NodeGroup-B] end L0 --> L1 --> L2 --> L3

CloudNativePG 多租户部署最佳实践:

apiVersion: v1
kind: Namespace
metadata:
  name: tenant-acme-db
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: pg-acme
  namespace: tenant-acme-db
spec:
  instances: 3
  storage:
    size: 50Gi
    storageClass: premium-rwo
  resources:
    requests:
      cpu: "2"
      memory: 4Gi
    limits:
      cpu: "4"
      memory: 8Gi

资源配额与限制策略:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: tenant-acme-quota
  namespace: tenant-acme-db
spec:
  hard:
    requests.cpu: "8"
    requests.memory: 32Gi
    requests.storage: 500Gi
    persistentvolumeclaims: "5"
26 PostgreSQL 的跨可用区 / 跨区域部署

答案:

PostgreSQL on Kubernetes 通过节点亲和性、拓扑分布约束和复制拓扑实现跨可用区(AZ)和跨区域高可用部署。

CloudNativePG 跨 AZ 配置:

spec:
  instances: 3
  topologySpreadConstraints:
    - maxSkew: 1
      topologyKey: topology.kubernetes.io/zone
      whenUnsatisfiable: DoNotSchedule
      labelSelector:
        matchLabels:
          cnpg.io/cluster: pg-production
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
          - matchExpressions:
              - key: node-role.kubernetes.io/database
                operator: Exists
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchLabels:
              cnpg.io/cluster: pg-production
          topologyKey: kubernetes.io/hostname
  postgresql:
    synchronous:
      numberOfInstances: 1

跨区域灾备(DR):

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: pg-dr-region-b
spec:
  instances: 3
  bootstrap:
    recovery:
      source: pg-production-wal-archive
  externalClusters:
    - name: pg-production-wal-archive
      barmanObjectStore:
        destinationPath: s3://pg-dr-backups/production
27 PostgreSQL Operator 对比矩阵

答案:

四款主流 PostgreSQL Operator 在架构、功能、运维复杂度方面存在显著差异。

综合对比矩阵:

维度CloudNativePGStackGresZalandoPGO (Crunchy)
维护方EDBOnGresZalandoCrunchy Data
许可证Apache 2.0AGPL v3MITApache 2.0
外部依赖etcd
HA 方案自研 ManagerPatroniPatroniPatroni
连接池需自行部署Envoy SidecarPgBouncer CRPgBouncer CR
备份方案Barman CloudpgBackRestWAL-GpgBackRest
运维复杂度
K8s 原生程度极高

选型决策树:

是否已有 etcd 基础设施?
  ├── 是 → 考虑 Zalando Operator
  └── 否 →
        是否需要 Babelfish / 150+ Extensions / 一体化平台?
          ├── 是 → 考虑 StackGres
          └── 否 →
                是否使用 Red Hat OpenShift?
                  ├── 是 → 考虑 Crunchy Data PGO
                  └── 否 → 考虑 CloudNativePG(K8s 原生,最小依赖)
28 PostgreSQL 的容器化性能调优

答案:

PostgreSQL 在容器化环境下需要对 shared_buffers、WAL 配置、Huge Pages 和 K8s 资源限制进行协同调优。

关键内存参数调优:

spec:
  postgresql:
    parameters:
      shared_buffers: "4GB"
      effective_cache_size: "12GB"
      work_mem: "64MB"
      maintenance_work_mem: "1GB"
      max_wal_size: "4GB"
      min_wal_size: "1GB"
      wal_buffers: "64MB"
      checkpoint_timeout: "15min"
      checkpoint_completion_target: "0.9"
      random_page_cost: "1.1"

shared_buffers 与 K8s 内存限制的关系:

参数建议计算方式
shared_buffersresource.limits.memory 的 25%,上限 8GB
effective_cache_sizeresource.limits.memory 的 75%
work_mem(limits.memory - shared_buffers) / (max_connections * 2)
maintenance_work_memlimits.memory 的 10%,上限 2GB

K8s 资源限制最佳实践:

资源requestslimits说明
CPU实际平均使用量的 80%实际峰值的 120%避免 CPU Throttle 导致查询延迟毛刺
Memorylimits = requests(Guaranteed QoS)同 requests避免 OOM Kill
Disk IOPS通过 StorageClass 指定OLTP 建议 >= 3000 IOPS
29 PostgreSQL on Kubernetes 的大版本升级

答案:

PostgreSQL 大版本升级(如 15 → 16)在 Kubernetes 环境中有 pg_upgrade、逻辑复制和导入导出三种策略。

三种升级策略对比:

策略停机时间数据完整性复杂度回滚能力
pg_upgrade(原地升级)分钟级(与数据量相关)二进制兼容验证依赖事先备份回滚
逻辑复制(在线迁移)接近零(秒级切换)逐表校验保留旧集群,可随时切回
pg_dump / pg_restore小时级(与数据量相关)数据完整性校验保留导出文件

CloudNativePG pg_upgrade 升级配置:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: pg-v16
spec:
  instances: 3
  imageName: ghcr.io/cloudnative-pg/postgresql:17.5
  bootstrap:
    pg_upgrade:
      sourceCluster:
        name: pg-v15
      import:
        type: snapshot
30 PostgreSQL on Kubernetes 生产环境最佳实践

答案:

生产环境部署 PostgreSQL on Kubernetes 需从高可用、备份、安全、性能、监控五个维度建立完整的运维规范。

一、高可用配置规范:

spec:
  instances: 3
  postgresql:
    synchronous:
      numberOfInstances: 1
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchLabels:
              cnpg.io/cluster: pg-production
          topologyKey: kubernetes.io/hostname
  topologySpreadConstraints:
    - maxSkew: 1
      topologyKey: topology.kubernetes.io/zone
      whenUnsatisfiable: DoNotSchedule

二、备份策略规范:

层级策略保留期存储
WAL 归档(连续)持续推送到 S3与全量备份对齐S3 Standard
全量备份(每日)CronJob triggered Backup30 天S3 Standard
Volume 快照(每 6h)CSI Snapshot7 天K8s 集群内
跨区域复制S3 Cross-Region Replication90 天异地 S3

三、安全加固规范:

spec:
  enableSuperuserAccess: false
  certificates:
    serverTLSSecret: pg-tls-cert
    clientCASecret: pg-client-ca
  postgresql:
    parameters:
      ssl: "on"
      ssl_min_protocol_version: "TLSv1.3"
      password_encryption: "scram-sha-256"
      shared_preload_libraries: "pg_stat_statements, pgaudit"
      pgaudit.log: "write, ddl, role"
      idle_in_transaction_session_timeout: "300s"
      statement_timeout: "30s"
      lock_timeout: "10s"

四、运维操作 SOP:

操作步骤窗口
计划内 Switchoverkubectl cnpg promote <cluster> <standby>业务低峰
扩缩容实例kubectl patch cluster <name> --type merge -p '{"spec":{"instances":5}}'业务低峰
小版本升级修改 imageName,触发 Rolling Update业务低峰
大版本升级pg_upgrade 模式,事先在测试集群验证维护窗口
存储扩容修改 storage.size,CSI 在线扩容无需停服
PITR 恢复从备份恢复到新集群,验证后切换应用紧急窗口

五、禁止事项:

  • 禁止在 PostgreSQL Pod 中执行 kill -9 终止 Postgres 进程
  • 禁止在生产环境直接修改 Pod 内的 postgresql.conf,应通过 Cluster CRD postgresql.parameters 统一管理
  • 禁止在没有备份验证的情况下执行 pg_upgrade
  • 禁止 VACUUM FULL 在生产高峰期执行
  • 禁止在生产环境使用 fsync=off
  • 禁止在未配置 idle_in_transaction_session_timeout 的情况下运行长连接应用