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 مع مشغل Zalando Postgres: دليل نشر Kubernetes للسحابة المتعددة

انشر PostgreSQL HA من فئة الإنتاج مع مشغل Zalando على أي منصة Kubernetes

Balinder Walia12 أبريل 202626 min read
مقدمة

: لماذا يعتبر التوفر العالي لـ PostgreSQL على Kubernetes مهمًا

يتطلب تشغيل PostgreSQL في الإنتاج توفرًا عاليًا (HA). يمكن أن يكلف وقت التوقف عن العمل، الذي يتم قياسه بالدقائق، المؤسسات ملايين الدولارات من الإيرادات المفقودة، وتآكل ثقة العملاء، وانتهاك اتفاقيات مستوى الخدمة. أصبح Kubernetes هو النظام الأساسي الفعلي لتنسيق أعباء العمل المجهزة بالحاويات، ولكن تشغيل الخدمات ذات الحالة مثل PostgreSQL على Kubernetes يقدم تحديات فريدة: إدارة التخزين المستمرة، واختيار القائد، وتجاوز الفشل التلقائي، وتنسيق النسخ الاحتياطي، وتجميع الاتصال.

Zalando Postgres Operatorهو حل مفتوح المصدر تم اختباره في المعركة، وقد صممه Zalando - أكبر بائع تجزئة للأزياء عبر الإنترنت في أوروبا - لإدارة المئات من مجموعات PostgreSQL في الإنتاج. إنه يستفيد منPatroniلانتخاب القائد على أساس الإجماع، وSpiloكصورة حاوية PostgreSQL، وWAL-Gللأرشفة المستمرة والاسترداد في الوقت المناسب، وPgBouncerلتجميع الاتصال. توفر هذه المكونات معًا عملية نشر PostgreSQL مؤتمتة بالكامل وذاتية الإصلاح تعمل عبر أي توزيع لـ Kubernetes — بدءًا من الخدمات السحابية المُدارة مثل AWS EKS وAzure AKS وGoogle GKE إلى المجموعات المعدنية التي تعمل على k3s مع Rancher.

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

بنية مشغل Zalando Postgres

يعد فهم البنية أمرًا ضروريًا قبل النشر. يتبع مشغل Zalando Postgres نمط مشغل Kubernetes: فهو يراقب تعريفات الموارد المخصصة (CRDs) من النوعpostgresqlويقوم بتسوية الحالة المطلوبة مع موارد Kubernetes الفعلية. إليك كيفية توافق المكونات معًا:

بنية المشغل Zalando PostgresPostgreSQL CRDنوع: postgresqlPostgres المشغلساعات واكسسواراتيوفق بينStatefulSetيدير دورة حياة الكبسولةجراب أساسيسبيلو (PostgreSQL)وكيل المستفيدطبق الأصل جراب 1سبيلو (PostgreSQL)وكيل المستفيدطبق الأصل جراب 2سبيلو (PostgreSQL)وكيل المستفيدباتروني DCS (Kubernetes API)انتخاب القائد & حالة الكتلةPgBouncerتجمع الاتصالوول-جيالنسخ الاحتياطية إلى S3/GCS/Azureالابتدائيالنسخة المتماثلةإجماع/DCSالنسخ الاحتياطيتجمع اتصال

Spilo: صورة حاوية PostgreSQL

Spiloهي صورة Docker من Zalando التي تجمع PostgreSQL مع Patroni وWAL-G والامتدادات الأساسية. تقوم كل حجرة في StatefulSet بتشغيل حاوية Spilo. مقابض Spilo:

    خادم
  • PostgreSQL— محرك قاعدة البيانات نفسه، يدعم الإصدارات من 13 إلى 16
  • Patroni— وكيل HA الذي يدير اختيار القائد والنسخ المتماثل وتجاوز الفشل
  • WAL-G- أداة أرشفة WAL المستمرة والنسخ الاحتياطي الأساسي
  • pg_cron، pg_stat_statements، PostGIS- الملحقات المطلوبة بشكل شائع
  • المثبتة مسبقًا

Patroni: انتخاب القائد وتجاوز الفشل التلقائي

Patroni هو قلب آلية HA. ويستخدم مخزن التكوين الموزع (DCS) للحفاظ على حالة المجموعة وإجراء اختيار القائد. في سياق مشغل Zalando، يستخدم PatroniKubernetes APIنفسه باعتباره DCS (عبر نقاط النهاية أو ConfigMaps)، مما يلغي الحاجة إلى مجموعة etcd خارجية أو ZooKeeper.

إليك كيفية عمل عملية تجاوز الفشل في Patroni:

    فحوصات صحة
  1. — يراقب كل وكيل Patroni بشكل مستمر مثيل PostgreSQL المحلي الخاص به ويبلغ حالة الصحة إلى DCS.
  2. قفل القائد— يحمل الأساسي قفلًا رئيسيًا في DCS (كائن نقطة نهاية Kubernetes). يحتوي القفل على TTL (افتراضي 30 ثانية).
  3. اكتشاف الفشل— إذا فشل الأساسي في تجديد قفله داخل TTL، فإن النسخ المتماثلة تكتشف الغياب.
  4. الانتخابات— تتنافس النسخ المتماثلة المؤهلة على قفل القائد. النسخة المتماثلة ذات تأخر النسخ المتماثل الأقل تفوز.
  5. الترويج- تقوم النسخة المتماثلة الفائزة بترقية نفسها إلى المستوى الأساسي، وتحديث DCS، وتحديث نقطة نهاية خدمة Kubernetesmasterتلقائيًا.
  6. Fencing- تم تسييج المرحلة الابتدائية القديمة (تم إيقافها أو خفض رتبتها إلى نسخة متماثلة) لمنع انقسام الدماغ.

عادةً ما تكتمل عملية تجاوز الفشل بأكملها فيخلال 15-30 ثانية، مما يضمن الحد الأدنى من وقت التوقف عن العمل لتطبيقاتك.

WAL-G: الأرشفة المستمرة والنسخ الاحتياطي

WAL-G هي أداة أرشيفية من الجيل التالي لـ PostgreSQL تدعم النسخ الاحتياطي إلى S3 وGoogle Cloud Storage (GCS) وAzure Blob Storage. ويوفر:

  • النسخ الاحتياطية الأساسية— نسخ احتياطي فعلي كامل باستخدامpg_basebackup
  • أرشفة WAL- شحن سجل الكتابة المسبق المستمر لاسترداد النقطة الزمنية
  • نسخ دلتا الاحتياطية- النسخ الاحتياطية التزايدية التي تخزن فقط الصفحات التي تم تغييرها
  • تشفير
  • — تشفير AES-256 للنسخ الاحتياطية أثناء عدم النشاط
  • ضغط
  • — ضغط LZ4 أو ZSTD لتقليل تكاليف التخزين

