Workstation Logo
ผลิตภัณฑ์
AI LabsOpenAI AgentsClaude AgentsGrok BotWorkstation CRM (WSL CRM)การตลาดผลิตภัณฑ์ทั้งหมด
โซลูชัน AI
เวิร์กสเตชัน AIAI SME PackagesAI ส่วนตัวคลัสเตอร์ GPUEdge AIแล็บ AI องค์กรAI ตามอุตสาหกรรม
บริการ
Platform ModernisationDigital EngineeringData Foundations & AIAutonomous Operationsที่ปรึกษา AIระบบอัตโนมัติ DevOpsความมั่นคงปลอดภัยไซเบอร์การพัฒนาซอฟต์แวร์การสร้างเอเจนต์การตั้งค่า MLOps
เกี่ยวกับเรา
พาร์ทเนอร์เรื่องราวลูกค้า
บทความ
เอกสาร
WSL ProxyRing PromoterWSL VaultJobshoutSysOps 24/7
บล็อก
ติดต่อเราLogin
Workstation

เวิร์กสเตชัน AI ซอฟต์แวร์มัลติเอเจนต์ AI โครงสร้างพื้นฐาน GPU และโซลูชันเอเจนต์อัจฉริยะสำหรับธุรกิจยุคใหม่

ติดต่อเรา

โซลูชัน AI

เวิร์กสเตชัน AIAI SME PackagesAI ส่วนตัวคลัสเตอร์ GPUEdge AIแล็บ AI องค์กรAI ตามอุตสาหกรรม

ผลิตภัณฑ์

ผลิตภัณฑ์ทั้งหมดWSL CRM และ ERPการตลาดOpenAI AgentsWSL ProxyRing PromoterWSL VaultJobshoutSysOps 24/7

บริษัท

เกี่ยวกับเราทำไมต้อง Workstationพาร์ทเนอร์เรื่องราวลูกค้าราคาติดต่อ

แหล่งข้อมูล

บทความเอกสารประกอบบล็อกค้นหาแผนผังเว็บไซต์
สำนักงานสหราชอาณาจักร
77-79 Marlowes, Hemel Hempstead HP1 1LFเส้นทาง - ออกทางแยกที่ 20 จาก M25 Outer Londonเลขทะเบียนบริษัท: 11641870จ. - ศ.: 9:00 - 18:00 น. GMT
+44 7515 356 146
สำนักงานเบลเยียม
Workstation SRL, Rue Vanderkindere 34, 1180 Uccle, BrusselsBE 0751.518.683จ. - ศ.: 9:00 - 18:00 น. CET
+32 492 45 67 46
สำนักงานอินเดีย
#159 Sector 9, Pocket 1, DDA Flats, 110077 Dwarka, New Delhi
+91 98881 98841

© 2026 Workstation AI สงวนลิขสิทธิ์

ความเป็นส่วนตัวคุกกี้ข้อกำหนดการให้บริการแผนผังเว็บไซต์

Loading blog...

Home / Blog
DatabaseKubernetesDevOpsBackend

PostgreSQL ความพร้อมใช้งานสูงพร้อมข้อมูลที่กรุบกรอบ PGO: การปรับใช้ Kubernetes ระดับองค์กร

PostgreSQL HA ระดับองค์กรพร้อม Crunchy Data PGO บน Kubernetes

Balinder Walia12 เมษายน 256917 min read

การรัน PostgreSQL ในการใช้งานจริงบน Kubernetes ต้องการมากกว่า StatefulSet ที่มีวอลุ่มถาวร คุณต้องมีการเปลี่ยนระบบอัตโนมัติ การสำรองข้อมูลอย่างต่อเนื่องและการกู้คืนแบบช่วงเวลา การรวมการเชื่อมต่อ การเข้ารหัส TLS การตรวจสอบ และความสามารถในการปรับใช้อย่างสม่ำเสมอระหว่างผู้ให้บริการระบบคลาวด์และ Bare Metal Crunchy Data PGO (Postgres Operator) v5 มอบทั้งหมดนี้ผ่านทรัพยากรแบบกำหนดเอง Kubernetes เดียว —PostgresClusterCRD — ซึ่งได้รับการสนับสนุนโดยส่วนประกอบที่ผ่านการทดสอบการต่อสู้: Patroni สำหรับ HA ตามฉันทามติ, pgBackRest สำหรับการสำรองข้อมูลระดับองค์กร, PgBouncer สำหรับการรวมการเชื่อมต่อ และ pgMonitor สำหรับความสามารถในการสังเกตที่เข้ากันได้กับ Prometheus

คู่มือนี้ครอบคลุมทุกสิ่งที่จำเป็นในการใช้คลัสเตอร์ PostgreSQL ที่จัดการโดย PGO ตั้งแต่การใช้งานครั้งแรกไปจนถึงการดำเนินการระดับการผลิตทั่วทั้ง AWS EKS, Azure AKS, GCP GKE และ Bare Metal k3s พร้อม Rancher ทุกส่วนประกอบด้วยค่า YAML, Helm ที่เป็นรูปธรรม และขั้นตอนการปฏิบัติงานที่คุณสามารถปรับให้เข้ากับสภาพแวดล้อมของคุณได้

ข้อมูลกรุบกรอบสถาปัตยกรรม PGO v5

PGO v5 เป็นการเขียนใหม่ของ Crunchy Postgres Operator โดยแทนที่ pgcluster/pgreplica/pgpolicy CRDs ก่อนหน้าด้วยทรัพยากรPostgresClusterเดียวที่อธิบายทุกแง่มุมของการปรับใช้ PostgreSQL อย่างเปิดเผย ผู้ปฏิบัติงานจะคอยดูการเปลี่ยนแปลงในทรัพยากรนี้และปรับสมดุลออบเจ็กต์ Kubernetes ที่เกี่ยวข้อง — StatefulSets, Services, ConfigMaps, Secrets, Jobs — เพื่อให้ตรงกับสถานะที่ต้องการ

สถาปัตยกรรมถูกสร้างขึ้นบนเสาสี่เสาPatroniทำงานเป็นรถเทียมข้างรถจักรยานยนต์ในพ็อด PostgreSQL ทุกตัว และจัดการการเลือกผู้นำ โทโพโลยีการจำลอง และเฟลโอเวอร์อัตโนมัติโดยใช้ฉันทามติแบบกระจาย Kubernetes ดั้งเดิมpgBackRestจัดการการสำรองข้อมูลเต็มรูปแบบ ส่วนต่าง และการสำรองข้อมูลส่วนเพิ่ม รวมถึงการเก็บถาวร WAL อย่างต่อเนื่องไปยังพื้นที่จัดเก็บอ็อบเจ็กต์ (S3, GCS, Azure Blob) หรือ PVC ภายในเครื่องPgBouncerมอบการรวมการเชื่อมต่อน้ำหนักเบาที่ป้องกัน PostgreSQL จากพายุการเชื่อมต่อpgMonitorเปิดเผยตัววัด PostgreSQL ผ่านตัวช่วยส่งออก Prometheus เพื่อบูรณาการกับสแต็กความสามารถในการสังเกตที่มีอยู่ของคุณ

สถาปัตยกรรม PGO ข้อมูลกรุบกรอบPGO โอเปอเรเตอร์ PodPostgresคลัสเตอร์ CRDอินสแตนซ์หลักStatefulSet (1 พ็อด)ผู้นำอุปถัมภ์ผู้ส่งออก pgMonitorอินสแตนซ์จำลองStatefulSet (N พ็อด)Patroni แบบจำลองการจำลองแบบสตรีมมิ่งpgBackRest RepoS3 / GCS / Azure หยดเต็ม + ส่วนต่าง + รวมWAL เอกสารเก่าวอลPgBouncer Poolerการปรับใช้(2+ พ็อด)Prometheus + GrafanapgMonitor เมตริกพ็อดแอปพลิเคชันเชื่อมต่อผ่าน PgBouncerหลักแบบจำลองสำรองพูลเลอร์การตรวจสอบ

ตัวดำเนินการเองไม่มีสถานะ — สถานะถาวรทั้งหมดอยู่ในคลัสเตอร์ PostgreSQL และที่เก็บข้อมูลสำรอง ซึ่งหมายความว่าคุณสามารถอัปเกรดหรือรีสตาร์ทตัวดำเนินการได้โดยไม่กระทบต่อฐานข้อมูลที่ทำงานอยู่ ลูปการกระทบยอดตัวดำเนินการเป็นแบบ idempotent: การใช้ข้อมูลจำเพาะPostgresClusterเดียวกันหลายครั้งจะสร้างอ็อบเจ็กต์ Kubernetes ชุดเดียวกัน

กำลังติดตั้ง PGO v5

