Workstation Logo
المنتجات
مختبرات الذكاء الاصطناعيوكلاء OpenAIوكلاء ClaudeGrok BotWorkstation CRM (WSL CRM)التسويقجميع المنتجات
حلول الذكاء الاصطناعي
محطات عمل الذكاء الاصطناعيAI SME Packagesذكاء اصطناعي خاصمجموعات GPUذكاء اصطناعي طرفيمختبر الذكاء الاصطناعي للمؤسساتالذكاء الاصطناعي حسب الصناعة
الخدمات
Platform ModernisationDigital EngineeringData Foundations & AIAutonomous Operationsاستشارات الذكاء الاصطناعيأتمتة DevOpsالأمن السيبرانيتطوير البرمجياتبناء الوكلاءإعداد MLOps
من نحن
الشركاءقصص العملاء
المقالات
الوثائق
WSL ProxyRing PromoterWSL VaultJobshoutSysOps 24/7
المدونة
اتصل بناLogin
Workstation

محطات عمل الذكاء الاصطناعي وبرمجيات الوكلاء المتعددة والبنية التحتية لوحدات GPU وحلول الوكلاء الأذكياء للشركات الحديثة.

اتصل بنا

حلول الذكاء الاصطناعي

محطات عمل الذكاء الاصطناعيAI SME Packagesذكاء اصطناعي خاصمجموعات GPUذكاء اصطناعي طرفيمختبر الذكاء الاصطناعي للمؤسساتالذكاء الاصطناعي حسب الصناعة

المنتجات

جميع المنتجاتWSL CRM و ERPالتسويقوكلاء OpenAIWSL ProxyRing PromoterWSL VaultJobshoutSysOps 24/7

الشركة

من نحنلماذا Workstationالشركاءقصص العملاءالأسعاراتصل

الموارد

المقالاتالتوثيقالمدونةبحثخريطة الموقع
مكتب المملكة المتحدة
77-79 Marlowes, Hemel Hempstead HP1 1LFالاتجاهات - اسلك المخرج 20 من الطريق M25 في لندن الخارجيةرقم الشركة: 11641870الاثنين - الجمعة: 9:00 ص - 6:00 م بتوقيت GMT
+44 7515 356 146
مكتب بلجيكا
Workstation SRL, Rue Vanderkindere 34, 1180 Uccle, BrusselsBE 0751.518.683الاثنين - الجمعة: 9:00 ص - 6: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: نشر Enterprise Kubernetes

Enterprise PostgreSQL HA مع Crunchy Data PGO على Kubernetes

Balinder Walia12 أبريل 202626 min read

يتطلب تشغيل PostgreSQL في الإنتاج على Kubernetes أكثر من مجرد StatefulSet مع وحدة تخزين ثابتة. أنت بحاجة إلى تجاوز الفشل التلقائي، والنسخ الاحتياطي المستمر والاسترداد في الوقت المناسب، وتجميع الاتصالات، وتشفير TLS، والمراقبة، والقدرة على النشر بشكل متسق عبر موفري الخدمات السحابية والمعدنية. يقدم الإصدار الخامس من Crunchy Data PGO (Postgres Operator) كل هذا من خلال مورد مخصص واحد أصلي لـ Kubernetes -PostgresClusterCRD - مدعوم بمكونات تم اختبارها في المعركة: Patroni لـ HA القائم على الإجماع، وpgBackRest للنسخ الاحتياطي للمؤسسات، وPgBouncer لتجميع الاتصالات، وpgMonitor لقابلية المراقبة المتوافقة مع Prometheus.

يغطي هذا الدليل كل ما هو مطلوب لاتخاذ مجموعة PostgreSQL التي تديرها PGO بدءًا من النشر الأولي وحتى التشغيل على مستوى الإنتاج عبر AWS EKS وAzure AKS وGCP GKE والمعادن العارية k3s مع Rancher. يتضمن كل قسم قيم YAML وHelm الملموسة والإجراءات التشغيلية التي يمكنك تكييفها مع بيئتك.

بنية البيانات المقرمشة PGO v5