Kubernetes التسلسل الهرمي للموارد

عندما تقوم بإنشاء موردpostgresqlمخصص، يقوم المشغل بإنشاء مجموعة شاملة من موارد Kubernetes لإدارة المجموعة. يعد فهم هذا التسلسل الهرمي أمرًا مهمًا لاستكشاف الأخطاء وإصلاحها ومراقبتها:

Kubernetes التسلسل الهرمي للموارد — مشغل Zalandopostgresql CRDPostgres المشغلستاتفولسيتخدمة(رئيسي)خدمة(نسخة طبق الأصل)نقاط النهايةبي دي بيالقرونPVCsأسرارPgBouncer نشرخدمة(المجمع)الابتدائيالنسخة المتماثلةالنسخة المتماثلةالخطوط الصلبة = الإنشاء المباشر | الخطوط المتقطعة = الإنشاء الشرطيموارد

تم إنشاؤها بواسطة المشغل

  • StatefulSet— يدير حجرات PostgreSQL بهويات شبكة مستقرة ونشر منظم
  • خدمات
  • - خدمتان من خدمات ClusterIP:<cluster-name>للنسخة الأساسية و<cluster-name>-replللنسخ المتماثلة للقراءة
  • نقاط النهاية— يقوم Patroni بتحديث نقاط النهاية للإشارة إلى القائد الحالي لتجاوز الفشل بشكل سلس
  • PodDisruptionBudgets (PDB)- يضمن بقاء مثيل واحد على الأقل متاحًا أثناء الاضطرابات الطوعية
  • Secrets- المستخدم المتميز PostgreSQL والنسخ المتماثل وبيانات اعتماد التطبيق المخزنة في صورة أسرار Kubernetes
  • مطالبات الحجم المستمر (PVCs)- PVC واحد لكل جراب لـ PostgreSQL تخزين البيانات
  • PgBouncer Deployment— تم نشر مُجمّع الاتصال الاختياري كنشر منفصل مع الخدمة الخاصة به
تثبيت

على منصات Kubernetes المتعددة

المتطلبات الأساسية

قبل تثبيت مشغل Zalando Postgres، تأكد من أن لديك:

  • مجموعة Kubernetes قيد التشغيل (الإصدار 1.25+)
  • تم تكوين
  • kubectlمع وصول مسؤول المجموعة إلى
  • helmv3 تم تثبيت
  • تم تكوين فئة التخزين الافتراضية
تثبيت مشغل

عبر Helm

تستخدم طريقة التثبيت الموصى بها Helm. يعمل هذا بشكل متسق عبر جميع منصات Kubernetes:

# Add the Zalando Postgres Operator Helm repository
helm repo add postgres-operator-charts https://opensource.zalando.com/postgres-operator/charts/postgres-operator
helm repo add postgres-operator-ui-charts https://opensource.zalando.com/postgres-operator/charts/postgres-operator-ui
helm repo update

# Create a dedicated namespace
kubectl create namespace postgres-operator

# Install the operator with custom values
helm install postgres-operator postgres-operator-charts/postgres-operator \
  --namespace postgres-operator \
  --set configKubernetes.enable_pod_antiaffinity=true \
  --set configKubernetes.pod_environment_configmap=postgres-pod-config \
  --set configAwsOrGcp.aws_region=us-east-1 \
  --set configLoadBalancer.db_hosted_zone=db.example.com \
  --set configConnectionPooler.connection_pooler_default_cpu_request=500m \
  --set configConnectionPooler.connection_pooler_default_memory_request=100Mi

# Optionally install the operator UI for visual management
helm install postgres-operator-ui postgres-operator-ui-charts/postgres-operator-ui \
  --namespace postgres-operator

تحقق من تشغيل المشغل:

kubectl get pods -n postgres-operator
# Expected output:
# NAME                                 READY   STATUS    RESTARTS   AGE
# postgres-operator-7f8b9c6d4-x2k9j   1/1     Running   0          2m

AWS EKS تفاصيل النشر

يتطلب Amazon EKS تكوينًا محددًا لأداء PostgreSQL الأمثل:

# EKS-specific Helm values (eks-values.yaml)
configAwsOrGcp:
  aws_region: us-east-1
  enable_ebs_gp3_migration: true
  additional_secret_mount: "aws-iam-token"

configKubernetes:
  enable_pod_antiaffinity: true
  pod_environment_configmap: "postgres-pod-config"
  spilo_privileged: false
  storage_resize_mode: pvc

# Use EBS gp3 StorageClass for better performance
# Create the StorageClass first:
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-gp3-postgres
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  iops: "6000"
  throughput: "400"
  encrypted: "true"
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true

بالنسبة للنسخ الاحتياطية لـ WAL-G على EKS، قم بتكوين أدوار IAM لحسابات الخدمة (IRSA):

# Create IAM policy for WAL-G S3 access
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:ListBucket",
        "s3:DeleteObject",
        "s3:GetBucketLocation"
      ],
      "Resource": [
        "arn:aws:s3:::my-pg-backups",
        "arn:aws:s3:::my-pg-backups/*"
      ]
    }
  ]
}

Azure AKS نشر

يستخدم

Azure AKS قرص Azure للتخزين المستمر والهوية المُدارة للمصادقة الاحتياطية:

# AKS-specific StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: managed-premium-postgres
provisioner: disk.csi.azure.com
parameters:
  skuName: Premium_LRS
  cachingMode: ReadOnly
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
---
# WAL-G backup to Azure Blob Storage environment variables
apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-pod-config
  namespace: default
data:
  AZURE_STORAGE_ACCOUNT: "pgbackupsstorage"
  AZURE_STORAGE_ACCESS_KEY: "" # Use Managed Identity instead
  WALG_AZ_PREFIX: "azure://pg-wal-backups/$(SCOPE)"
  USE_WALG_BACKUP: "true"
  USE_WALG_RESTORE: "true"
  BACKUP_SCHEDULE: "0 2 * * *"
  BACKUP_NUM_TO_RETAIN: "7"

نشر Google GKE

يستخدم

Google Kubernetes Engine معرف القرص الثابت وهوية عبء العمل للوصول إلى النسخ الاحتياطي لـ GCS:

# GKE StorageClass for SSD Persistent Disks
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ssd-postgres
provisioner: pd.csi.storage.gke.io
parameters:
  type: pd-ssd
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
---
# GCS backup configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-pod-config
  namespace: default