PGO v5 สามารถติดตั้งผ่าน Helm หรือรายการ kubectl โดยตรง แนวทาง Helm เป็นที่ต้องการสำหรับการผลิต เนื่องจากผสานรวมกับเวิร์กโฟลว์ GitOps ได้อย่างสมบูรณ์ และให้การอัปเกรดที่ควบคุมเวอร์ชัน

# Add the Crunchy Data Helm repository
helm repo add crunchydata https://charts.crunchydata.com
helm repo update

# Install PGO into its own namespace
helm install pgo crunchydata/pgo \
  --namespace postgres-operator \
  --create-namespace \
  --set controllerImages.cluster=registry.crunchydata.com/crunchydata/postgres-operator:ubi8-5.7.2-0 \
  --set relatedImages.postgres_16=registry.crunchydata.com/crunchydata/crunchy-postgres:ubi8-16.6-1 \
  --set relatedImages.pgbackrest=registry.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.54.1-0 \
  --set relatedImages.pgbouncer=registry.crunchydata.com/crunchydata/crunchy-pgbouncer:ubi8-1.23.1-0 \
  --set relatedImages.pgexporter=registry.crunchydata.com/crunchydata/crunchy-postgres-exporter:ubi8-0.16.0-0

สำหรับสภาพแวดล้อมที่มีช่องว่างอากาศ ให้มิเรอร์อิมเมจที่ต้องการไปยังรีจิสตรีภายในของคุณ และอัปเดตค่าrelatedImagesตามนั้น PGO จะดึงเฉพาะรูปภาพที่ระบุในค่า Helm หรือข้อมูลจำเพาะPostgresClusterเท่านั้น โดยจะไม่เข้าถึงรีจิสทรีภายนอกขณะรันไทม์ เว้นแต่จะได้รับการกำหนดค่าอย่างชัดเจนให้ทำเช่นนั้น

# Verify the operator is running
kubectl get pods -n postgres-operator
NAME                                READY   STATUS    RESTARTS   AGE
pgo-controller-manager-7d8f9b6c4-xk2pt   1/1     Running   0          45s

Postgresคลัสเตอร์ CRD ข้อมูลจำเพาะ

PostgresClusterCRD เป็นพื้นผิวการประกาศเดียวสำหรับการปรับใช้ PostgreSQL ทั้งหมดของคุณ ด้านล่างนี้คือข้อกำหนดเฉพาะที่พร้อมสำหรับการผลิตซึ่งสาธิตส่วนสำคัญๆ แต่ละส่วนจะมีการกล่าวถึงโดยละเอียดในส่วนต่อๆ ไปของคู่มือนี้

apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
  name: production-db
  namespace: databases
spec:
  postgresVersion: 16
  image: registry.crunchydata.com/crunchydata/crunchy-postgres:ubi8-16.6-1

  instances:
    - name: pgha1
      replicas: 3
      resources:
        requests:
          cpu: "2"
          memory: 8Gi
        limits:
          cpu: "4"
          memory: 16Gi
      dataVolumeClaimSpec:
        storageClassName: gp3-csi
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 100Gi
      walVolumeClaimSpec:
        storageClassName: gp3-csi
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 20Gi
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - topologyKey: kubernetes.io/hostname
              labelSelector:
                matchLabels:
                  postgres-operator.crunchydata.com/cluster: production-db
      tolerations:
        - key: "workload"
          operator: "Equal"
          value: "database"
          effect: "NoSchedule"

  backups:
    pgbackrest:
      image: registry.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.54.1-0
      configuration:
        - secret:
            name: pgbackrest-s3-creds
      global:
        repo1-retention-full: "7"
        repo1-retention-diff: "14"
        repo1-path: /pgbackrest/production-db/repo1
        repo1-s3-uri-style: path
      repos:
        - name: repo1
          schedules:
            full: "0 2 * * 0"         # Sunday 2am
            differential: "0 2 * * 1-6" # Mon-Sat 2am
            incremental: "0 */4 * * *"  # Every 4 hours
          s3:
            bucket: mycompany-pg-backups
            endpoint: s3.eu-west-1.amazonaws.com
            region: eu-west-1

  proxy:
    pgBouncer:
      image: registry.crunchydata.com/crunchydata/crunchy-pgbouncer:ubi8-1.23.1-0
      replicas: 2
      resources:
        requests:
          cpu: 500m
          memory: 256Mi
        limits:
          cpu: "1"
          memory: 512Mi
      config:
        global:
          pool_mode: transaction
          max_client_conn: "1000"
          default_pool_size: "25"
          min_pool_size: "5"
          reserve_pool_size: "5"
          reserve_pool_timeout: "3"

  monitoring:
    pgmonitor:
      exporter:
        image: registry.crunchydata.com/crunchydata/crunchy-postgres-exporter:ubi8-0.16.0-0
        resources:
          requests:
            cpu: 100m
            memory: 128Mi

  patroni:
    dynamicConfiguration:
      synchronous_mode: true
      postgresql:
        parameters:
          shared_buffers: 2GB
          effective_cache_size: 6GB
          work_mem: 32MB
          maintenance_work_mem: 512MB
          max_connections: 200
          wal_buffers: 64MB
          checkpoint_completion_target: 0.9
          random_page_cost: 1.1
          effective_io_concurrency: 200
          min_wal_size: 1GB
          max_wal_size: 4GB
          max_worker_processes: 8
          max_parallel_workers_per_gather: 4
          max_parallel_workers: 8
          log_min_duration_statement: 500
          log_checkpoints: "on"
          log_connections: "on"
          log_disconnections: "on"
          log_lock_waits: "on"

  users:
    - name: appuser
      databases: ["appdb"]
      options: "NOSUPERUSER"
    - name: readonly
      databases: ["appdb"]
      options: "NOSUPERUSER"

  databaseInitSQL:
    name: init-sql-configmap
    key: init.sql

ข้อมูลจำเพาะนี้สร้างคลัสเตอร์ PostgreSQL 16 สามอินสแตนซ์ที่มีข้อมูลและวอลุ่ม WAL แยกกัน, การสำรองข้อมูล S3 ที่สำรองไว้ตามกำหนดเวลาแบบเต็ม/ส่วนต่าง/ส่วนเพิ่ม, การรวมการเชื่อมต่อ PgBouncer ในโหมดธุรกรรม, การส่งออกตัววัด Prometheus และการจำลองแบบซิงโครนัส Patroni กฎการต่อต้านความสัมพันธ์ของพ็อดช่วยให้แน่ใจว่าทั้งสามอินสแตนซ์ลงจอดบนโหนด Kubernetes ที่แตกต่างกัน

Patroni-Based HA และเฟลโอเวอร์อัตโนมัติ

Patroni เป็นเฟรมเวิร์ก HA ที่ฝังอยู่ในพ็อด PostgreSQL ที่จัดการโดย PGO ทุกตัว โดยจะใช้ Kubernetes API เป็นที่จัดเก็บการกำหนดค่าแบบกระจาย (DCS) — ไม่จำเป็นต้องใช้ etcd หรือคลัสเตอร์ ZooKeeper แยกต่างหาก Patroni ตรวจสอบความสมบูรณ์ของ PostgreSQL หลักและแบบจำลองอย่างต่อเนื่อง เมื่อตัวจำลองหลักไม่ตอบสนอง Patroni จะเริ่มเฟลโอเวอร์โดยอัตโนมัติ โดยจะเลื่อนระดับตัวจำลองที่เป็นปัจจุบันที่สุดไปเป็นตัวจำลองหลัก และกำหนดค่าตัวจำลองที่เหลืออีกครั้งเพื่อติดตามผู้นำคนใหม่

กระบวนการเฟลโอเวอร์ใน PGO ทำงานดังนี้ Patroni บนแต่ละพ็อดมีการล็อคผู้นำใน Kubernetes (ผ่านจุดสิ้นสุดหรือออบเจ็กต์ ConfigMap) หลักปัจจุบันจะต้องต่ออายุการล็อคนี้ในช่วงเวลาที่กำหนดได้ (ค่าเริ่มต้น 10 วินาที TTL, รอ 3 วินาทีวนซ้ำ) หากตัวหลักล้มเหลวในการต่ออายุ — เนื่องจากมันขัดข้อง โหนดหยุดทำงาน หรือเครือข่ายถูกแบ่งพาร์ติชัน — แบบจำลองที่ใกล้กับตำแหน่ง WAL ของตัวหลักมากที่สุดจะได้รับการล็อคและเลื่อนระดับตัวเอง โดยทั่วไปกระบวนการทั้งหมดจะเสร็จสิ้นภายใน 10 ถึง 30 วินาที

โหมดการจำลองแบบซิงโครนัส