PGO v5 هو إعادة كتابة كاملة لمشغل Crunchy Postgres. فهو يستبدل pgcluster/pgreplica/pgpolicy CRDs السابقة بموردPostgresClusterواحد يصف بشكل تعريفي كل جانب من جوانب نشر PostgreSQL. يراقب المشغل التغييرات التي تطرأ على هذا المورد ويقوم بتسوية كائنات Kubernetes الأساسية - StatefulSets، Services، ConfigMaps، Secrets، Jobs - لمطابقة الحالة المطلوبة.

تم بناء الهيكل على أربعة ركائز. يعملPatroniكعربة جانبية في كل حاوية PostgreSQL ويدير اختيار القائد وطوبولوجيا النسخ المتماثل وتجاوز الفشل التلقائي باستخدام الإجماع الموزع الأصلي لـ Kubernetes.pgBackRest يتعاملمع النسخ الاحتياطية الكاملة والتفاضلية والتزايدية بالإضافة إلى أرشفة WAL المستمرة لتخزين الكائنات (S3 وGCS وAzure Blob) أو PVCs المحلية. يوفرPgBouncerتجميع اتصال خفيف الوزن يحمي PostgreSQL من عواصف الاتصال. يعرضpgMonitorمقاييس PostgreSQL من خلال عربة جانبية لمصدر Prometheus للتكامل مع مكدس إمكانية المراقبة الحالي لديك.

بنية PGO للبيانات المقرمشةجراب المشغل PGOPostgresالكلوستر CRDالمثيل الأساسيStatefulSet (جراب واحد)قائد الراعيمصدر pgMonitorمثيلاتالمتماثلةStatefulSet (N pods)النسخ المتماثلةPatroniالنسخ المتماثل للبثpgBackRest الريبوS3 / GCS / Azure Blobكامل + فرق + IncrأرشيفوولوولPgBouncer Poolerنشر(2+ كبسولة)Prometheus + GrafanapgMonitor Metricsحاضنات التطبيقاتاتصل عبر PgBouncerالابتدائيالنسخ المتماثلةالنسخ الاحتياطيبولرمراقبة

المشغل نفسه عديم الحالة - جميع الحالات المستمرة موجودة في مجموعة PostgreSQL ومستودع النسخ الاحتياطي الخاص بها. وهذا يعني أنه يمكنك ترقية المشغل أو إعادة تشغيله دون التأثير على قواعد البيانات قيد التشغيل. حلقة تسوية المشغل غير فعالة: يؤدي تطبيق نفس مواصفات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
مواصفات

PostgresCluster 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 مختلفة.

HA المستند إلى Patroni وتجاوز الفشل التلقائي

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). يعد فهم كيفية توافق هذه العناصر معًا أمرًا ضروريًا لتصميم إستراتيجية النسخ الاحتياطي التي توازن بين تكلفة التخزين وسرعة النسخ الاحتياطي ووقت الاسترداد.

pgBackRest بنية النسخ الاحتياطيPostgreSQL الابتدائيملفات بيانات(PGDATA)شرائحWALpg_wal/ الدليلpgBackRest Agentأرشيف WAL المستمرالنسخ الاحتياطية المجدولةمستودع pgBackRestS3 / GCS / Azure بلوب / PVCالنسخ الاحتياطي الكاملنسخة كاملةالتفاضليمنذ آخركاملتزايدي (منذ آخر مرة)أرشيفوول000000030000000A000000030000000B000000030000000C... مستمر ...يمكّن PITRالجدول الزمني لاسترداد النقطة الزمنيةكاملالأحد 2 صباحًافرقفرقفرقفرقفرقكاملالأحد 2 صباحًاتيار WAL المستمر →هدفPITRاستعادة إلى أي نقطة زمنيةالنسخ الاحتياطي الكاملالتفاضليةوال ستريمهدف الاسترداد

نسخة احتياطية كاملة لـينسخدليل بيانات 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. بدون عمليات الاحتفاظ القوية، قد يتم إسقاط الاتصالات الخاملة بصمت بواسطة مكونات الشبكة المتوسطة، مما يتسبب في حدوث أخطاء في التطبيق في محاولة الاستعلام التالية.

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

للحصول على مرونة مناطق توافر خدمات متعددة، تأكد من أن مجموعات عقدة 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

بالنسبة إلى هوية حمل العمل (ما يعادل Azure لـ AWS IRSA)، قم بتكوين مجموعة AKS مع مُصدر OIDC وقم بإنشاء بيانات اعتماد هوية موحدة لحساب خدمة pgBackRest. وهذا يلغي الحاجة إلى تخزين مفاتيح الحساب في الأسرار.