data:
  WALG_GS_PREFIX: "gs://my-pg-backups/$(SCOPE)"
  USE_WALG_BACKUP: "true"
  USE_WALG_RESTORE: "true"
  GOOGLE_APPLICATION_CREDENTIALS: "/var/secrets/google/key.json"
  BACKUP_SCHEDULE: "0 2 * * *"
  BACKUP_NUM_TO_RETAIN: "7"

المعدن العاري k3s/Rancher مع وحدة تخزين طويلة القرون

بالنسبة لعمليات النشر المحلية، يوفر k3s توزيع Kubernetes خفيف الوزن ويوفر Longhorn تخزينًا موزعًا للكتل. يعد هذا المزيج مثاليًا عندما تحتاج إلى التحكم الكامل في البنية الأساسية الخاصة بك دون تقييد بائع السحابة.

# Install k3s on all nodes
# Master node:
curl -sfL https://get.k3s.io | sh -s - server \
  --cluster-init \
  --disable traefik \
  --write-kubeconfig-mode 644

# Worker nodes:
curl -sfL https://get.k3s.io | sh -s - agent \
  --server https://master-ip:6443 \
  --token $(cat /var/lib/rancher/k3s/server/node-token)

# Install Longhorn for persistent storage
helm repo add longhorn https://charts.longhorn.io
helm install longhorn longhorn/longhorn \
  --namespace longhorn-system \
  --create-namespace \
  --set defaultSettings.defaultReplicaCount=3 \
  --set defaultSettings.defaultDataPath=/mnt/longhorn

# Install MetalLB for LoadBalancer services
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.5/config/manifests/metallb-native.yaml

# Configure MetalLB IP pool
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: postgres-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.1.200-192.168.1.210
k3s / نشر المعادن العاريةخادم إدارة المزرعةالعقدة 1 (خادم k3s)PostgreSQL الابتدائيسبيلو + باترونيمشغل زالاندوتجمع PgBouncerحجم القرون الطويلة/mnt/longhorn (3 نسخ متماثلة)العقدة 2 (خادم k3s)PostgreSQL النسخة المتماثلةسبيلو + باترونيتجمع PgBouncerPrometheus مصدرحجم القرون الطويلة/mnt/longhorn (3 نسخ متماثلة)العقدة 3 (وكيل k3s)PostgreSQL النسخة المتماثلةسبيلو + باترونيتجمع PgBouncerGrafana لوحة القيادةحجم القرون الطويلة/mnt/longhorn (3 نسخ متماثلة)HAProxy / MetalLB LoadBalancerالنسخ الاحتياطيةWAL-GNFS / MinIO S3 متوافق معالابتدائينسخة طبق الأصل منPgBouncerقرون طويلةالنسخ المتماثل للبثمواصفات

PostgreSQL الكتلة CRD

جوهر نشر أ مجموعة PostgreSQL مع مشغل Zalando هي موردpostgresqlالمخصص. يعلن بيان YAML هذا عن الحالة المرغوبة لمجموعتك، ويقوم المشغل بتحويلها إلى واقع. فيما يلي مواصفات CRD الشاملة والجاهزة للإنتاج:

apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
  name: pg-production-cluster
  namespace: databases
  labels:
    team: platform
    environment: production
spec:
  teamId: "platform"
  volume:
    size: 100Gi
    storageClass: ebs-gp3-postgres
  numberOfInstances: 3
  enableConnectionPooler: true
  enableReplicaConnectionPooler: true
  connectionPooler:
    numberOfInstances: 2
    mode: transaction
    schema: pooler
    user: pooler
    resources:
      requests:
        cpu: 500m
        memory: 100Mi
      limits:
        cpu: "1"
        memory: 256Mi
  users:
    app_user:
    - superuser
    - createdb
    readonly_user: []
  databases:
    app_database: app_user
  postgresql:
    version: "16"
    parameters:
      shared_buffers: "2GB"
      max_connections: "200"
      work_mem: "64MB"
      maintenance_work_mem: "512MB"
      effective_cache_size: "6GB"
      random_page_cost: "1.1"
      effective_io_concurrency: "200"
      wal_buffers: "64MB"
      max_wal_size: "4GB"
      min_wal_size: "1GB"
      checkpoint_completion_target: "0.9"
      default_statistics_target: "100"
      log_statement: "ddl"
      log_min_duration_statement: "1000"
      idle_in_transaction_session_timeout: "600000"
      lock_timeout: "30000"
      statement_timeout: "60000"
  patroni:
    initdb:
      encoding: "UTF8"
      locale: "en_US.UTF-8"
      data-checksums: "true"
    pg_hba:
    - hostssl all all 0.0.0.0/0 md5
    - host    all all 0.0.0.0/0 md5
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    synchronous_mode: false
    synchronous_mode_strict: false
    maximum_lag_on_failover: 33554432
  resources:
    requests:
      cpu: "2"
      memory: 8Gi
    limits:
      cpu: "4"
      memory: 16Gi
  podAnnotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "9187"
  tolerations:
  - key: "database"
    operator: "Equal"
    value: "postgres"
    effect: "NoSchedule"
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: workload-type
          operator: In
          values:
          - database
  enableShmVolume: true
  spiloRunAsUser: 101
  spiloRunAsGroup: 103
  spiloFSGroup: 103
شرح حقول

الرئيسية CRD

  • numberOfInstances— إجمالي عدد القرون. يقوم المشغل تلقائيًا بتعيين إحداها كنسخة أساسية والباقي كنسخ متماثلة متدفقة.
  • EnableConnectionPooler— ينشر PgBouncer Sidecar للخدمة الأساسية، مما يقلل من حمل الاتصال.
  • EnableReplicaConnectionPooler— ينشر PgBouncer منفصلًا لخدمة النسخ المتماثلة، وهو ضروري لأحمال العمل كثيفة القراءة.
  • postgresql.parameters— تم تمرير معلمات تكوين PostgreSQL المباشرة إلىpostgresql.conf.
  • المستفيد— يقوم بتكوين سلوك Patroni بما في ذلك TTL، وانتظار الحلقة، ومهلة إعادة المحاولة، ووضع النسخ المتماثل المتزامن.
  • Volume.storageClass— تعيينات إلى StorageClass الخاص بالمنصة (EBS gp3 على AWS، وPremium SSD على Azure، وSSD PD على GCP، وLonghorn على k3s).
  • EnableShmVolume- يتم تركيبtmpfsفي/dev/shmللذاكرة المشتركة PostgreSQL، وهو أمر بالغ الأهمية للأداء.
تجمع اتصال

مع PgBouncer

يجعل نموذج العملية لكل اتصال الخاص بـ

PostgreSQL من المكلف التعامل مع أعداد كبيرة من اتصالات العملاء. يستهلك كل اتصال حوالي 10 ميغابايت من ذاكرة الوصول العشوائي. يحل PgBouncer هذه المشكلة عن طريق مضاعفة آلاف اتصالات العملاء عبر مجموعة صغيرة من اتصالات PostgreSQL الفعلية.