ซึ่งเปิดใช้งานผ่านsynchronous_mode: trueในการกำหนดค่า Patroni รับประกันการสูญเสียข้อมูลเป็นศูนย์ (RPO = 0) โดยมีต้นทุนของเวลาแฝงในการเขียนที่สูงขึ้นเล็กน้อย ในโหมดซิงโครนัส ธุรกรรมจะไม่ได้รับการยอมรับจากไคลเอนต์จนกว่าแบบจำลองอย่างน้อยหนึ่งรายการจะยืนยันการรับ WAL หากไม่มีการจำลองแบบซิงโครนัส Patroni จะปิดใช้งานโหมดซิงโครนัสชั่วคราวเพื่อรักษาความพร้อมใช้งาน คุณสามารถแทนที่สิ่งนี้ด้วยsynchronous_mode_strict: trueหากคุณต้องการเสียสละความพร้อมใช้งานเพื่อความสอดคล้อง

# Check Patroni cluster status
kubectl exec -it production-db-pgha1-0 -n databases -- patronictl list

+----------------------------+-------------------+---------+---------+----+-----------+
| Member                     | Host              | Role    | State   | TL | Lag in MB |
+----------------------------+-------------------+---------+---------+----+-----------+
| production-db-pgha1-0      | 10.244.0.15       | Leader  | running |  3 |           |
| production-db-pgha1-1      | 10.244.1.22       | Replica | running |  3 |         0 |
| production-db-pgha1-2      | 10.244.2.18       | Replica | running |  3 |         0 |
+----------------------------+-------------------+---------+---------+----+-----------+

# Manual switchover (planned, zero downtime)
kubectl exec -it production-db-pgha1-0 -n databases -- \
  patronictl switchover --master production-db-pgha1-0 --candidate production-db-pgha1-1 --force

# Manual failover (forced, for emergencies)
kubectl exec -it production-db-pgha1-1 -n databases -- \
  patronictl failover --candidate production-db-pgha1-1 --force

PGO กำหนดค่าบริการ Kubernetes โดยอัตโนมัติเพื่อติดตามผู้นำ Patroni บริการproduction-db-primaryจะชี้ไปที่พ็อดใดก็ตามที่มีการล็อคผู้นำอยู่ตลอดเวลา ดังนั้นแอปพลิเคชันที่เชื่อมต่อผ่านบริการนี้จะพบกับการเฟลโอเวอร์ที่ราบรื่นด้วยการรีเซ็ตการเชื่อมต่อเพียงช่วงสั้นๆ เท่านั้น

pgBackRest สำรองและกู้คืน

pgBackRest คือกลไกสำรองข้อมูลที่รวมอยู่ใน PGO รองรับการสำรองข้อมูลสามประเภท — เต็ม, ส่วนต่าง และส่วนเพิ่ม — บวกกับการเก็บถาวร WAL อย่างต่อเนื่องสำหรับการกู้คืนช่วงเวลา (PITR) การทำความเข้าใจว่าสิ่งเหล่านี้เข้ากันได้อย่างไรเป็นสิ่งสำคัญสำหรับการออกแบบกลยุทธ์การสำรองข้อมูลที่สร้างสมดุลระหว่างต้นทุนการจัดเก็บข้อมูล ความเร็วการสำรองข้อมูล และเวลาในการกู้คืน

สถาปัตยกรรมการสำรองข้อมูล pgBackRestPostgreSQL หลักไฟล์ข้อมูล (PGDATA)เซ็กเมนต์ WALpg_wal/ ไดเร็กทอรีเอเจนต์ pgBackRestไฟล์เก็บถาวร WAL ต่อเนื่องการสำรองข้อมูลตามกำหนดเวลาพื้นที่เก็บข้อมูล pgBackRestS3 / GCS / Azure หยด / PVCการสำรองข้อมูลแบบเต็มคัดลอกให้สมบูรณ์ดิฟเฟอเรนเชียลตั้งแต่เต็มรูปแบบครั้งล่าสุดส่วนเพิ่ม (ตั้งแต่ครั้งล่าสุด)WAL เอกสารเก่า000000030000000A000000030000000B000000030000000C... ต่อเนื่อง ...เปิดใช้งาน PITRไทม์ไลน์การกู้คืนช่วงเวลาเต็มอา. ตี 2ส่วนต่างส่วนต่างส่วนต่างส่วนต่างส่วนต่างเต็มอา. ตี 2สตรีม WAL ต่อเนื่อง →PITR เป้าหมายคืนค่าไปยังจุดใดก็ได้ในเวลาการสำรองข้อมูลแบบเต็มดิฟเฟอเรนเชียลWAL สตรีมเป้าหมายการกู้คืน

การสำรองข้อมูลเต็มรูปแบบจะคัดลอกไดเร็กทอรีข้อมูล PostgreSQL ทั้งหมดและเป็นข้อมูลพื้นฐานสำหรับการสำรองข้อมูลประเภทอื่นๆ ทั้งหมด การสำรองข้อมูลส่วนต่างจะคัดลอกเฉพาะหน้าที่เปลี่ยนแปลงตั้งแต่การสำรองข้อมูลเต็มรูปแบบครั้งล่าสุด การสำรองข้อมูลส่วนเพิ่มจะคัดลอกเฉพาะหน้าที่เปลี่ยนแปลงตั้งแต่การสำรองข้อมูลครั้งล่าสุดทุกประเภท ในระหว่างการกู้คืน pgBackRest จะเชื่อมโยงการสำรองข้อมูลที่จำเป็นเข้าด้วยกันโดยอัตโนมัติ ตัวอย่างเช่น การกู้คืนจากส่วนเพิ่มต้องใช้ส่วนเพิ่มบวกส่วนต่างก่อนหน้า (หรือทั้งหมด) บวกกับการสำรองข้อมูลทั้งหมด รวมถึงส่วน WAL ใด ๆ ที่จำเป็นในการไปถึงจุดการกู้คืนเป้าหมาย

การกำหนดค่ากำหนดการสำรอง

กำหนดการสำรองข้อมูลถูกกำหนดไว้ในส่วนreposของการกำหนดค่า pgBackRest ภายในข้อกำหนดPostgresClusterโดยปกติแล้ว ตารางการผลิตที่มั่นคงจะดำเนินการสำรองข้อมูลส่วนเพิ่มรายสัปดาห์แบบเต็มรายสัปดาห์ และสำรองข้อมูลส่วนเพิ่มบ่อยขึ้น

backups:
  pgbackrest:
    global:
      repo1-retention-full: "4"        # Keep 4 full backups
      repo1-retention-full-type: count
      repo1-retention-diff: "14"       # Keep 14 differentials
    repos:
      - name: repo1
        schedules:
          full: "0 2 * * 0"            # Weekly full: Sunday 2am
          differential: "0 2 * * 1-6"  # Daily diff: Mon-Sat 2am
          incremental: "0 */6 * * *"   # Every 6 hours
        s3:
          bucket: mycompany-pg-backups
          endpoint: s3.eu-west-1.amazonaws.com
          region: eu-west-1

สำรองและกู้คืน

ด้วยตนเอง
# Trigger a manual full backup
kubectl annotate postgrescluster production-db -n databases \
  postgres-operator.crunchydata.com/pgbackrest-backup="$(date +%s)" \
  --overwrite

# Check backup status
kubectl exec -it production-db-pgha1-0 -n databases -- \
  pgbackrest info --stanza=db

# Restore to a specific point in time
# First, update the PostgresCluster spec:
spec:
  backups:
    pgbackrest:
      restore:
        enabled: true
        repoName: repo1
        options:
          - --type=time
          - --target="2026-04-12 08:30:00+00"
          - --target-action=promote

# Apply the restore annotation
kubectl annotate postgrescluster production-db -n databases \
  postgres-operator.crunchydata.com/pgbackrest-restore="$(date +%s)" \
  --overwrite

ในระหว่างการกู้คืน PITR PGO จะปิดอินสแตนซ์ PostgreSQL ทั้งหมด กู้คืนจากการสำรองข้อมูลเต็มรูปแบบหรือส่วนต่างที่ใกล้ที่สุด เล่นซ้ำส่วน WAL จนถึงเวลาเป้าหมาย จากนั้นเริ่มคลัสเตอร์ การดำเนินการทั้งหมดได้รับการควบคุมโดยผู้ปฏิบัติงาน โดยไม่จำเป็นต้องใช้คนควบคุมพ็อดแต่ละตัว

การรวมการเชื่อมต่อ PgBouncer

PostgreSQL สร้างกระบวนการใหม่สำหรับการเชื่อมต่อไคลเอ็นต์ทุกครั้ง ในขนาด — พ็อดแอปพลิเคชันนับร้อยหรือหลายพันตัวที่แต่ละพ็อดรักษาพูลการเชื่อมต่อ — โมเดลนี้พังทลายลง PgBouncer อยู่ระหว่างแอปพลิเคชันของคุณกับ PostgreSQL ซึ่งเป็นการมัลติเพล็กซ์การเชื่อมต่อไคลเอนต์จำนวนมากผ่านการเชื่อมต่อเซิร์ฟเวอร์จำนวนน้อยกว่า