نشر

GCP GKE

يستخدم

GKE القرص الثابت (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 الاحتياطيةالمنطقة أ (الابتدائية)، على سبيل المثال، AWS eu-west-1 / Azure غرب أوروباPostgreSQL الابتدائيقراءة/كتابةزعيم المستفيدينالنسخ المتماثلة(2)للقراءة فقطمزامنة النسخ المتماثلأرشيف والpgBackRest Repo (S3/GCS/Blob)تم تمكين النسخ المتماثل عبر المناطقS3 عبر المناطقالنسخ المتماثلالمنطقة ب (الاستعداد)، على سبيل المثال، AWS us-east-1 / Azure شرق الولايات المتحدةPostgreSQL المجموعة الاحتياطيةإعادة تشغيل WAL المستمر من Repoللقراءة فقط (وضع الاستعداد)pgBackRest Repo (المنطقة B)منسوخ من المنطقة Aوال إعادة تشغيلتجاوز فشل/ الترويج لـالوضع المتزامنRPO ≈ دقيقة (شحن WAL)RTO ≈ 5-15 دقيقةغير متزامن (افتراضي)RPO ≈ ثانية-دقيقةRTO ≈ 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 على الطراز المعدني k3s مع إدارة Rancher اهتمامًا دقيقًا بالتخزين والشبكات، نظرًا لعدم وجود أقراص مُدارة بواسطة موفر السحابة أو موازنات تحميل.

k3s / نشر Rancher PGO (المعدن العاري)خادم إدارة المزرعةمجموعةk3s (3 عقد وكيل + N)مشغل PGOعقدة الوكيل1PostgreSQL الابتدائي+ pgMonitor مُصدرLonghorn PVC (بيانات + WAL)pgBackRest Repo (PVC المحلي)عقدة الوكيل2PostgreSQL النسخة المتماثلة 1+ pgMonitor مُصدرLonghorn PVC (بيانات + WAL)PgBouncer Podعقدة الوكيل3PostgreSQL النسخة المتماثلة 2+ pgMonitor مُصدرLonghorn PVC (بيانات + WAL)PgBouncer PodMetalLB LoadBalancer — يعرض pg-primary:5432 + pgbouncer:5432الابتدائيالنسخ المتماثلةقرون طويلةالنسخ الاحتياطيPgBouncerميتالبالمشغل

تخزين طويل القرن

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 مع PVC المحلي أو NFS للمعادن العارية

# 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 أو مثيل MinIO الذي يعمل محليًا، مما يوفر نسخة احتياطية خارج المجموعة بدون تبعيات سحابية.

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

تفترض هذه المعلمات عقدة تحتوي على 16 نواة CPU وذاكرة وصول عشوائي (RAM) سعة 32 جيجابايت مخصصة لـ PostgreSQL. اضبطshared_buffersعلى 25% تقريبًا من ذاكرة الوصول العشوائي المتاحة و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 عند إنشاء المجموعة الذي يقوم بإنشاء دور للقراءة فقط ويمنحه تحديدًا على كافة الجداول.

# 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;
تحديثات

المتجددة وترقيات الإصدار الرئيسي

يتعامل

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 الذي يتطلب الكثير من الكتابة من التنافس مع إدخال/إخراج البيانات.
  • استخدم وحدة تخزين IOPS عالية: gp3 (AWS)، أو Premium SSD v2 (Azure)، أو pd-ssd (GCP)، أو Longhorn المدعوم من NVMe على المعدن العاري. تتطلب أنماط الإدخال/الإخراج العشوائية لـ PostgreSQL تخزينًا منخفض زمن الوصول.
  • توسيع الحجم: تأكد من أن StorageClass الخاص بك يحتوي علىallowVolumeExpansion: true. يمكن لـ PGO توسيع PVCs بشكل غير متقطع على موفري التخزين المدعومين.

ميزانيات تعطيل الكبسولة

يقوم

PGO تلقائيًا بإنشاء PDBs لمثيلات 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 وضمان فئة جودة الخدمة المضمونة.
  • قم بتعيين CPU بشكل متحفظ وحدود أعلى للسماح بالانفجار أثناء عمليات التفريغ أو الصيانة.
  • راقب الاستخدام الفعلي عبر مقاييس pgMonitor واضبطه كل ثلاثة أشهر.
إدارة الاتصال

  • يتصل دائمًا عبر PgBouncer، وليس مباشرة بـ PostgreSQL.
  • قم بتعيينmax_connectionsفي PostgreSQL إلى قيمة تمثل حجم تجمع PgBouncer بالإضافة إلى اتصالات النظام (النسخ المتماثل والمراقبة والمستخدم المتميز).
  • استخدم وضع تجميع المعاملات لتطبيقات الويب. قم بالتبديل إلى تجميع الجلسات فقط إذا كان تطبيقك يستخدم عبارات معدة أو حالة على مستوى الجلسة (على سبيل المثال، أوامر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
قائمة مراجعة مراقبة

  • تأخر النسخ: التنبيه عندما تتجاوز أي نسخة متماثلة 100 ميجابايت أو 60 ثانية من التأخير.
  • تشبع الاتصال: تنبيه عندما تتجاوز الاتصالات النشطة 80% منmax_connections.
  • شذوذات معدل المعاملات: حدد TPS الخاص بك ونبه إلى الانحرافات الكبيرة.
  • استخدام القرص: تنبيه عند عتبات 70% و85% مع دفاتر تشغيل توسيع الحجم.
  • نضارة النسخ الاحتياطي: تنبيه عندما تكون آخر نسخة احتياطية كاملة أقدم من نافذة RPO الخاصة بك.
  • تنافس القفل: تنبيه بشأن الأقفال طويلة الأمد (> 30 ثانية) والتي قد تشير إلى أخطاء في التطبيق.
  • صحة الفراغ التلقائي: تنبيه عند عدم تنظيف الطاولات بالمكنسة الكهربائية خلال أكثر من 24 ساعة.

دليل التشغيل للتعافي من الكوارث

تكون خطة التعافي من الكوارث مفيدة فقط إذا تم اختبارها. يوضح دليل التشغيل التالي الإجراءات الأساسية للتعافي من سيناريوهات الفشل الشائعة.

فشل جراب واحد

يتعامل

Patroni وKubernetes مع هذا الأمر تلقائيًا. في حالة تعطل الكبسولة الأساسية، يقوم Patroni بترويج نسخة طبق الأصل خلال 10-30 ثانية. يقوم Kubernetes بإعادة تشغيل الكبسولة الفاشلة، والتي يتم إعادة الانضمام إليها كنسخة متماثلة.

فشل عقدة واحدة

إذا ماتت العقدة التي تقوم بتشغيل جراب PostgreSQL، فإن Kubernetes يعيد جدولة الكبسولة على عقدة سليمة. يتم توصيل الكبسولة بـ PVC الموجود بها (إذا كان التخزين متصلاً بالشبكة) أو يتم استعادتها من النسخة الاحتياطية (إذا تم استخدام التخزين المحلي). تضمن قواعد مكافحة التقارب في Pod استمرار المثيلات المتبقية في خدمة حركة المرور.

خسارة كاملة للكتلة

في حالة فقدان مجموعة 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 وk3s المعدنية العارية في نفس مواصفاتPostgresClusterالأساسية - ما يتغير هو فئة التخزين وتكوين مستودع النسخ الاحتياطي وطبقة الشبكة. هذا الاتساق هو القيمة الحقيقية للنهج القائم على المشغل: يتعلم فريقك أداة واحدة، ونموذج تشغيلي واحد، ومجموعة واحدة من أدلة التشغيل التي تعمل في كل مكان.

ابدأ بمجموعة مكونة من ثلاث مثيلات، وPgBouncer في وضع تجميع المعاملات، وجدول نسخ احتياطي تفاضلي أسبوعي كامل بالإضافة إلى يومي، وتنبيهات Prometheus الأساسية. تحقق من صحة إجراء استعادة النسخة الاحتياطية في اليوم الأول — وليس عندما تحتاج إليها لأول مرة. قم بالتوسيع ليشمل مجموعات الاستعداد متعددة المناطق، والنسخ المتماثل المتزامن، والضبط المتقدم مع نمو متطلبات التوفر لديك والنضج التشغيلي. المشغل يتعامل مع الميكانيكا. مسؤوليتك هي فهم البنية جيدًا بما يكفي لإجراء المفاضلات المناسبة لعبء العمل الخاص بك.