يدعم مشغل Zalando أصلاً نشر PgBouncer. عندما تقوم بتعيينenableConnectionPooler: trueفي CRD، يقوم المشغل بإنشاء:

  • نشر PgBouncer مع عدد النسخ المتماثلة القابلة للتكوين
  • خدمة مخصصة (<cluster-name>-pooler) للاتصالات المجمعة
  • مزامنة بيانات الاعتماد التلقائية مع PostgreSQL
أوضاع تكوين

PgBouncer

# PgBouncer connection pooler modes:
#
# transaction (recommended for most workloads)
#   - Connection returned to pool after each transaction
#   - Best balance of efficiency and compatibility
#   - Cannot use session-level features (prepared statements, temp tables)
#
# session
#   - Connection held for entire client session
#   - Full PostgreSQL compatibility
#   - Lower pooling efficiency
#
# statement
#   - Connection returned after each statement
#   - Most efficient but most restrictive
#   - Only works with autocommit queries

# Custom PgBouncer configuration via operator
spec:
  connectionPooler:
    numberOfInstances: 3
    mode: transaction
    schema: pooler
    user: pooler
    defaultPoolSize: 25
    maxDBConnections: 100
    resources:
      requests:
        cpu: 250m
        memory: 128Mi
      limits:
        cpu: "1"
        memory: 256Mi

بالنسبة للتطبيقات التي تحتاج إلى بيانات معدة أو ميزات على مستوى الجلسة، اتصل مباشرة بخدمات PostgreSQL متجاوزة PgBouncer، أو استخدم وضع التجميعsessionمع مقايضة انخفاض كفاءة الاتصال.

النسخ المتماثل PostgreSQL متعدد المناطق

بالنسبة للتطبيقات العالمية التي تتطلب قراءات ذات زمن وصول منخفض من مواقع جغرافية متعددة أو التعافي من الكوارث عبر المناطق، يعد النسخ المتماثل متعدد المناطق أمرًا ضروريًا. يدعم مشغل Zalando ذلك من خلال المجموعات الاحتياطية التي تتكرر من المجموعة الأساسية عبر النسخ المتماثل المتدفق أو أرشيفات WAL-G.

النسخ المتماثل للبث PostgreSQL متعدد المناطقالولايات المتحدة-شرق-1 (AWS EKS)المجموعة الأساسيةpg-prod-us (3 قرون)الابتدائينسخة طبق الأصل منالنسخ المتماثل للمزامنة داخل AZWAL-G → S3 (مستمر)PgBouncer Poolerالاتحاد الأوروبي-WEST-1 (Azure AKS)المجموعة الاحتياطيةpg-standby-eu (2 جراب)الاستعدادالنسخة المتماثلةالنسخ المتماثل المتتاليWAL-G → Azure BlobPgBouncer (للقراءة فقط)AP-SOUTHEAST (GCP GKE)المجموعة الاحتياطيةpg-standby-ap (2 جراب)الاستعدادالنسخة المتماثلةالنسخ المتماثل المتتاليWAL-G → دلو GCSPgBouncer (للقراءة فقط)غير متزامنغير متزامن (شحن WAL)طوبولوجيا النسخ المتماثلأساسي (الولايات المتحدة-شرق) → البث غير المتزامن إلى الاتحاد الأوروبي-غرب & مجموعات الاستعداد AP-SOUTHEAST | RPO: ~ثواني | RTO: أقل من 5 دقائق مع الترويج اليدويمزامنة النسخ المتماثلالنسخ المتماثل غير المتزامنالابتدائيقائد الاستعدادقراءة النسخة المتماثلة

تكوين النسخ المتماثل المتدفق

يعد النسخ المتماثل للتدفق

PostgreSQL أساس HA في مشغل Zalando. وهو يعمل عن طريق شحن سجلات سجل الكتابة المسبقة (WAL) من السجلات الأساسية إلى النسخ المتماثلة في الوقت الفعلي تقريبًا. يقوم المشغل بتكوين ذلك تلقائيًا، لكن فهم التفاصيل يساعد في الضبط واستكشاف الأخطاء وإصلاحها.

  • النسخ المتماثل المتزامن- ينتظر الأساسي نسخة متماثلة واحدة على الأقل لتأكيد استلام WAL قبل تنفيذ المعاملة. وهذا يضمن عدم فقدان أي بيانات (RPO=0) ولكنه يضيف زمن الوصول. تمكين معpatroni.synchronous_mode: true.
  • النسخ المتماثل غير المتزامن- يتم الالتزام الأساسي على الفور ويشحن WAL بشكل غير متزامن. زمن وصول أقل قليلاً ولكن من المحتمل فقدان البيانات أثناء تجاوز الفشل. هذا هو الافتراضي.
  • النسخ المتماثل المتتالي— يمكن نسخ النسخ المتماثلة من نسخ متماثلة أخرى بدلاً من النسخة الأساسية، مما يقلل الحمل على النسخة الأساسية في المجموعات الكبيرة.
# Enable synchronous replication for zero data loss
spec:
  patroni:
    synchronous_mode: true
    synchronous_mode_strict: false  # Allow async if no sync replica available
    synchronous_node_count: 1       # Number of sync replicas required
  postgresql:
    parameters:
      synchronous_commit: "on"      # Matches Patroni synchronous_mode
      max_wal_senders: "10"         # Maximum WAL sender processes
      wal_keep_size: "1GB"          # WAL retention for replica catch-up
      hot_standby: "on"             # Allow queries on replicas
      hot_standby_feedback: "on"    # Reduce query conflicts on replicas
النسخ الاحتياطي والاسترداد

مع WAL-G

WAL-G تكوين النسخ الاحتياطي

يعد تكوين النسخ الاحتياطي المناسب أمرًا بالغ الأهمية للتعافي من الكوارث. يقوم مشغل Zalando بدمج WAL-G للنسخ الاحتياطي المستمر لتخزين الكائنات. فيما يلي تكوين كامل للتخزين المتوافق مع S3:

# ConfigMap for WAL-G backup configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-pod-config
  namespace: databases