PGO ปรับใช้ PgBouncer เป็นการปรับใช้แยกต่างหากด้วยบริการของตัวเอง บริการproduction-db-pgbouncerคือสิ่งที่แอปพลิเคชันของคุณควรเชื่อมต่อ ไม่ใช่บริการหลัก PostgreSQL โดยตรง PgBouncer รองรับโหมดพูลสามโหมด:

  • การรวมเซสชัน— การเชื่อมต่อเซิร์ฟเวอร์ถูกกำหนดให้กับไคลเอนต์ตลอดอายุการใช้งานของการเชื่อมต่อไคลเอนต์ ปลอดภัยที่สุด แต่มีประสิทธิภาพน้อยที่สุด
  • การรวมธุรกรรม— การเชื่อมต่อเซิร์ฟเวอร์ถูกกำหนดไว้ในช่วงระยะเวลาของธุรกรรมเท่านั้น มีประสิทธิภาพสูงสุดสำหรับปริมาณงานบนเว็บ นี่เป็นค่าเริ่มต้นที่แนะนำ
  • การรวมคำสั่ง— การเชื่อมต่อเซิร์ฟเวอร์ถูกกำหนดไว้สำหรับคำสั่งเดียว ใช้งานได้เฉพาะกับปริมาณงานธรรมดาที่ไม่ใช่ธุรกรรมเท่านั้น
proxy:
  pgBouncer:
    replicas: 3
    config:
      global:
        pool_mode: transaction
        max_client_conn: "2000"
        default_pool_size: "30"
        min_pool_size: "10"
        reserve_pool_size: "10"
        reserve_pool_timeout: "3"
        server_idle_timeout: "300"
        server_lifetime: "3600"
        client_idle_timeout: "600"
        tcp_keepalive: "1"
        tcp_keepidle: "30"
        tcp_keepintvl: "10"
        tcp_keepcnt: "3"
    affinity:
      podAntiAffinity:
        preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              topologyKey: kubernetes.io/hostname
              labelSelector:
                matchLabels:
                  postgres-operator.crunchydata.com/role: pgbouncer

โปรดทราบการตั้งค่าtcp_keepalive— สิ่งเหล่านี้มีความสำคัญเมื่อ PgBouncer ทำงานอยู่เบื้องหลังโหลดบาลานเซอร์บนคลาวด์หรือบริการ Kubernetes หากไม่มี Keepalive ที่ก้าวร้าว การเชื่อมต่อที่ไม่ได้ใช้งานอาจถูกละทิ้งโดยส่วนประกอบเครือข่ายระดับกลาง ทำให้เกิดข้อผิดพลาดของแอปพลิเคชันในการพยายามสืบค้นครั้งถัดไป

pgMonitor และ Prometheus/Grafana การตรวจสอบ

การผสานรวมการตรวจสอบของ

PGO ใช้งานรถเทียมข้างรถจักรยานยนต์crunchy-postgres-exporterในพ็อด PostgreSQL ทุกตัว ผู้ส่งออกรายนี้ขูดมุมมองสถิติภายในของ PostgreSQL และเปิดเผยเป็นตัวชี้วัด Prometheus บนพอร์ต 9187 ผู้ส่งออกครอบคลุมตัวชี้วัดมากกว่า 150 รายการตั้งแต่แกะกล่อง รวมถึงการเชื่อมต่อ ความล่าช้าในการจำลอง อัตราการทำธุรกรรม อัตราส่วนการเข้าถึงแคช สถิติของตารางและดัชนี การช่วงชิงการล็อค และอัตราการสร้าง WAL

# ServiceMonitor for Prometheus Operator auto-discovery
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: postgres-monitoring
  namespace: databases
  labels:
    release: kube-prometheus-stack
spec:
  selector:
    matchLabels:
      postgres-operator.crunchydata.com/cluster: production-db
      postgres-operator.crunchydata.com/crunchy-postgres-exporter: "true"
  endpoints:
    - port: exporter
      interval: 15s
      scrapeTimeout: 10s

Crunchy Data มอบชุดแดชบอร์ด Grafana ที่สร้างไว้ล่วงหน้าซึ่งคุณสามารถนำเข้าได้โดยตรง สิ่งเหล่านี้ครอบคลุมภาพรวม PostgreSQL สถานะการจำลอง สถานะการสำรองข้อมูล pgBackRest สถิติ PgBouncer และการใช้ทรัพยากรระดับพ็อด นำเข้าผ่านการจัดเตรียมแดชบอร์ดของ Grafana หรือด้วยตนเองจากที่เก็บข้อมูลตัวอย่าง Crunchy Data

# Install Grafana dashboards as ConfigMaps
kubectl create configmap grafana-pg-overview \
  --from-file=pg-overview.json=dashboards/pg-overview.json \
  -n monitoring
kubectl label configmap grafana-pg-overview grafana_dashboard=1 -n monitoring

กฎการแจ้งเตือนที่สำคัญสำหรับ PostgreSQL

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: postgres-alerts
  namespace: databases
  labels:
    release: kube-prometheus-stack
spec:
  groups:
    - name: postgresql-health
      rules:
        - alert: PostgresReplicationLagHigh
          expr: ccp_replication_lag_size_bytes > 104857600
          for: 5m
          labels:
            severity: warning
          annotations:
            summary: "Replica {{ $labels.pod }} lag exceeds 100MB"

        - alert: PostgresConnectionsExhausted
          expr: ccp_connection_stats_active / ccp_connection_stats_max_connections > 0.85
          for: 2m
          labels:
            severity: critical
          annotations:
            summary: "PostgreSQL connections above 85% capacity"

        - alert: PostgresDeadlockDetected
          expr: rate(ccp_stat_database_deadlocks[5m]) > 0
          for: 1m
          labels:
            severity: warning
          annotations:
            summary: "Deadlocks detected in {{ $labels.datname }}"

        - alert: PostgresCacheHitRatioLow
          expr: ccp_stat_database_blks_hit / (ccp_stat_database_blks_hit + ccp_stat_database_blks_read) < 0.95
          for: 10m
          labels:
            severity: warning
          annotations:
            summary: "Cache hit ratio below 95% for {{ $labels.datname }}"

        - alert: PgBackRestStaleBackup
          expr: time() - ccp_backrest_last_full_backup_time_since_completion_seconds > 604800
          for: 1h
          labels:
            severity: critical
          annotations:
            summary: "No full backup in the last 7 days"

AWS EKS การใช้งาน

การปรับใช้ PGO บน AWS EKS จำเป็นต้องกำหนดค่าไดรเวอร์ EBS CSI สำหรับวอลุ่มถาวรและบทบาท IAM สำหรับบัญชีบริการ (IRSA) สำหรับการเข้าถึงข้อมูลสำรอง S3 วิธีนี้จะช่วยหลีกเลี่ยงการจัดเก็บข้อมูลประจำตัว AWS ที่มีอายุยาวนานในความลับ Kubernetes

# Install the EBS CSI driver (required for gp3 volumes)
eksctl create addon --name aws-ebs-csi-driver --cluster my-cluster --region eu-west-1 \
  --service-account-role-arn arn:aws:iam::111122223333:role/AmazonEKS_EBS_CSI_DriverRole

# Create a gp3 StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: gp3-csi
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  iops: "3000"
  throughput: "125"
  encrypted: "true"
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
# IAM policy for pgBackRest S3 access
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::mycompany-pg-backups",
        "arn:aws:s3:::mycompany-pg-backups/*"
      ]
    }
  ]
}

# Create an IRSA-enabled service account
eksctl create iamserviceaccount \
  --name pgbackrest-sa \
  --namespace databases \
  --cluster my-cluster \
  --attach-policy-arn arn:aws:iam::111122223333:policy/PGBackRestS3Policy \
  --approve

ในข้อมูลจำเพาะPostgresClusterให้อ้างอิงบัคเก็ต S3 และภูมิภาค PGO จะใช้ข้อมูลรับรองบัญชีบริการของพ็อด (ผ่าน IRSA) โดยอัตโนมัติ โดยไม่ต้องใช้คีย์การเข้าถึงที่ชัดเจน

backups:
  pgbackrest:
    repos:
      - name: repo1
        s3:
          bucket: mycompany-pg-backups
          endpoint: s3.eu-west-1.amazonaws.com
          region: eu-west-1

สำหรับความยืดหยุ่นหลาย AZ ตรวจสอบให้แน่ใจว่ากลุ่มโหนด EKS ของคุณขยายโซนความพร้อมใช้งานอย่างน้อยสามโซน และใช้ข้อจำกัดการแพร่กระจายโทโพโลยีที่แสดงก่อนหน้านี้เพื่อกระจายพ็อด PostgreSQL ข้ามโซนเหล่านั้น