data:
  # S3 backup configuration
  AWS_ENDPOINT: "https://s3.us-east-1.amazonaws.com"
  AWS_S3_FORCE_PATH_STYLE: "false"
  AWS_REGION: "us-east-1"
  WALG_S3_PREFIX: "s3://my-pg-backups/$(SCOPE)"
  WALG_DISABLE_S3_SSE: "false"
  WALG_S3_SSE: "aws:kms"
  WALG_S3_SSE_KMS_ID: "arn:aws:kms:us-east-1:123456789:key/mrk-abcdef"

  # Backup scheduling and retention
  USE_WALG_BACKUP: "true"
  USE_WALG_RESTORE: "true"
  BACKUP_SCHEDULE: "0 1 * * *"       # Daily at 1 AM UTC
  BACKUP_NUM_TO_RETAIN: "14"          # Keep 14 daily backups

  # WAL archiving
  WALG_COMPRESSION_METHOD: "zstd"     # Better compression than lz4
  WALG_DELTA_MAX_STEPS: "6"           # Delta backups between full backups
  WALG_UPLOAD_CONCURRENCY: "4"        # Parallel upload streams
  WALG_DOWNLOAD_CONCURRENCY: "4"      # Parallel download for restore
  WALG_UPLOAD_DISK_CONCURRENCY: "4"   # Disk read concurrency

  # Clone configuration
  CLONE_AWS_ENDPOINT: "https://s3.us-east-1.amazonaws.com"
  CLONE_AWS_REGION: "us-east-1"
  CLONE_WALG_S3_PREFIX: "s3://my-pg-backups/$(CLONE_SCOPE)"
  CLONE_METHOD: "CLONE_WITH_WALG"
  CLONE_USE_WALG_RESTORE: "true"

استرداد نقطة في الوقت المناسب (PITR)

يسمح لك

PITR باستعادة قاعدة البيانات الخاصة بك إلى أي لحظة زمنية محددة - وهو أمر بالغ الأهمية للتعافي من حذف البيانات غير المقصود أو الفساد. يدعم مشغل Zalando PITR من خلال آلية الاستنساخ:

# Clone a cluster with PITR
apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
  name: pg-restored-cluster
  namespace: databases
spec:
  teamId: "platform"
  volume:
    size: 100Gi
    storageClass: ebs-gp3-postgres
  numberOfInstances: 3
  postgresql:
    version: "16"
  clone:
    cluster: "pg-production-cluster"
    timestamp: "2026-04-11T14:30:00+00:00"  # Restore to this exact moment
    s3_wal_path: "s3://my-pg-backups/wal/16/pg-production-cluster"
    s3_endpoint: "https://s3.us-east-1.amazonaws.com"
    s3_access_key_id: ""      # Use IAM role instead
    s3_secret_access_key: ""  # Use IAM role instead

عند تطبيق CRD، يقوم المشغل بتنفيذ الخطوات التالية:

  1. يبحث عن أحدث نسخة احتياطية أساسية قبل الطابع الزمني المستهدف
  2. يستعيد النسخة الاحتياطية الأساسية إلى الكبسولة الأساسية الجديدة لـ StatefulSet
  3. يعيد تشغيل مقاطع WAL حتى الطابع الزمني المحدد
  4. يفتح قاعدة البيانات لعمليات القراءة والكتابة
  5. يقوم بإعداد النسخ المتماثل المتدفق إلى كبسولات النسخ المتماثلة

مجموعة الاستعداد للتعافي من الكوارث

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

# Standby cluster in a different region
apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
  name: pg-standby-eu
  namespace: databases
spec:
  teamId: "platform"
  volume:
    size: 100Gi
    storageClass: managed-premium-postgres
  numberOfInstances: 2
  postgresql:
    version: "16"
  standby:
    standby_host: "pg-production-cluster.databases.svc.cluster.local"
    standby_port: "5432"
    # Alternative: replicate from S3 WAL archive
    # s3_wal_path: "s3://my-pg-backups/wal/16/pg-production-cluster"
  enableConnectionPooler: true
  enableReplicaConnectionPooler: true

لترقية مجموعة احتياطية إلى مجموعة أساسية مستقلة (أثناء التعافي من الكوارث)، ما عليك سوى إزالة قسمstandbyمن CRD وتطبيق:

# Edit the standby cluster CRD to remove standby section
kubectl patch postgresql pg-standby-eu -n databases --type json \
  -p '[{"op": "remove", "path": "/spec/standby"}]'

# The operator will promote the standby to primary
# Update your application DNS/service mesh to point to the new primary
مراقبة

مع Prometheus وGrafana

المراقبة الشاملة غير قابلة للتفاوض لعمليات نشر PostgreSQL للإنتاج. يدعم مشغل Zalando تصدير مقاييس Prometheus عبر السيارة الجانبيةpostgres_exporter. فيما يلي كيفية إعداد مجموعة مراقبة كاملة:

ServiceMonitor لـ Prometheus

# ServiceMonitor for PostgreSQL metrics
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: postgres-monitor
  namespace: databases
  labels:
    team: platform
    release: prometheus
spec:
  selector:
    matchLabels:
      team: platform
  namespaceSelector:
    matchNames:
    - databases
  endpoints:
  - port: exporter
    interval: 15s
    scrapeTimeout: 10s
    path: /metrics
    relabelings:
    - sourceLabels: [__meta_kubernetes_pod_label_spilo_role]
      targetLabel: role
    - sourceLabels: [__meta_kubernetes_pod_label_cluster_name]
      targetLabel: cluster
---
# PodMonitor alternative (scrapes pods directly)
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: postgres-pod-monitor
  namespace: databases
spec:
  selector:
    matchLabels:
      application: spilo
  podMetricsEndpoints:
  - port: exporter
    interval: 15s
    path: /metrics

المقاييس الرئيسية لمراقبة

هذه هي مقاييس PostgreSQL الأكثر أهمية التي يجب تتبعها في لوحات معلومات Grafana:

  • pg_stat_replication_lag— تأخر النسخ بالبايت والثواني. تنبيه إذا تجاوز التأخر حد RPO الخاص بك.
  • pg_stat_activity_count— الاتصالات النشطة حسب الحالة. تنبيه بشأن استنفاد تجمع الاتصال.
  • pg_stat_database_tup_fetched/returned/inserted/updated/deleted— مقاييس إنتاجية الاستعلام.
  • pg_stat_bgwriter_buffers_checkpoint/clean/backend— كفاءة إدارة المخزن المؤقت.
  • pg_database_size_bytes— نمو حجم قاعدة البيانات بمرور الوقت لتخطيط السعة.
  • pg_locks_count— قفل التنافس. التنبيه على أقفال الانتظار المفرطة.
  • pg_stat_statements_calls/mean_time— الاستعلام عن إحصائيات الأداء من أجل التحسين.
  • Patroni_postgres_running— الحالة الصحية لباتروني (1 = قيد التشغيل، 0 = لأسفل).
  • المستفيد— أي جراب هو الأساسي الحالي (1 = رئيسي، 0 = نسخة متماثلة).
  • pg_up— مسبار توفر PostgreSQL الأساسي.

قواعد التنبيه

# PrometheusRule for PostgreSQL alerts
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: postgres-alerts
  namespace: databases
spec:
  groups:
  - name: postgresql.rules
    rules:
    - alert: PostgreSQLDown
      expr: pg_up == 0
      for: 1m
      labels:
        severity: critical
      annotations:
        summary: "PostgreSQL instance {{ $labels.instance }} is down"
    - alert: PostgreSQLReplicationLag
      expr: pg_stat_replication_pg_wal_lsn_diff > 100000000
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "Replication lag is {{ $value }} bytes on {{ $labels.instance }}"
    - alert: PostgreSQLHighConnections
      expr: sum(pg_stat_activity_count) by (instance) > 180
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "{{ $value }} active connections on {{ $labels.instance }}"
    - alert: PostgreSQLDeadlocks
      expr: rate(pg_stat_database_deadlocks[5m]) > 0
      for: 1m
      labels:
        severity: warning
      annotations:
        summary: "Deadlocks detected on {{ $labels.datname }}"
    - alert: PatroniFailover
      expr: changes(patroni_master[5m]) > 0
      labels:
        severity: critical
      annotations:
        summary: "Patroni failover occurred in cluster {{ $labels.cluster }}"
دليل ضبط الإنتاج

يعد الضبط المناسب ضروريًا لاستخراج الحد الأقصى من الأداء من PostgreSQL على Kubernetes. يجب تعديل المعلمات التالية بناءً على حدود موارد الكبسولة وخصائص عبء العمل.

تكوين الذاكرة

# For a pod with 16GB memory limit:
postgresql:
  parameters:
    # shared_buffers: 25% of total memory
    shared_buffers: "4GB"

    # effective_cache_size: 75% of total memory
    # (tells planner how much OS cache to expect)
    effective_cache_size: "12GB"

    # work_mem: shared_buffers / (max_connections * 2)
    # Conservative to prevent OOM
    work_mem: "10MB"

    # maintenance_work_mem: 5-10% of total memory
    # Used for VACUUM, CREATE INDEX, ALTER TABLE
    maintenance_work_mem: "1GB"

    # temp_buffers: memory for temp tables per session
    temp_buffers: "32MB"

    # huge_pages: try to use huge pages (requires OS config)
    huge_pages: "try"

WAL وتكوين نقطة التفتيش

postgresql:
  parameters:
    # WAL settings
    wal_buffers: "64MB"           # 1/32 of shared_buffers, max 64MB
    wal_compression: "zstd"        # Compress WAL (PG 15+)
    max_wal_size: "8GB"            # Before forced checkpoint
    min_wal_size: "2GB"            # WAL disk reservation
    wal_level: "replica"           # Required for replication

    # Checkpoint settings
    checkpoint_completion_target: "0.9"  # Spread I/O over 90% of interval
    checkpoint_timeout: "15min"          # Max time between checkpoints

مخطط الاستعلام والإدخال/الإخراج

postgresql:
  parameters:
    # Cost parameters for SSD storage
    random_page_cost: "1.1"          # SSD: close to seq_page_cost
    seq_page_cost: "1.0"             # Sequential I/O baseline
    effective_io_concurrency: "200"   # Concurrent I/O for SSD

    # Planner behavior
    default_statistics_target: "200"  # More accurate statistics
    from_collapse_limit: 12           # JOIN planning threshold
    join_collapse_limit: 12           # JOIN planning threshold

    # Parallel queries
    max_parallel_workers_per_gather: "4"
    max_parallel_workers: "8"
    max_parallel_maintenance_workers: "4"
    parallel_tuple_cost: "0.01"
    parallel_setup_cost: "1000"
اتصال وتسجيل

postgresql:
  parameters:
    # Connection limits
    max_connections: "200"                   # Keep low, use PgBouncer
    superuser_reserved_connections: "5"       # Reserve for admin access

    # Logging for troubleshooting
    log_statement: "ddl"                     # Log DDL statements
    log_min_duration_statement: "500"         # Log queries > 500ms
    log_checkpoints: "on"                    # Log checkpoint activity
    log_connections: "off"                   # Too noisy in production
    log_disconnections: "off"                # Too noisy in production
    log_lock_waits: "on"                     # Log lock waits
    log_temp_files: "0"                      # Log all temp file usage
    log_autovacuum_min_duration: "1000"       # Log slow autovacuum

    # Statement timeouts
    statement_timeout: "60000"               # 60 second query timeout
    lock_timeout: "30000"                    # 30 second lock timeout
    idle_in_transaction_session_timeout: "600000"  # 10 min idle txn timeout
تحديثات

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

الإصدار الثانوي يقوم بترقية

تتم معالجة ترقيات الإصدار الثانوية (على سبيل المثال، 16.2 إلى 16.3) تلقائيًا بواسطة المشغل عند تحديث علامة صورة Spilo. يقوم المشغل بإجراء إعادة تشغيل متجددة:

# Update the operator configuration to use a new Spilo image
helm upgrade postgres-operator postgres-operator-charts/postgres-operator \
  --namespace postgres-operator \
  --set configGeneral.docker_image=ghcr.io/zalando/spilo-16:3.1-p1 \
  --reuse-values

# The operator will perform rolling updates:
# 1. Restart replicas one at a time
# 2. Failover the primary to a freshly updated replica
# 3. Restart the old primary (now a replica)
الإصدار الرئيسي

يقوم بترقية

تتطلب ترقيات الإصدار الرئيسي

(على سبيل المثال، PostgreSQL 15 إلى 16) تخطيطًا أكثر دقة. يدعم مشغل Zalando الترقيات الرئيسية الموضعية باستخدامpg_upgrade:

# Step 1: Update the CRD to the new major version
spec:
  postgresql:
    version: "16"  # Changed from "15"

# Step 2: The operator detects the version change and:
# a) Scales down the StatefulSet to 1 replica
# b) Runs pg_upgrade on the primary pod
# c) Scales back up to the desired numberOfInstances
# d) Replicas are rebuilt from the upgraded primary

# Step 3: Verify the upgrade
kubectl exec -it pg-production-cluster-0 -n databases -- \
  su postgres -c "psql -c 'SELECT version()'"

# Step 4: Run ANALYZE to update statistics after upgrade
kubectl exec -it pg-production-cluster-0 -n databases -- \
  su postgres -c "psql -c 'ANALYZE VERBOSE'"

اعتبارات مهمة للترقيات الرئيسية:

  • قم دائمًا بأخذ نسخة احتياطية جديدة قبل ترقية
  • اختبر الترقية على مجموعة مستنسخة أولاً
  • تتطلب الترقيات الرئيسية فترة توقف (عادةً من 5 إلى 30 دقيقة حسب حجم قاعدة البيانات)
  • قم بمراجعة ملاحظات إصدار PostgreSQL لكسر التغييرات
  • مراقبة تأخر النسخ المتماثل عن كثب بعد إعادة إنشاء النسخة المتماثلة
  • قم بتشغيلANALYZEعلى كافة قواعد البيانات لتجديد إحصائيات مخطط الاستعلام