Azure AKS การปรับใช้

Azure AKS ใช้ดิสก์ที่ได้รับการจัดการสำหรับพื้นที่จัดเก็บข้อมูลถาวร และ Azure Blob Storage สำหรับการสำรองข้อมูล pgBackRest คลาสพื้นที่จัดเก็บข้อมูลที่แนะนำใช้ Premium SSD v2 หรือ Premium LRS สำหรับเวิร์กโหลดฐานข้อมูล

# StorageClass for Azure Premium SSD
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: azure-premium-ssd
provisioner: disk.csi.azure.com
parameters:
  skuName: Premium_LRS
  kind: Managed
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true

---
# pgBackRest with Azure Blob Storage
backups:
  pgbackrest:
    configuration:
      - secret:
          name: pgbackrest-azure-creds
    global:
      repo1-azure-account: mystorageaccount
      repo1-retention-full: "7"
    repos:
      - name: repo1
        schedules:
          full: "0 2 * * 0"
          differential: "0 2 * * 1-6"
        azure:
          container: pg-backups

---
# Secret with Azure credentials
apiVersion: v1
kind: Secret
metadata:
  name: pgbackrest-azure-creds
  namespace: databases
stringData:
  azure.conf: |
    [global]
    repo1-azure-key=BASE64_STORAGE_ACCOUNT_KEY

สำหรับ Workload Identity (เทียบเท่า Azure ของ AWS IRSA) ให้กำหนดค่าคลัสเตอร์ AKS กับผู้ออก OIDC และสร้างข้อมูลรับรองตัวตนแบบรวมศูนย์สำหรับบัญชีบริการ pgBackRest วิธีนี้ช่วยลดความจำเป็นในการเก็บคีย์บัญชีที่เป็นความลับ

GCP GKE การปรับใช้

GKE ใช้ Persistent Disk (pd-ssd) สำหรับการจัดเก็บข้อมูลและ GCS สำหรับการสำรองข้อมูล pgBackRest GKE Workload Identity จะจับคู่บัญชีบริการ Kubernetes กับบัญชีบริการ Google Cloud เพื่อการตรวจสอบสิทธิ์แบบไม่ใช้คีย์ที่ปลอดภัย

# StorageClass for GKE SSD Persistent Disk
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: pd-ssd
provisioner: pd.csi.storage.gke.io
parameters:
  type: pd-ssd
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true

---
# pgBackRest with GCS
backups:
  pgbackrest:
    configuration:
      - secret:
          name: pgbackrest-gcs-creds
    repos:
      - name: repo1
        gcs:
          bucket: mycompany-pg-backups

---
# GCS service account key secret
apiVersion: v1
kind: Secret
metadata:
  name: pgbackrest-gcs-creds
  namespace: databases
stringData:
  gcs-key.json: |
    {
      "type": "service_account",
      "project_id": "my-project",
      ...
    }
# Enable Workload Identity on GKE
gcloud container clusters update my-cluster \
  --workload-pool=my-project.svc.id.goog

# Create and bind IAM service account
gcloud iam service-accounts create pgbackrest-gcs \
  --display-name="pgBackRest GCS Access"

gcloud projects add-iam-policy-binding my-project \
  --member="serviceAccount:pgbackrest-gcs@my-project.iam.gserviceaccount.com" \
  --role="roles/storage.objectAdmin"

gcloud iam service-accounts add-iam-policy-binding \
  pgbackrest-gcs@my-project.iam.gserviceaccount.com \
  --role="roles/iam.workloadIdentityUser" \
  --member="serviceAccount:my-project.svc.id.goog[databases/production-db-pgbackrest]"

การกู้คืนความเสียหายหลายภูมิภาค

PGO รองรับคลัสเตอร์สแตนด์บายสำหรับการกู้คืนความเสียหายข้ามภูมิภาค คลัสเตอร์สแตนด์บายเล่นซ้ำ WAL จากที่เก็บ pgBackRest ของคลัสเตอร์หลักอย่างต่อเนื่อง โดยคงสำเนาวอร์มไว้ซึ่งสามารถเลื่อนระดับเป็นคลัสเตอร์หลักอิสระในกรณีที่เกิดความล้มเหลวในระดับภูมิภาค

DR หลายภูมิภาคพร้อมคลัสเตอร์สแตนด์บาย PGOภูมิภาค A (หลัก)เช่น AWS eu-west-1 / Azure ยุโรปตะวันตกPostgreSQL หลักอ่าน/เขียนผู้นำอุปถัมภ์แบบจำลอง(2)อ่านอย่างเดียวการจำลองแบบซิงค์WAL เอกสารเก่าpgBackRest Repo (S3/GCS/หยด)เปิดใช้งานการจำลองแบบข้ามภูมิภาคแล้วS3 ข้ามภูมิภาคการจำลองภูมิภาค B (สแตนด์บาย)เช่น AWS us-east-1 / Azure East USPostgreSQL คลัสเตอร์สแตนด์บายเล่นซ้ำ WAL อย่างต่อเนื่องจาก Repoอ่านอย่างเดียว (โหมดสแตนด์บาย)pgBackRest Repo (ภูมิภาค B)จำลองแบบจากภูมิภาค AWAL เล่นซ้ำล้มเหลว / เลื่อนระดับโหมดซิงโครนัสRPO ≈ นาที (จัดส่ง WAL)RTO & #8776; 5-15 นาทีAsync (ค่าเริ่มต้น)RPO & #8776; วินาที-นาทีRTO & #8776; 5-15 นาทีคลัสเตอร์สแตนด์บายสามารถเลื่อนระดับเป็นคลัสเตอร์หลักอิสระผ่านการเปลี่ยนแปลงข้อมูลจำเพาะ PostgresCluster
# Standby cluster in Region B
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
  name: production-db-standby
  namespace: databases
spec:
  postgresVersion: 16
  image: registry.crunchydata.com/crunchydata/crunchy-postgres:ubi8-16.6-1

  standby:
    enabled: true
    repoName: repo1

  instances:
    - name: pgha1
      replicas: 2
      dataVolumeClaimSpec:
        storageClassName: gp3-csi
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 100Gi

  backups:
    pgbackrest:
      image: registry.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.54.1-0
      configuration:
        - secret:
            name: pgbackrest-s3-creds
      repos:
        - name: repo1
          s3:
            bucket: mycompany-pg-backups
            endpoint: s3.us-east-1.amazonaws.com
            region: us-east-1

หากต้องการเลื่อนระดับคลัสเตอร์สแตนด์บายระหว่างเกิดภัยพิบัติ ให้ตั้งค่าstandby.enabled: falseในข้อมูลจำเพาะและใช้การเปลี่ยนแปลง PGO ส่งเสริมการสแตนด์บายให้กับคลัสเตอร์หลักที่เป็นอิสระ โปรโมชันนี้ไม่สามารถย้อนกลับได้ คุณจะต้องสร้างความสัมพันธ์ในการจำลองใหม่ตั้งแต่ต้นหลังจากที่ภูมิภาคหลักเดิมฟื้นตัวแล้ว

การปรับใช้โลหะเปลือย k3s/Rancher

การรัน PGO บน Bare Metal k3s พร้อมการจัดการ Rancher จำเป็นต้องได้รับความเอาใจใส่อย่างระมัดระวังในด้านพื้นที่จัดเก็บและเครือข่าย เนื่องจากคุณไม่มีดิสก์หรือโหลดบาลานเซอร์ที่ผู้ให้บริการระบบคลาวด์จัดการ

k3s / Rancher PGO Deployment (โลหะเปลือย)เซิร์ฟเวอร์การจัดการ Rancherคลัสเตอร์k3s (3 เซิร์ฟเวอร์ + โหนดเอเจนต์ N)ตัวดำเนินการ PGOโหนดเอเจนต์ 1PostgreSQL หลัก+ ผู้ส่งออก pgMonitorLonghorn PVC (ข้อมูล + WAL)pgBackRest Repo (PVC ท้องถิ่น)โหนดเอเจนต์ 2PostgreSQL แบบจำลอง 1+ ผู้ส่งออก pgMonitorLonghorn PVC (ข้อมูล + WAL)PgBouncer Podเอเจนต์โหนด 3PostgreSQL แบบจำลอง 2+ ผู้ส่งออก pgMonitorLonghorn PVC (ข้อมูล + WAL)PgBouncer PodMetalLB LoadBalancer — เปิดเผย pg-primary:5432 + pgbouncer:5432หลักแบบจำลองเขายาวสำรองPgBouncerโลหะLBโอเปอเรเตอร์

ที่เก็บของทรงยาว

Longhorn เป็นระบบจัดเก็บข้อมูลบล็อกแบบกระจายน้ำหนักเบาสำหรับ Kubernetes ซึ่งเหมาะสำหรับสภาพแวดล้อมที่เป็นโลหะเปลือย โดยจำลองวอลุ่มข้ามหลายโหนดเพื่อความคงทนและรองรับสแน็ปช็อต การสำรองข้อมูล และการขยายวอลุ่ม

# Install Longhorn via Helm
helm repo add longhorn https://charts.longhorn.io
helm repo update

helm install longhorn longhorn/longhorn \
  --namespace longhorn-system \
  --create-namespace \
  --set defaultSettings.defaultReplicaCount=3 \
  --set defaultSettings.storageOverProvisioningPercentage=100 \
  --set defaultSettings.storageMinimalAvailablePercentage=15

---
# Longhorn StorageClass for PostgreSQL
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: longhorn-pg
provisioner: driver.longhorn.io
parameters:
  numberOfReplicas: "3"
  staleReplicaTimeout: "2880"
  fsType: ext4
  dataLocality: best-effort
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: Retain

MetalLB สำหรับโหลดบาลานซ์

# Install MetalLB
helm repo add metallb https://metallb.github.io/metallb
helm install metallb metallb/metallb --namespace metallb-system --create-namespace

---
# Configure IP address pool
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: pg-pool
  namespace: metallb-system
spec:
  addresses:
    - 192.168.1.200-192.168.1.210
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: pg-l2
  namespace: metallb-system
spec:
  ipAddressPools:
    - pg-pool

ด้วยการกำหนดค่า MetalLB บริการของ PGO ประเภทLoadBalancerจะได้รับที่อยู่ IP จากพูลของคุณ ทำให้จุดสิ้นสุด PostgreSQL หลักและ PgBouncer สามารถเข้าถึงได้โดยตรงจากเครือข่ายของคุณ โดยไม่ต้องส่งต่อพอร์ตด้วยตนเอง

pgBackRest พร้อม Local PVC หรือ NFS สำหรับ Bare Metal

# For environments without S3/GCS/Azure Blob, use a PVC-based repo
backups:
  pgbackrest:
    repos:
      - name: repo1
        schedules:
          full: "0 2 * * 0"
          differential: "0 2 * * 1-6"
        volume:
          volumeClaimSpec:
            storageClassName: longhorn-pg
            accessModes: ["ReadWriteOnce"]
            resources:
              requests:
                storage: 200Gi

สำหรับสภาพแวดล้อมแบบช่องว่างอากาศ คุณยังสามารถกำหนดค่าพื้นที่เก็บข้อมูล pgBackRest สำรองที่จัดส่งการสำรองข้อมูลไปยังการแบ่งปัน NFS หรืออินสแตนซ์ MiniIO ที่ทำงานภายในองค์กร โดยจัดเตรียมสำเนาสำรองนอกคลัสเตอร์โดยไม่ต้องพึ่งพาระบบคลาวด์

การกำหนดค่าการเข้ารหัส

TLS/SSL

PGO สร้างใบรับรอง TLS ที่ลงนามด้วยตนเองสำหรับการสื่อสารภายในทั้งหมดตามค่าเริ่มต้น — อินสแตนซ์ PostgreSQL, การจำลอง, pgBackRest และ PgBouncer ล้วนสื่อสารผ่านช่องทางที่เข้ารหัสโดยไม่มีการจัดการใบรับรองด้วยตนเอง อย่างไรก็ตาม สำหรับสภาพแวดล้อมการใช้งานจริง คุณมักจะต้องการใช้ใบรับรองที่ลงนามโดย CA ขององค์กรของคุณ

# Create a TLS secret with your CA-signed certificates
kubectl create secret tls production-db-tls \
  --cert=server.crt \
  --key=server.key \
  -n databases

kubectl create secret generic production-db-ca \
  --from-file=ca.crt=ca.crt \
  -n databases

---
# Reference in PostgresCluster spec
spec:
  customTLSSecret:
    name: production-db-tls
  customReplicationTLSSecret:
    name: production-db-replication-tls

PGO กำหนดค่า PostgreSQL ด้วยssl = onและตั้งค่าพารามิเตอร์ssl_cert_file,ssl_key_fileและssl_ca_fileที่เหมาะสม PgBouncer ได้รับการกำหนดค่าในทำนองเดียวกันให้ต้องใช้ TLS สำหรับการเชื่อมต่อไคลเอนต์ และใช้ TLS เมื่อเชื่อมต่อกับแบ็กเอนด์ PostgreSQL

# Enforce TLS for all client connections via pg_hba.conf
spec:
  patroni:
    dynamicConfiguration:
      postgresql:
        pg_hba:
          - hostssl all all 0.0.0.0/0 scram-sha-256
          - hostssl replication all 0.0.0.0/0 scram-sha-256

การกำหนดค่า PostgreSQL แบบกำหนดเอง

PGO แสดงการกำหนดค่า PostgreSQL ผ่านส่วนการกำหนดค่าไดนามิก Patroni นี่เป็นแนวทางที่แนะนำเนื่องจาก Patroni รับประกันว่าอินสแตนซ์ทั้งหมดจะรักษาการกำหนดค่าที่สอดคล้องกันและจัดการการรีสตาร์ทเมื่อจำเป็น

patroni:
  dynamicConfiguration:
    postgresql:
      parameters:
        # Memory
        shared_buffers: 4GB
        effective_cache_size: 12GB
        work_mem: 64MB
        maintenance_work_mem: 1GB
        huge_pages: "try"

        # WAL
        wal_buffers: 128MB
        min_wal_size: 2GB
        max_wal_size: 8GB
        checkpoint_completion_target: 0.9
        wal_compression: lz4

        # Query Planning
        random_page_cost: 1.1
        effective_io_concurrency: 200
        default_statistics_target: 200

        # Parallelism
        max_worker_processes: 16
        max_parallel_workers_per_gather: 4
        max_parallel_workers: 8
        max_parallel_maintenance_workers: 4

        # Connections
        max_connections: 200
        idle_in_transaction_session_timeout: 60000
        statement_timeout: 300000

        # Logging
        log_min_duration_statement: 250
        log_checkpoints: "on"
        log_connections: "on"
        log_disconnections: "on"
        log_lock_waits: "on"
        log_temp_files: 0
        log_autovacuum_min_duration: 0

        # Autovacuum Tuning
        autovacuum_max_workers: 5
        autovacuum_naptime: 30
        autovacuum_vacuum_cost_limit: 800
        autovacuum_vacuum_scale_factor: 0.02
        autovacuum_analyze_scale_factor: 0.01

พารามิเตอร์เหล่านี้ถือว่าโหนดที่มีแกน CPU 16 แกน และ RAM ขนาด 32 GB สำหรับ PostgreSQL โดยเฉพาะ ปรับshared_buffersเป็นประมาณ 25% ของ RAM ที่มีอยู่ และeffective_cache_sizeเป็นประมาณ 75% การตั้งค่า WAL และจุดตรวจสอบได้รับการปรับแต่งสำหรับปริมาณงานที่มีการเขียนข้อมูลจำนวนมาก — ลดmax_wal_sizeสำหรับระบบที่อ่านข้อมูลจำนวนมาก ซึ่งความถี่ของจุดตรวจสอบมีความสำคัญน้อยกว่า

การจัดการผู้ใช้และฐานข้อมูล

PGO จัดการผู้ใช้ PostgreSQL และฐานข้อมูลอย่างชัดเจนผ่านส่วนusersของข้อมูลจำเพาะPostgresClusterเมื่อคุณเพิ่มผู้ใช้ PGO จะสร้างบทบาทใน PostgreSQL สร้างรหัสผ่านแบบสุ่ม และจัดเก็บข้อมูลประจำตัวไว้ใน Kubernetes Secret

users:
  - name: appuser
    databases: ["appdb"]
    options: "NOSUPERUSER NOCREATEDB NOCREATEROLE"
  - name: readonly
    databases: ["appdb"]
    options: "NOSUPERUSER NOCREATEDB NOCREATEROLE"
  - name: migrations
    databases: ["appdb"]
    options: "NOSUPERUSER CREATEDB"
  - name: monitoring
    databases: ["postgres"]
    options: "NOSUPERUSER LOGIN"

---
# Access credentials from the generated secret
kubectl get secret production-db-pguser-appuser -n databases -o jsonpath='{.data.password}' | base64 -d

# The secret also contains a full connection URI
kubectl get secret production-db-pguser-appuser -n databases -o jsonpath='{.data.uri}' | base64 -d
# postgresql://appuser:PASSWORD@production-db-primary.databases.svc:5432/appdb