أنماط التشغيل المتقدمة

النسخ الاحتياطية المنطقية

بالإضافة إلى النسخ الاحتياطية الفعلية لـ WAL-G، يدعم المشغل النسخ الاحتياطية المنطقية باستخدامpg_dump. تعد النسخ الاحتياطية المنطقية مفيدة لعمليات ترحيل الإصدارات المشتركة واستعادة الجدول الانتقائي:

# Enable logical backups in the operator configuration
helm upgrade postgres-operator postgres-operator-charts/postgres-operator \
  --namespace postgres-operator \
  --set configLogicalBackup.logical_backup_schedule="0 3 * * *" \
  --set configLogicalBackup.logical_backup_s3_bucket="my-pg-logical-backups" \
  --set configLogicalBackup.logical_backup_s3_region="us-east-1" \
  --set configLogicalBackup.logical_backup_s3_sse="AES256" \
  --reuse-values

# The operator creates a CronJob for each cluster that:
# 1. Connects to the primary PostgreSQL instance
# 2. Runs pg_dumpall (or pg_dump per database)
# 3. Compresses and uploads to S3

متغيرات بيئة الكبسولة المخصصة

يمكنك حقن متغيرات البيئة في كبسولات Spilo باستخدام ConfigMap. يعد هذا مفيدًا لتكوين WAL-G أو البرامج النصية المخصصة أو ضبط المعلمات على مستوى نظام التشغيل:

apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-pod-config
  namespace: databases
data:
  # Custom Spilo configurations
  SPILO_CONFIGURATION: |
    bootstrap:
      dcs:
        ttl: 30
        loop_wait: 10
        retry_timeout: 10
        maximum_lag_on_failover: 33554432
        postgresql:
          use_pg_rewind: true
          use_slots: true
          parameters:
            archive_mode: "on"
            archive_timeout: 1800s
  # Enable pg_stat_statements
  POSTGRESQL_SHARED_PRELOAD_LIBRARIES: "bg_mon,pg_stat_statements,pgextwlist,pg_auth_mon,set_user,timescaledb,pg_cron,pg_stat_kcache"
  # Cron jobs inside PostgreSQL
  ENABLE_PG_CRON: "true"

سياسات الشبكة للأمان

في الإنتاج، قم بتقييد الوصول إلى الشبكة إلى كبسولات PostgreSQL باستخدام Kubernetes NetworkPolicies:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: postgres-network-policy
  namespace: databases
spec:
  podSelector:
    matchLabels:
      application: spilo
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: app-namespace
    - podSelector:
        matchLabels:
          app: backend
    ports:
    - protocol: TCP
      port: 5432
    - protocol: TCP
      port: 8008   # Patroni REST API
  - from:
    - namespaceSelector:
        matchLabels:
          name: monitoring
    ports:
    - protocol: TCP
      port: 9187   # Prometheus exporter
  egress:
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0
    ports:
    - protocol: TCP
      port: 443    # S3/GCS/Azure for backups

استكشاف المشكلات الشائعة وإصلاحها

حتى مع التشغيل الآلي، تظهر مشكلات. فيما يلي المشاكل الأكثر شيوعًا وحلولها عند تشغيل PostgreSQL مع مشغل Zalando:

1. الجراب عالق في حالة انتظار

# Check events for the pod
kubectl describe pod pg-production-cluster-0 -n databases

# Common causes:
# - No nodes with matching tolerations/affinity
# - Insufficient CPU or memory on nodes
# - PVC cannot be provisioned (check StorageClass)

# Fix: Check node resources and storage availability
kubectl get nodes -o custom-columns=NAME:.metadata.name,CPU:.status.allocatable.cpu,MEM:.status.allocatable.memory
kubectl get pvc -n databases

2. تزايد تأخر النسخ

# Check replication status on the primary
kubectl exec -it pg-production-cluster-0 -n databases -- \
  su postgres -c "psql -c 'SELECT client_addr, state, sent_lsn, write_lsn, flush_lsn, replay_lsn, write_lag, flush_lag, replay_lag FROM pg_stat_replication'"

# Common causes:
# - Replica CPU/IO saturation
# - Network bandwidth limits
# - Long-running queries on replica blocking WAL replay
# - Insufficient wal_keep_size

# Fix: Check replica resources and cancel blocking queries
kubectl exec -it pg-production-cluster-1 -n databases -- \
  su postgres -c "psql -c 'SELECT pg_cancel_backend(pid) FROM pg_stat_activity WHERE state = \"active\" AND query_start < now() - interval \"5 minutes\"'"

3. عدم تشغيل تجاوز الفشل

# Check Patroni cluster status
kubectl exec -it pg-production-cluster-0 -n databases -- \
  su postgres -c "patronictl list"

# Check Patroni logs
kubectl logs pg-production-cluster-0 -n databases -c postgres | grep -i patroni

# Manual failover (if auto-failover is stuck)
kubectl exec -it pg-production-cluster-0 -n databases -- \
  su postgres -c "patronictl failover --candidate pg-production-cluster-1 --force"

4. فشل النسخ الاحتياطي

# Check WAL-G backup status
kubectl exec -it pg-production-cluster-0 -n databases -- \
  su postgres -c "envdir /run/etc/wal-e.d/env wal-g backup-list"

# Check backup CronJob logs
kubectl logs -l application=spilo,cluster-name=pg-production-cluster -n databases | grep -i wal-g

# Verify S3/GCS credentials
kubectl exec -it pg-production-cluster-0 -n databases -- \
  su postgres -c "envdir /run/etc/wal-e.d/env aws s3 ls s3://my-pg-backups/"
أفضل ممارسات أمان

يتطلب تأمين PostgreSQL على Kubernetes نهجًا دفاعيًا متعمقًا:

    تشفير
  • TLS— تمكين SSL لجميع اتصالات العميل. يمكن للمشغل توفير الشهادات تلقائيًا باستخدام مدير الشهادات.
  • الإدارة السرية- استخدم أسرار Kubernetes (أو مديري السرية الخارجيين مثل Vault) لبيانات اعتماد قاعدة البيانات. لا تقم مطلقًا بتخزين كلمات المرور في ConfigMaps.
  • RBAC— الحد من أذونات حساب خدمة المشغل. استخدم الوصول الأقل امتيازًا لمستخدمي قاعدة بيانات التطبيق.
  • NetworkPolicies- تقييد الاتصال من جراب إلى جراب كما هو موضح في القسم السابق.
  • pg_hba.conf— قم بتكوين المصادقة المستندة إلى المضيف لتقييد عناوين IP والمستخدمين الذين يمكنهم الاتصال.
  • تسجيل التدقيق— تمكين ملحقpgauditلتسجيل تدقيق SQL في البيئات المنظمة.
  • التخزين المشفر— استخدم فئات التخزين المشفرة (تشفير EBS، تشفير قرص Azure، وما إلى ذلك).
  • Pod Security Standards- قم بتشغيل pods Spilo باعتبارها غير جذر مع سياقات أمان مقيدة.