สำหรับการให้สิทธิ์การเข้าถึงแบบอ่านอย่างเดียว ให้ใช้คุณสมบัติdatabaseInitSQLเพื่อรัน SQL ในการสร้างคลัสเตอร์ที่สร้างบทบาทแบบอ่านอย่างเดียวและให้สิทธิ์ SELECT บนตารางทั้งหมด

# init.sql ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: init-sql-configmap
  namespace: databases
data:
  init.sql: |
    -- Read-only role for reporting users
    ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly;
    GRANT CONNECT ON DATABASE appdb TO readonly;
    GRANT USAGE ON SCHEMA public TO readonly;
    GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;

    -- Extensions
    CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
    CREATE EXTENSION IF NOT EXISTS pgcrypto;
    CREATE EXTENSION IF NOT EXISTS pg_trgm;

การอัปเดตแบบ Rolling และการอัปเกรดเวอร์ชันหลัก

PGO จัดการการอัพเกรดเวอร์ชันรองผ่านการอัปเดตแบบต่อเนื่อง เมื่อคุณเปลี่ยนแท็กรูปภาพในข้อมูลจำเพาะPostgresClusterไปเป็นแพตช์ที่ใหม่กว่า PGO จะอัปเดตอินสแตนซ์ทีละรายการ โดยเริ่มจากแบบจำลองและจบด้วยอินสแตนซ์หลัก (ซึ่งจะทริกเกอร์การเปลี่ยน Patroni เพื่อลดเวลาหยุดทำงานให้เหลือน้อยที่สุด)

# Minor version upgrade: change the image tag
spec:
  image: registry.crunchydata.com/crunchydata/crunchy-postgres:ubi8-16.7-0
การอัพเกรด

เวอร์ชันหลัก (เช่น PostgreSQL 15 ถึง 16) ต้องใช้pg_upgradeซึ่ง PGO จัดเตรียมผ่านPGUpgradeCRD ที่แยกต่างหาก

apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PGUpgrade
metadata:
  name: production-db-upgrade
  namespace: databases
spec:
  postgresClusterName: production-db
  fromPostgresVersion: 15
  toPostgresVersion: 16
  image: registry.crunchydata.com/crunchydata/crunchy-upgrade:ubi8-5.7.2-0

กระบวนการอัปเกรดจะปิดคลัสเตอร์ที่มีอยู่ รันpg_upgrade --linkเพื่อดำเนินการอัปเกรดแบบแทนที่โดยใช้ฮาร์ดลิงก์ (ลดการคัดลอกข้อมูล) ตรวจสอบการอัพเกรด และเริ่มคลัสเตอร์ในเวอร์ชันใหม่ ทำการสำรองข้อมูลทั้งหมดก่อนที่จะเริ่มการอัพเกรดเวอร์ชันหลักและทดสอบขั้นตอนบนคลัสเตอร์ที่ไม่ใช่การใช้งานจริงก่อน

# Pre-upgrade checklist
# 1. Take a full backup
kubectl annotate postgrescluster production-db -n databases \
  postgres-operator.crunchydata.com/pgbackrest-backup="$(date +%s)" \
  --overwrite

# 2. Verify backup completed
kubectl exec -it production-db-pgha1-0 -n databases -- pgbackrest info --stanza=db

# 3. Shutdown the cluster (set replicas to 0 or use PGO shutdown annotation)
kubectl annotate postgrescluster production-db -n databases \
  postgres-operator.crunchydata.com/shutdown="$(date +%s)" \
  --overwrite

# 4. Apply the PGUpgrade resource
kubectl apply -f pg-upgrade.yaml

# 5. Update the PostgresCluster spec with the new version and image
# 6. Remove the shutdown annotation to start the upgraded cluster
คำแนะนำในการปรับแต่งการผลิต

การรัน PGO ในการผลิตต้องให้ความสนใจกับพื้นที่ปฏิบัติงานหลายประการ นอกเหนือจากการใช้งานครั้งแรก

ประสิทธิภาพการจัดเก็บข้อมูล

  • แยกข้อมูลและวอลุ่ม WAL: ใช้walVolumeClaimSpecเสมอเพื่อวาง WAL บน PVC เฉพาะ วิธีนี้จะป้องกันไม่ให้กิจกรรม WAL ที่มีการเขียนจำนวนมากแข่งขันกับข้อมูล I/O
  • ใช้พื้นที่จัดเก็บข้อมูล IOPS สูง: gp3 (AWS), Premium SSD v2 (Azure), pd-ssd (GCP) หรือ Longhorn ที่รองรับ NVMe บนโลหะเปลือย รูปแบบ I/O แบบสุ่มของ PostgreSQL ต้องการพื้นที่จัดเก็บข้อมูลที่มีความหน่วงต่ำ
  • การขยายระดับเสียง: ตรวจสอบให้แน่ใจว่า StorageClass ของคุณมีallowVolumeExpansion: truePGO สามารถขยาย PVC ได้โดยไม่รบกวนผู้ให้บริการพื้นที่จัดเก็บข้อมูลที่รองรับ

งบประมาณการหยุดชะงักของพ็อด

PGO จะสร้าง PDB สำหรับอินสแตนซ์ PostgreSQL ของคุณโดยอัตโนมัติ แต่ตรวจสอบว่าเหมาะสมกับข้อกำหนด HA ของคุณ

# Check PDBs
kubectl get pdb -n databases
NAME                    MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
production-db-pgha1     1               N/A               2                     7d
คำขอและขีดจำกัดทรัพยากร

  • ตั้งค่าคำขอหน่วยความจำเท่ากับขีดจำกัดสำหรับพ็อดฐานข้อมูลเพื่อป้องกัน OOM kill และรับรองคลาส QoS ที่รับประกัน
  • ตั้งค่าคำขอ CPU อย่างระมัดระวังและจำกัดให้สูงกว่าเพื่อให้สามารถระเบิดได้ระหว่างการดำเนินการสุญญากาศหรือการบำรุงรักษา
  • ตรวจสอบการใช้งานจริงผ่านตัวชี้วัด pgMonitor และปรับรายไตรมาส

การจัดการการเชื่อมต่อ

  • เชื่อมต่อผ่าน PgBouncer เสมอ ไม่ใช่เชื่อมต่อกับ PostgreSQL โดยตรง
  • ตั้งค่าmax_connectionsใน PostgreSQL เป็นค่าที่คำนึงถึงขนาดพูลของ PgBouncer รวมถึงการเชื่อมต่อระบบ (การจำลองแบบ การตรวจสอบ superuser)
  • ใช้โหมดการรวมธุรกรรมสำหรับเว็บแอปพลิเคชัน สลับไปใช้การรวมเซสชันเฉพาะในกรณีที่แอปพลิเคชันของคุณใช้คำสั่งที่เตรียมไว้หรือสถานะระดับเซสชัน (เช่น คำสั่งSETตารางชั่วคราว)
การตรวจสอบการสำรองข้อมูล

  • ทดสอบการกู้คืนเป็นประจำโดยการสร้างคลัสเตอร์โคลนจากการสำรองข้อมูลและเรียกใช้การทดสอบควันระดับแอปพลิเคชัน
  • ตรวจสอบการแจ้งเตือนPgBackRestStaleBackupเพื่อให้แน่ใจว่าการสำรองข้อมูลเสร็จสิ้นตามกำหนดเวลา
  • ตรวจสอบ PITR โดยการเรียกคืนการประทับเวลาที่เฉพาะเจาะจง และตรวจสอบความสอดคล้องของข้อมูล
# Clone cluster for backup validation
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
  name: backup-validation
  namespace: databases
spec:
  postgresVersion: 16
  image: registry.crunchydata.com/crunchydata/crunchy-postgres:ubi8-16.6-1
  dataSource:
    postgresCluster:
      clusterName: production-db
      repoName: repo1
      options:
        - --type=time
        - --target="2026-04-12 06:00:00+00"
  instances:
    - name: pgha1
      replicas: 1
      dataVolumeClaimSpec:
        storageClassName: gp3-csi
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 100Gi
  backups:
    pgbackrest:
      repos:
        - name: repo1
          volume:
            volumeClaimSpec:
              accessModes: ["ReadWriteOnce"]
              resources:
                requests:
                  storage: 50Gi
นโยบายเครือข่าย

# Restrict PostgreSQL traffic to known namespaces
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: postgres-network-policy
  namespace: databases
spec:
  podSelector:
    matchLabels:
      postgres-operator.crunchydata.com/cluster: production-db
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              app-access: database
        - podSelector:
            matchLabels:
              postgres-operator.crunchydata.com/cluster: production-db
      ports:
        - port: 5432
          protocol: TCP
        - port: 9187
          protocol: TCP
รายการตรวจสอบการตรวจสอบ

  • Replication lag: แจ้งเตือนเมื่อเรพลิกาใด ๆ เกิน 100MB หรือ 60 วินาทีของความล่าช้า
  • ความอิ่มตัวของการเชื่อมต่อ: แจ้งเตือนเมื่อมีการเชื่อมต่อที่ใช้งานเกิน 80% ของmax_connections
  • อัตราการทำธุรกรรมผิดปกติ: กำหนดพื้นฐาน TPS ของคุณและแจ้งเตือนการเบี่ยงเบนที่สำคัญ
  • การใช้ดิสก์: แจ้งเตือนที่เกณฑ์ 70% และ 85% ด้วย runbooks การขยายวอลุ่ม
  • ความใหม่ของการสำรองข้อมูล: แจ้งเตือนเมื่อการสำรองข้อมูลเต็มรูปแบบครั้งล่าสุดเก่ากว่าหน้าต่าง RPO ของคุณ
  • การช่วงชิงการล็อค: แจ้งเตือนการล็อคที่ถือไว้เป็นเวลานาน (> 30 วินาที) ที่อาจบ่งบอกถึงข้อบกพร่องของแอปพลิเคชัน
  • สุขภาพเครื่องดูดฝุ่นอัตโนมัติ: แจ้งเตือนเมื่อโต๊ะไม่ได้รับการดูดฝุ่นเกิน 24 ชั่วโมง

คู่มือการกู้คืนความเสียหาย

แผนการกู้คืนระบบจะมีประโยชน์ก็ต่อเมื่อได้รับการทดสอบแล้วเท่านั้น Runbook ต่อไปนี้สรุปขั้นตอนสำคัญสำหรับการกู้คืนจากสถานการณ์ความล้มเหลวทั่วไป

พ็อดเดี่ยวล้มเหลว

Patroni และ Kubernetes จัดการสิ่งนี้โดยอัตโนมัติ หากพ็อดหลักขัดข้อง Patroni จะเลื่อนระดับแบบจำลองภายใน 10-30 วินาที Kubernetes รีสตาร์ทพ็อดที่ล้มเหลว ซึ่งจะเข้าร่วมอีกครั้งในรูปแบบเรพลิกา

โหนดเดี่ยวล้มเหลว

หากโหนดที่ใช้งานพ็อด PostgreSQL เสีย Kubernetes จะจัดกำหนดการพ็อดใหม่บนโหนดที่มีสุขภาพดี พ็อดเชื่อมต่อกับ PVC ที่มีอยู่ (หากพื้นที่จัดเก็บข้อมูลเชื่อมต่อกับเครือข่าย) หรือกู้คืนจากการสำรองข้อมูล (หากใช้พื้นที่จัดเก็บในตัวเครื่อง) กฎการต่อต้านความสัมพันธ์ของพ็อดช่วยให้แน่ใจว่าอินสแตนซ์ที่เหลือยังคงให้บริการการรับส่งข้อมูลต่อไป

สูญเสียคลัสเตอร์อย่างสมบูรณ์

หากคลัสเตอร์ Kubernetes ทั้งหมดสูญหาย ให้ปรับใช้คลัสเตอร์ใหม่ ติดตั้ง PGO และสร้างPostgresClusterใหม่โดยมีdataSourceชี้ไปที่ที่เก็บข้อมูลสำรอง PGO กู้คืนข้อมูลสำรองล่าสุดและเล่น WAL ซ้ำไปยังจุดที่มีอยู่ล่าสุด

ความล้มเหลวระดับภูมิภาค

หากภูมิภาคหลักหายไป ให้เลื่อนระดับคลัสเตอร์สแตนด์บายโดยตั้งค่าstandby.enabled: falseอัปเดต DNS หรือโหลดบาลานเซอร์ของคุณให้ชี้ไปยังภูมิภาคหลักใหม่ เมื่อพื้นที่เดิมฟื้นตัวแล้ว คุณสามารถสร้างความสัมพันธ์ในการสแตนด์บายขึ้นมาใหม่ในแบบย้อนกลับได้

# Promote standby cluster
kubectl patch postgrescluster production-db-standby -n databases --type merge \
  -p '{"spec":{"standby":{"enabled":false}}}'

# Verify the cluster is now an independent primary
kubectl exec -it production-db-standby-pgha1-0 -n databases -- patronictl list

คำสั่งปฏิบัติการ อ้างอิงด่วน

# Cluster status
kubectl get postgrescluster -n databases
kubectl describe postgrescluster production-db -n databases

# Patroni status
kubectl exec -it production-db-pgha1-0 -n databases -- patronictl list
kubectl exec -it production-db-pgha1-0 -n databases -- patronictl history

# Connect to PostgreSQL
kubectl exec -it production-db-pgha1-0 -n databases -- psql -U postgres

# Backup info
kubectl exec -it production-db-pgha1-0 -n databases -- pgbackrest info --stanza=db

# Manual backup
kubectl annotate postgrescluster production-db -n databases \
  postgres-operator.crunchydata.com/pgbackrest-backup="$(date +%s)" --overwrite

# Restart PostgreSQL (rolling)
kubectl annotate postgrescluster production-db -n databases \
  postgres-operator.crunchydata.com/restart="$(date +%s)" --overwrite

# Logs
kubectl logs production-db-pgha1-0 -n databases -c database
kubectl logs production-db-pgha1-0 -n databases -c pgbackrest
kubectl logs production-db-pgha1-0 -n databases -c exporter

# PgBouncer status
kubectl exec -it $(kubectl get pod -l postgres-operator.crunchydata.com/role=pgbouncer -n databases -o name | head -1) -n databases -- psql -U pgbouncer pgbouncer -c "SHOW POOLS;"

# Scale replicas
kubectl patch postgrescluster production-db -n databases --type merge \
  -p '{"spec":{"instances":[{"name":"pgha1","replicas":5}]}}'

สรุป

Crunchy Data PGO แปลง PostgreSQL บน Kubernetes จากภาระในการปฏิบัติงานไปเป็นระบบที่สามารถจัดการและประกาศได้PostgresClusterCRD รวบรวมการปรับใช้ทั้งหมด เช่น อินสแตนซ์ การจำลอง การสำรองข้อมูล การรวมกลุ่ม การตรวจสอบ TLS ในทรัพยากรที่ควบคุมเวอร์ชันเดียว Patroni มีระบบเฟลโอเวอร์อัตโนมัติที่ผ่านการทดสอบการต่อสู้แล้ว pgBackRest มอบการสำรองข้อมูลระดับองค์กรพร้อมการกู้คืน ณ เวลาใดเวลาหนึ่งไปยังที่จัดเก็บออบเจ็กต์บนคลาวด์ PgBouncer จัดการการรวมการเชื่อมต่อที่โมเดลกระบวนการต่อการเชื่อมต่อของ PostgreSQL ต้องการในวงกว้าง และ pgMonitor จะป้อนตัววัดที่คุณต้องการลงใน Prometheus และ Grafana เพื่อการมองเห็นการปฏิบัติงาน

รูปแบบการปรับใช้ทั่วทั้ง AWS EKS, Azure AKS, GCP GKE และ Bare Metal k3s มีข้อมูลจำเพาะหลักPostgresClusterเหมือนกัน — คลาสพื้นที่จัดเก็บข้อมูล การกำหนดค่าพื้นที่เก็บข้อมูลสำรอง และเลเยอร์เครือข่ายมีการเปลี่ยนแปลงอะไรบ้าง ความสม่ำเสมอนี้เป็นคุณค่าที่แท้จริงของแนวทางที่อิงจากผู้ปฏิบัติงาน: ทีมของคุณเรียนรู้เครื่องมือหนึ่งชิ้น โมเดลการปฏิบัติงานหนึ่งชุด และชุดการดำเนินการหนึ่งชุดที่ทำงานได้ทุกที่

เริ่มต้นด้วยคลัสเตอร์สามอินสแตนซ์, PgBouncer ในโหมดการรวมธุรกรรม, กำหนดการสำรองข้อมูลส่วนต่างรายสัปดาห์แบบเต็มบวกรายวัน และการแจ้งเตือน Prometheus หลัก ตรวจสอบขั้นตอนการกู้คืนข้อมูลสำรองของคุณในวันแรก ไม่ใช่เมื่อคุณต้องการมันครั้งแรก ขยายไปสู่คลัสเตอร์สแตนด์บายหลายภูมิภาค การจำลองแบบซิงโครนัส และการปรับแต่งขั้นสูงตามความต้องการด้านความพร้อมใช้งานและความพร้อมในการดำเนินงานของคุณที่เพิ่มขึ้น ผู้ปฏิบัติงานจะจัดการกับกลไก ความรับผิดชอบของคุณคือการทำความเข้าใจสถาปัตยกรรมให้ดีพอที่จะทำให้เกิดการแลกเปลี่ยนที่เหมาะสมสำหรับปริมาณงานของคุณ