# Security-hardened CRD settings
spec:
  spiloRunAsUser: 101
  spiloRunAsGroup: 103
  spiloFSGroup: 103
  enableShmVolume: true
  patroni:
    pg_hba:
    - hostssl all all 0.0.0.0/0 md5
    - host    replication standby all md5
    - hostssl replication standby all md5
  postgresql:
    parameters:
      ssl: "on"
      ssl_min_protocol_version: "TLSv1.3"
      password_encryption: "scram-sha-256"
  additionalVolumes:
  - name: postgres-tls
    mountPath: /tls
    secret:
      secretName: pg-tls-cert
      defaultMode: 0640

تخطيط السعة والتحجيم

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

ذاكرةتطوير
عبء العملCPUتخزينمثيلات
500 م1Gi10Gi1
إنتاج صغير2 النوى8Gi50Gi SSD3
إنتاج متوسط4 النوى16Gi200Gi SSD3
إنتاج كبير8 النوى32جي500Gi SSD5
المؤسسة/التحليلات16+ النوى64Gi +1Ti + SSD5+

مثال النشر الشامل

دعونا نجمع كل شيء معًا من خلال النشر الكامل من البداية على مجموعة Kubernetes جديدة:

# Step 1: Create namespace and configure storage
kubectl create namespace databases
kubectl create namespace postgres-operator

# Step 2: Install the Zalando Postgres Operator
helm repo add postgres-operator-charts \
  https://opensource.zalando.com/postgres-operator/charts/postgres-operator
helm repo update

helm install postgres-operator postgres-operator-charts/postgres-operator \
  --namespace postgres-operator \
  --set configKubernetes.enable_pod_antiaffinity=true \
  --set configKubernetes.pod_environment_configmap=databases/postgres-pod-config

# Step 3: Create backup configuration
kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-pod-config
  namespace: databases
data:
  USE_WALG_BACKUP: "true"
  USE_WALG_RESTORE: "true"
  WALG_S3_PREFIX: "s3://my-pg-backups/\$(SCOPE)"
  BACKUP_SCHEDULE: "0 1 * * *"
  BACKUP_NUM_TO_RETAIN: "14"
EOF

# Step 4: Deploy the PostgreSQL cluster
kubectl apply -f - <<EOF
apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
  name: pg-app-cluster
  namespace: databases
  labels:
    team: platform
spec:
  teamId: "platform"
  volume:
    size: 50Gi
  numberOfInstances: 3
  enableConnectionPooler: true
  enableReplicaConnectionPooler: true
  users:
    app_user:
    - superuser
    - createdb
  databases:
    app_db: app_user
  postgresql:
    version: "16"
    parameters:
      shared_buffers: "2GB"
      work_mem: "64MB"
      effective_cache_size: "6GB"
  resources:
    requests:
      cpu: "2"
      memory: 8Gi
    limits:
      cpu: "4"
      memory: 16Gi
EOF

# Step 5: Wait for cluster readiness
kubectl wait --for=condition=Running postgresql/pg-app-cluster \
  -n databases --timeout=300s

# Step 6: Verify cluster status
kubectl get postgresql -n databases
kubectl get pods -n databases -l cluster-name=pg-app-cluster
kubectl get svc -n databases -l cluster-name=pg-app-cluster

# Step 7: Get connection credentials
export PGPASSWORD=$(kubectl get secret app-user.pg-app-cluster.credentials.postgresql.acid.zalan.do \
  -n databases -o jsonpath='{.data.password}' | base64 -d)

# Step 8: Connect and verify
kubectl run pg-client --rm -it --image=postgres:16 -n databases -- \
  psql -h pg-app-cluster-pooler -U app_user -d app_db -c "SELECT version();"
استنتاج

يقوم مشغل Zalando Postgres بتحويل PostgreSQL على Kubernetes من تحدي تشغيلي معقد إلى نشر آلي يمكن التحكم فيه. من خلال الاستفادة من Patroni لتجاوز الفشل القائم على الإجماع، وSpilo لصورة حاوية مضمنة بالبطاريات، وWAL-G للنسخ الاحتياطي والاسترداد المستمر، وPgBouncer لتجميع الاتصال الفعال، يمكنك الحصول على نظام أساسي لقاعدة بيانات على مستوى الإنتاج يعمل بشكل متسق عبر مجموعات AWS EKS وAzure AKS وGoogle GKE ومجموعات k3s المعدنية العارية.

النقاط الرئيسية من هذا الدليل هي:

  • أتمتة كل شيء- اسمح للمشغل بالتعامل مع إدارة StatefulSet وتجاوز الفشل وجدولة النسخ الاحتياطي. وينبغي أن يكون التدخل اليدوي هو الاستثناء.
  • راقب بقوة— انشر Prometheus وGrafana من اليوم الأول. إن تأخر النسخ المتماثل، وأعداد الاتصالات، وتنافس القفل هي إشارات الإنذار المبكر الخاصة بك.
  • التخطيط لمواجهة الكوارث— قم بتكوين النسخ الاحتياطية لـ WAL-G، واختبار PITR بانتظام، والحفاظ على مجموعة احتياطية لأحمال العمل الهامة.
  • قم بضبط عبء العمل الخاص بك— معلمات PostgreSQL الافتراضية متحفظة. اضبط إعدادات المخازن المؤقتة المشتركة وذاكرة العمل ونقاط التفتيش بناءً على تخصيص الموارد وأنماط الاستعلام.
  • آمن بشكل افتراضي— قم بتمكين TLS، واستخدم مصادقة SCRAM-SHA-256، وتقييد الوصول إلى الشبكة، وتشفير التخزين أثناء عدم النشاط.
  • اختبار الترقيات— قم دائمًا باستنساخ مجموعتك واختبار ترقيات الإصدار الرئيسية قبل تطبيقها على الإنتاج.

مع هذا الأساس الشامل، أنت مجهز جيدًا لنشر وتشغيل مجموعات PostgreSQL المتوفرة للغاية على أي منصة Kubernetes، مما يخدم التطبيقات التي تتطلب الموثوقية والأداء وتكامل البيانات على نطاق واسع.