פריסת מסד נתונים של PostgreSQL עם זמינות גבוהה ב-GKE

PostgreSQL הוא מסד נתונים רלציוני של אובייקטים בקוד פתוח, שידוע במהימנות שלו ובתקינות נתונים. היא תואמת ל-ACID ותומכת במפתחות זרים, בצירופים, בתצוגות, בטריגרים ובפרוצדורות מאוחסנות.

המסמך הזה מיועד לאדמינים של מסדי נתונים, לארכיטקטים של ענן ולמומחי תפעול שרוצים לפרוס טופולוגיה של PostgreSQL עם זמינות גבוהה ב-Google Kubernetes Engine ‏ (GKE).

מטרות

במדריך הזה תלמדו איך:

  • איך משתמשים ב-Terraform כדי ליצור אשכול GKE אזורי.
  • פריסת מסד נתונים של PostgreSQL עם זמינות גבוהה.
  • הגדרת מעקב אחר אפליקציית PostgreSQL.
  • ביצוע שדרוגים של מסד נתונים של PostgreSQL ואשכול GKE.
  • סימולציה של שיבוש באשכול ומעבר לגיבוי בעותק של PostgreSQL.
  • מבצעים גיבוי ושחזור של מסד הנתונים של PostgreSQL.

ארכיטקטורה

בקטע הזה מתוארת הארכיטקטורה של הפתרון שתבנו במדריך הזה.

תקצו שני אשכולות GKE באזורים שונים: אשכול ראשי ואשכול גיבוי. במדריך הזה, האשכול הראשי נמצא באזור us-central1 והאשכול לגיבוי נמצא באזור us-west1. הארכיטקטורה הזו מאפשרת להקצות מסד נתונים של PostgreSQL עם זמינות גבוהה ולבדוק את תוכנית ההתאוששות מאסון (DR), כמו שמתואר בהמשך במדריך הזה.

באשכול המקור, תשתמשו בתרשים Helm ‏(bitnami/postgresql-ha) כדי להגדיר אשכול PostgreSQL עם זמינות גבוהה.

תרשים שמציג ארכיטקטורה לדוגמה של אשכול PostgreSQL עם זמינות גבוהה.
איור 1: דוגמה לארכיטקטורה של אשכול PostgreSQL עם זמינות גבוהה.

עלויות

במסמך הזה משתמשים ברכיבים הבאים של Google Cloud, והשימוש בהם כרוך בתשלום:

כדי להעריך את ההוצאות בהתאם לתחזית השימוש שלכם, אתם יכולים להיעזר במחשבון העלויות.

משתמשים חדשים של Google Cloud ? יכול להיות שאתם זכאים לתקופת ניסיון בחינם.

כשמסיימים את המשימות שמתוארות במסמך הזה אפשר למחוק את המשאבים שיצרתם כדי להימנע מחיובים נוספים. מידע נוסף זמין בקטע הסרת המשאבים.

לפני שמתחילים

הגדרת הפרויקט

  1. נכנסים לחשבון Google Cloud . אם אתם משתמשים חדשים ב- Google Cloud, צרו חשבון כדי שתוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.
  2. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Roles required to create a project

    To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Enable the Google Kubernetes Engine, Backup for GKE, Artifact Registry, Compute Engine, and IAM APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  5. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Roles required to create a project

    To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the Google Kubernetes Engine, Backup for GKE, Artifact Registry, Compute Engine, and IAM APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

הגדרת תפקידים

  1. מעניקים תפקידים לחשבון המשתמש. מריצים את הפקודה הבאה לכל אחד מהתפקידים הבאים ב-IAM: roles/storage.objectViewer, roles/logging.logWriter, roles/artifactregistry.Admin, roles/container.clusterAdmin, roles/container.serviceAgent, roles/serviceusage.serviceUsageAdmin, roles/iam.serviceAccountAdmin

    gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE

    מחליפים את מה שכתוב בשדות הבאים:

    • PROJECT_ID: מזהה הפרויקט.
    • USER_IDENTIFIER: המזהה של חשבון המשתמש . לדוגמה, myemail@example.com.
    • ROLE: תפקיד ה-IAM שאתם מקצים לחשבון המשתמש.

מגדירים את הסביבה

במדריך הזה משתמשים ב-Cloud Shell כדי לנהל משאבים שמתארחים ב-Google Cloud. ב-Cloud Shell מותקן מראש התוכנה שדרושה לכם במדריך הזה, כולל Docker,‏ kubectl,‏ ה-CLI של gcloud,‏ Helm ו-Terraform.

כדי להשתמש ב-Cloud Shell להגדרת הסביבה:

  1. מפעילים סשן של Cloud Shell מ Google Cloud המסוף. לשם כך, לוחצים על Activate Cloud Shell (הפעלת Cloud Shell) בGoogle Cloud מסוף.סמל ההפעלה של Cloud Shell סשן יופעל בחלונית התחתונה של Google Cloud המסוף.

  2. מגדירים משתני סביבה.

    export PROJECT_ID=PROJECT_ID
    export SOURCE_CLUSTER=cluster-db1
    export REGION=us-central1
    

    מחליפים את הערכים הבאים:

  3. מגדירים את משתני הסביבה שמוגדרים כברירת מחדל.

    gcloud config set project PROJECT_ID
    
  4. משכפלים את מאגר המקורות של הקוד.

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    
  5. עוברים לספריית העבודה.

    cd kubernetes-engine-samples/databases/gke-stateful-postgres
    

יצירת תשתית האשכול

בקטע הזה, מריצים סקריפט Terraform כדי ליצור ענן וירטואלי פרטי (VPC) בהתאמה אישית, מאגר Artifact Registry לאחסון תמונות PostgreSQL ושני אשכולות אזוריים של GKE. אשכול אחד יופעל ב-us-central1 והאשכול השני לגיבוי יופעל ב-us-west1.

כדי ליצור את האשכול, מבצעים את השלבים הבאים:

טייס אוטומטי

ב-Cloud Shell, מריצים את הפקודות הבאות:

terraform -chdir=terraform/gke-autopilot init
terraform -chdir=terraform/gke-autopilot apply -var project_id=$PROJECT_ID

כשמופיעה בקשה, כותבים yes.

הסבר על התצורה של Terraform

קובצי ההגדרות של Terraform יוצרים את המשאבים הבאים כדי לפרוס את התשתית:

  • יוצרים מאגר ב-Artifact Registry לאחסון קובצי האימג' של Docker.
    resource "google_artifact_registry_repository" "main" {
      location      = "us"
      repository_id = "main"
      format        = "DOCKER"
      project       = var.project_id
    }
  • יוצרים את רשת ה-VPC והתת-רשת לממשק הרשת של המכונה הווירטואלית.
    module "gcp-network" {
      source  = "terraform-google-modules/network/google"
      version = "< 8.0.0"
    
      project_id   = var.project_id
      network_name = "vpc-gke-postgresql"
    
      subnets = [
        {
          subnet_name           = "snet-gke-postgresql-us-central1"
          subnet_ip             = "10.0.0.0/17"
          subnet_region         = "us-central1"
          subnet_private_access = true
        },
        {
          subnet_name           = "snet-gke-postgresql-us-west1"
          subnet_ip             = "10.0.128.0/17"
          subnet_region         = "us-west1"
          subnet_private_access = true
        },
      ]
    
      secondary_ranges = {
        ("snet-gke-postgresql-us-central1") = [
          {
            range_name    = "ip-range-pods-db1"
            ip_cidr_range = "192.168.0.0/18"
          },
          {
            range_name    = "ip-range-svc-db1"
            ip_cidr_range = "192.168.64.0/18"
          },
        ],
        ("snet-gke-postgresql-us-west1") = [
          {
            range_name    = "ip-range-pods-db2"
            ip_cidr_range = "192.168.128.0/18"
          },
          {
            range_name    = "ip-range-svc-db2"
            ip_cidr_range = "192.168.192.0/18"
          },
        ]
      }
    }
    
    output "network_name" {
      value = module.gcp-network.network_name
    }
    
    output "primary_subnet_name" {
      value = module.gcp-network.subnets_names[0]
    }
    
    output "secondary_subnet_name" {
      value = module.gcp-network.subnets_names[1]
    }
  • יוצרים אשכול GKE ראשי.

    ‫Terraform יוצר אשכול פרטי באזור us-central1 ומפעיל את הגיבוי ל-GKE לצורך תוכנית התאוששות מאסון (DR) ואת שירות מנוהל ל-Prometheus לצורך מעקב אחרי האשכול.

    שירות מנוהל ל-Prometheus נתמך רק באשכולות של Autopilot שפועלת בהם GKE מגרסה 1.25 ואילך.

    module "gke-db1-autopilot" {
      source                          = "../modules/beta-autopilot-private-cluster"
      project_id                      = var.project_id
      name                            = "cluster-db1"
      kubernetes_version              = "1.25" # Will be ignored if use "REGULAR" release_channel
      region                          = "us-central1"
      regional                        = true
      zones                           = ["us-central1-a", "us-central1-b", "us-central1-c"]
      network                         = module.network.network_name
      subnetwork                      = module.network.primary_subnet_name
      ip_range_pods                   = "ip-range-pods-db1"
      ip_range_services               = "ip-range-svc-db1"
      horizontal_pod_autoscaling      = true
      release_channel                 = "RAPID" # Default version is 1.22 in REGULAR. GMP on Autopilot requires V1.25 via var.kubernetes_version
      enable_vertical_pod_autoscaling = true
      enable_private_endpoint         = false
      enable_private_nodes            = true
      master_ipv4_cidr_block          = "172.16.0.0/28"
      create_service_account          = false
    }

  • יוצרים אשכול גיבוי באזור us-west1 לשחזור במקרה של אסון.

    module "gke-db2-autopilot" {
      source                          = "../modules/beta-autopilot-private-cluster"
      project_id                      = var.project_id
      name                            = "cluster-db2"
      kubernetes_version              = "1.25" # Will be ignored if use "REGULAR" release_channel
      region                          = "us-west1"
      regional                        = true
      zones                           = ["us-west1-a", "us-west1-b", "us-west1-c"]
      network                         = module.network.network_name
      subnetwork                      = module.network.secondary_subnet_name
      ip_range_pods                   = "ip-range-pods-db2"
      ip_range_services               = "ip-range-svc-db2"
      horizontal_pod_autoscaling      = true
      release_channel                 = "RAPID" # Default version is 1.22 in REGULAR. GMP on Autopilot requires V1.25 via var.kubernetes_version
      enable_vertical_pod_autoscaling = true
      enable_private_endpoint         = false
      enable_private_nodes            = true
      master_ipv4_cidr_block          = "172.16.0.16/28"
      create_service_account          = false
    }

רגילה

ב-Cloud Shell, מריצים את הפקודות הבאות:

terraform -chdir=terraform/gke-standard init
terraform -chdir=terraform/gke-standard apply -var project_id=$PROJECT_ID

כשמופיעה בקשה, כותבים yes.

הסבר על התצורה של Terraform

קובצי התצורה של Terraform יוצרים את המשאבים הבאים כדי לפרוס את התשתית:

  • יוצרים מאגר ב-Artifact Registry לאחסון קובצי האימג' של Docker.
    resource "google_artifact_registry_repository" "main" {
      location      = "us"
      repository_id = "main"
      format        = "DOCKER"
      project       = var.project_id
    }
    resource "google_artifact_registry_repository_iam_binding" "binding" {
      provider   = google-beta
      project    = google_artifact_registry_repository.main.project
      location   = google_artifact_registry_repository.main.location
      repository = google_artifact_registry_repository.main.name
      role       = "roles/artifactregistry.reader"
      members = [
        "serviceAccount:${module.gke-db1.service_account}",
      ]
    }
  • יוצרים את רשת ה-VPC והתת-רשת לממשק הרשת של המכונה הווירטואלית.
    module "gcp-network" {
      source  = "terraform-google-modules/network/google"
      version = "< 8.0.0"
    
      project_id   = var.project_id
      network_name = "vpc-gke-postgresql"
    
      subnets = [
        {
          subnet_name           = "snet-gke-postgresql-us-central1"
          subnet_ip             = "10.0.0.0/17"
          subnet_region         = "us-central1"
          subnet_private_access = true
        },
        {
          subnet_name           = "snet-gke-postgresql-us-west1"
          subnet_ip             = "10.0.128.0/17"
          subnet_region         = "us-west1"
          subnet_private_access = true
        },
      ]
    
      secondary_ranges = {
        ("snet-gke-postgresql-us-central1") = [
          {
            range_name    = "ip-range-pods-db1"
            ip_cidr_range = "192.168.0.0/18"
          },
          {
            range_name    = "ip-range-svc-db1"
            ip_cidr_range = "192.168.64.0/18"
          },
        ],
        ("snet-gke-postgresql-us-west1") = [
          {
            range_name    = "ip-range-pods-db2"
            ip_cidr_range = "192.168.128.0/18"
          },
          {
            range_name    = "ip-range-svc-db2"
            ip_cidr_range = "192.168.192.0/18"
          },
        ]
      }
    }
    
    output "network_name" {
      value = module.gcp-network.network_name
    }
    
    output "primary_subnet_name" {
      value = module.gcp-network.subnets_names[0]
    }
    
    output "secondary_subnet_name" {
      value = module.gcp-network.subnets_names[1]
    }
  • יוצרים אשכול GKE ראשי.

    ‫Terraform יוצר אשכול פרטי באזור us-central1 ומפעיל את הגיבוי ל-GKE לצורך תוכנית התאוששות מאסון (DR) ואת שירות מנוהל ל-Prometheus לצורך מעקב אחרי האשכול.

    module "gke-db1" {
      source                   = "../modules/beta-private-cluster"
      project_id               = var.project_id
      name                     = "cluster-db1"
      regional                 = true
      region                   = "us-central1"
      network                  = module.network.network_name
      subnetwork               = module.network.primary_subnet_name
      ip_range_pods            = "ip-range-pods-db1"
      ip_range_services        = "ip-range-svc-db1"
      create_service_account   = true
      enable_private_endpoint  = false
      enable_private_nodes     = true
      master_ipv4_cidr_block   = "172.16.0.0/28"
      network_policy           = true
      cluster_autoscaling = {
        "autoscaling_profile": "OPTIMIZE_UTILIZATION",
        "enabled" : true,
        "gpu_resources" : [],
        "min_cpu_cores" : 36,
        "min_memory_gb" : 144,
        "max_cpu_cores" : 48,
        "max_memory_gb" : 192,
      }
      monitoring_enable_managed_prometheus = true
      gke_backup_agent_config = true
    
      node_pools = [
        {
          name            = "pool-sys"
          autoscaling     = true
          min_count       = 1
          max_count       = 3
          max_surge       = 1
          max_unavailable = 0
          machine_type    = "e2-standard-4"
          node_locations  = "us-central1-a,us-central1-b,us-central1-c"
          auto_repair     = true
        },
        {
          name            = "pool-db"
          autoscaling     = true
          max_surge       = 1
          max_unavailable = 0
          machine_type    = "e2-standard-8"
          node_locations  = "us-central1-a,us-central1-b,us-central1-c"
          auto_repair     = true
        },
      ]
      node_pools_labels = {
        all = {}
        pool-db = {
          "app.stateful/component" = "postgresql"
        }
        pool-sys = {
          "app.stateful/component" = "postgresql-pgpool"
        }
      }
      node_pools_taints = {
        all = []
        pool-db = [
          {
            key    = "app.stateful/component"
            value  = "postgresql"
            effect = "NO_SCHEDULE"
          },
        ],
        pool-sys = [
          {
            key    = "app.stateful/component"
            value  = "postgresql-pgpool"
            effect = "NO_SCHEDULE"
          },
        ],
      }
      gce_pd_csi_driver = true
    }

  • יוצרים אשכול גיבוי באזור us-west1 לשחזור במקרה של אסון.

    module "gke-db2" {
      source                   = "../modules/beta-private-cluster"
      project_id               = var.project_id
      name                     = "cluster-db2"
      regional                 = true
      region                   = "us-west1"
      network                  = module.network.network_name
      subnetwork               = module.network.secondary_subnet_name
      ip_range_pods            = "ip-range-pods-db2"
      ip_range_services        = "ip-range-svc-db2"
      create_service_account   = false
      service_account          = module.gke-db1.service_account
      enable_private_endpoint  = false
      enable_private_nodes     = true
      master_ipv4_cidr_block   = "172.16.0.16/28"
      network_policy           = true
      cluster_autoscaling = {
        "autoscaling_profile": "OPTIMIZE_UTILIZATION",
        "enabled" : true,
        "gpu_resources" : [],
        "min_cpu_cores" : 10,
        "min_memory_gb" : 144,
        "max_cpu_cores" : 48,
        "max_memory_gb" : 192,
      }
      monitoring_enable_managed_prometheus = true
      gke_backup_agent_config = true
      node_pools = [
        {
          name            = "pool-sys"
          autoscaling     = true
          min_count       = 1
          max_count       = 3
          max_surge       = 1
          max_unavailable = 0
          machine_type    = "e2-standard-4"
          node_locations  = "us-west1-a,us-west1-b,us-west1-c"
          auto_repair     = true
        },
        {
          name            = "pool-db"
          autoscaling     = true
          max_surge       = 1
          max_unavailable = 0
          machine_type    = "e2-standard-8"
          node_locations  = "us-west1-a,us-west1-b,us-west1-c"
          auto_repair     = true
        },
      ]
      node_pools_labels = {
        all = {}
        pool-db = {
          "app.stateful/component" = "postgresql"
        }
        pool-sys = {
          "app.stateful/component" = "postgresql-pgpool"
        }
      }
      node_pools_taints = {
        all = []
        pool-db = [
          {
            key    = "app.stateful/component"
            value  = "postgresql"
            effect = "NO_SCHEDULE"
          },
        ],
        pool-sys = [
          {
            key    = "app.stateful/component"
            value  = "postgresql-pgpool"
            effect = "NO_SCHEDULE"
          },
        ],
      }
      gce_pd_csi_driver = true
    }

פריסת PostgreSQL באשכול

בקטע הזה תפרסו מופע של מסד נתונים של PostgreSQL להפעלה ב-GKE באמצעות תרשים Helm.

התקנת PostgreSQL

כדי להתקין את PostgreSQL באשכול, פועלים לפי השלבים הבאים.

  1. מגדירים גישה ל-Docker.

    gcloud auth configure-docker us-docker.pkg.dev
    
  2. מאכלסים את Artifact Registry בתמונות ה-Docker הנדרשות של PostgreSQL.

    ./scripts/gcr.sh bitnami/postgresql-repmgr 15.1.0-debian-11-r0
    ./scripts/gcr.sh bitnami/postgres-exporter 0.11.1-debian-11-r27
    ./scripts/gcr.sh bitnami/pgpool 4.3.3-debian-11-r28
    

    הסקריפט מעביר את תמונות Bitnami הבאות אל Artifact Registry כדי ש-Helm יתקין אותן:

    • postgresql-repmgr: פתרון האשכול הזה של PostgreSQL כולל את PostgreSQL replication manager (repmgr), כלי בקוד פתוח לניהול שכפול ומעבר לגיבוי בעת כשל באשכולות של PostgreSQL.
    • postgres-exporter: ‫PostgreSQL Exporter אוסף מדדים של PostgreSQL לשימוש ב-Prometheus.
    • pgpool: Pgpool-II הוא פרוקסי של PostgreSQL. הוא מספק איגום חיבורים ואיזון עומסים.
  3. מוודאים שהתמונות הנכונות מאוחסנות במאגר.

    gcloud artifacts docker images list us-docker.pkg.dev/$PROJECT_ID/main \
        --format="flattened(package)"
    

    הפלט אמור להיראות כך:

    ---
    image: us-docker.pkg.dev/[PROJECT_ID]/main/bitnami/pgpool
    ---
    image: us-docker.pkg.dev/[PROJECT_ID]/main/bitnami/postgres-exporter
    ---
    image: us-docker.pkg.dev/h[PROJECT_ID]/main/bitnami/postgresql-repmgr
    
  4. מגדירים kubectl גישה לשורת הפקודה לאשכול הראשי.

    gcloud container clusters get-credentials $SOURCE_CLUSTER \
    --location=$REGION --project=$PROJECT_ID
    
  5. יוצרים מרחב שמות.

    export NAMESPACE=postgresql
    kubectl create namespace $NAMESPACE
    
  6. אם אתם פורסים לאשכול Autopilot, צריך להגדיר הקצאת צמתים בשלושה אזורים. אפשר לדלג על השלב הזה אם אתם פורסים לאשכול רגיל.

    כברירת מחדל, Autopilot מקצה משאבים רק בשני אזורים. הפריסה שמוגדרת ב-prepareforha.yaml מבטיחה שהפעלת Autopilot תספק צמתים בשלושה אזורים באשכול, על ידי הגדרת הערכים הבאים:

    • replicas:3
    • podAntiAffinity עם requiredDuringSchedulingIgnoredDuringExecution ועם topologyKey: "topology.kubernetes.io/zone"
    kubectl -n $NAMESPACE apply -f scripts/prepareforha.yaml
    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: prepare-three-zone-ha
      labels:
        app: prepare-three-zone-ha
        app.kubernetes.io/name: postgresql-ha
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: prepare-three-zone-ha
          app.kubernetes.io/name: postgresql-ha
      template:
        metadata:
          labels:
            app: prepare-three-zone-ha
            app.kubernetes.io/name: postgresql-ha
        spec:
          affinity:
            podAntiAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
              - labelSelector:
                  matchExpressions:
                  - key: app
                    operator: In
                    values:
                    - prepare-three-zone-ha
                topologyKey: "topology.kubernetes.io/zone"
            nodeAffinity:
              preferredDuringSchedulingIgnoredDuringExecution:
              - preference:
                  matchExpressions:
                  - key: cloud.google.com/compute-class
                    operator: In
                    values:
                    - "Scale-Out"
                weight: 1
          nodeSelector:
            app.stateful/component: postgresql
          tolerations:
          - effect: NoSchedule
            key: app.stateful/component
            operator: Equal
            value: postgresql
          containers:
          - name: prepare-three-zone-ha
            image: busybox:latest
            command:
                - "/bin/sh"
                - "-c"
                - "while true; do sleep 3600; done"
            resources:
              limits:
                cpu: "500m"
                ephemeral-storage: "10Mi"
                memory: "0.5Gi"
              requests:
                cpu: "500m"
                ephemeral-storage: "10Mi"
                memory: "0.5Gi"
    
  7. מעדכנים את התלות ב-Helm.

    cd helm/postgresql-bootstrap
    helm dependency update
    
  8. בודקים ומאמתים את התרשימים ש-Helm יתקין.

    helm -n postgresql template postgresql . \
      --set global.imageRegistry="us-docker.pkg.dev/$PROJECT_ID/main"
    
  9. מתקינים את תרשים Helm.

    helm -n postgresql upgrade --install postgresql . \
        --set global.imageRegistry="us-docker.pkg.dev/$PROJECT_ID/main"
    

    הפלט אמור להיראות כך:

    NAMESPACE: postgresql
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    
  10. מוודאים שהרפליקות של PostgreSQL פועלות.

    kubectl get all -n $NAMESPACE
    

    הפלט אמור להיראות כך:

    NAME                                                          READY   STATUS    RESTARTS   AGE
    pod/postgresql-postgresql-bootstrap-pgpool-75664444cb-dkl24   1/1     Running   0          8m39s
    pod/postgresql-postgresql-ha-pgpool-6d86bf9b58-ff2bg          1/1     Running   0          8m39s
    pod/postgresql-postgresql-ha-postgresql-0                     2/2     Running   0          8m39s
    pod/postgresql-postgresql-ha-postgresql-1                     2/2     Running   0          8m39s
    pod/postgresql-postgresql-ha-postgresql-2                     2/2     Running   0          8m38s
    
    NAME                                                   TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)    AGE
    service/postgresql-postgresql-ha-pgpool                ClusterIP   192.168.99.236    <none>        5432/TCP   8m39s
    service/postgresql-postgresql-ha-postgresql            ClusterIP   192.168.90.20     <none>        5432/TCP   8m39s
    service/postgresql-postgresql-ha-postgresql-headless   ClusterIP   None              <none>        5432/TCP   8m39s
    service/postgresql-postgresql-ha-postgresql-metrics    ClusterIP   192.168.127.198   <none>        9187/TCP   8m39s
    
    NAME                                                     READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/postgresql-postgresql-bootstrap-pgpool   1/1     1            1           8m39s
    deployment.apps/postgresql-postgresql-ha-pgpool          1/1     1            1           8m39s
    
    NAME                                                                DESIRED   CURRENT   READY   AGE
    replicaset.apps/postgresql-postgresql-bootstrap-pgpool-75664444cb   1         1         1       8m39s
    replicaset.apps/postgresql-postgresql-ha-pgpool-6d86bf9b58          1         1         1       8m39s
    
    NAME                                                   READY   AGE
    statefulset.apps/postgresql-postgresql-ha-postgresql   3/3     8m39s
    

יצירת מערך נתונים לבדיקה

בקטע הזה תיצרו מסד נתונים וטבלה עם ערכים לדוגמה. מסד הנתונים משמש כמערך נתונים לבדיקה של תהליך המעבר לגיבוי שתיבדק בהמשך במדריך הזה.

  1. מתחברים למופע PostgreSQL.

    cd ../../
    ./scripts/launch-client.sh
    

    הפלט אמור להיראות כך:

    Launching Pod pg-client in the namespace postgresql ...
    pod/pg-client created
    waiting for the Pod to be ready
    Copying script files to the target Pod pg-client ...
    Pod: pg-client is healthy
    
  2. מתחילים סשן של מעטפת.

    kubectl exec -it pg-client -n postgresql -- /bin/bash
    
  3. יוצרים מסד נתונים וטבלה, ואז מוסיפים כמה שורות לבדיקה.

    psql -h $HOST_PGPOOL -U postgres -a -q -f /tmp/scripts/generate-db.sql
    
  4. בודקים את מספר השורות בכל טבלה.

    psql -h $HOST_PGPOOL -U postgres -a -q -f /tmp/scripts/count-rows.sql
    

    הפלט אמור להיראות כך:

    select COUNT(*) from tb01;
     count
    --------
     300000
    (1 row)
    
    select COUNT(*) from tb02;
     count
    --------
     300000
    (1 row)
    
  5. ליצור נתונים לבדיקה.

    export DB=postgres
    pgbench -i -h $HOST_PGPOOL -U postgres $DB -s 50
    

    הפלט אמור להיראות כך:

    dropping old tables...
    creating tables...
    generating data (client-side)...
    5000000 of 5000000 tuples (100%) done (elapsed 29.85 s, remaining 0.00 s)
    vacuuming...
    creating primary keys...
    done in 36.86 s (drop tables 0.00 s, create tables 0.01 s, client-side generate 31.10 s, vacuum 1.88 s, primary keys 3.86 s).
    
  6. יוצאים מ-Pod של לקוח postgres.

    exit
    

מעקב אחרי PostgreSQL

בקטע הזה מוצגים מדדים ואפשר להגדיר התראות למופע PostgreSQL. תשתמשו בשירות המנוהל של Google Cloud ל-Prometheus כדי לבצע מעקב והתראות.

הצגת המדדים

הפריסה של PostgreSQL כוללת קונטיינר postgresql-exporter sidecar. הקונטיינר הזה חושף נקודת קצה של /metrics. השירות המנוהל של Google Cloud ל-Prometheus מוגדר למעקב אחרי ה-Pods של PostgreSQL בנקודת הקצה הזו. אפשר לראות את המדדים האלה ב Google Cloud לוחות הבקרה במסוף.

במסוף Google Cloud יש כמה דרכים ליצור ולשמור את הגדרות מרכז הבקרה:

  • יצירה וייצוא: אתם יכולים ליצור מרכזי בקרה ישירות ב- Google Cloud console, ואז לייצא ולאחסן אותם במאגר המקורות של הקוד. כדי לעשות את זה, בסרגל הכלים של לוח הבקרה, פותחים את עורך ה-JSON ומורידים את קובץ ה-JSON של לוח הבקרה.
  • אחסון וייבוא: אפשר לייבא לוח בקרה מקובץ JSON. לשם כך, לוחצים על +יצירת לוח בקרה ומעלים את תוכן ה-JSON של לוח הבקרה באמצעות התפריט עורך JSON.

כדי להציג נתונים מהאפליקציה שלכם ב-PostgreSQL ומאשכול GKE, פועלים לפי השלבים הבאים:

  1. יוצרים את מרכזי הבקרה הבאים.

    cd monitoring
    gcloud monitoring dashboards create \
            --config-from-file=dashboard/postgresql-overview.json \
            --project=$PROJECT_ID
    gcloud monitoring dashboards create \
            --config-from-file dashboard/gke-postgresql.json \
            --project $PROJECT_ID
    
  2. במסוף Google Cloud , עוברים אל Cloud Monitoring Dashboard. כניסה ללוח הבקרה של Cloud Monitoring

  3. בוחרים באפשרות בהתאמה אישית מרשימת לוחות הבקרה. מוצגים מרכזי הבקרה הבאים:

    • סקירה כללית של PostgreSQL: מוצגים מדדים מהאפליקציה PostgreSQL, כולל זמן הפעולה של מסד הנתונים, הגודל של מסד הנתונים והחביון של העסקאות.
    • GKE PostgreSQL Cluster: הצגת מדדים מאשכול GKE ש-PostgreSQL פועל בו, כולל שימוש במעבד, שימוש בזיכרון וניצול נפח.
  4. כדי לבדוק את לוחות הבקרה שנוצרו, לוחצים על כל קישור.

הגדרת התראות

התראות מאפשרות לכם לדעת בזמן על בעיות באפליקציות, כדי שתוכלו לפתור אותן במהירות. אתם יכולים ליצור מדיניות התראות כדי לציין את הנסיבות שבהן תרצו לקבל התראה ואת האופן שבו תרצו לקבל אותה. אפשר גם ליצור ערוצי התראות שמאפשרים לבחור לאן יישלחו ההתראות.

בקטע הזה נשתמש ב-Terraform כדי להגדיר את ההתראות לדוגמה הבאות:

  • db_max_transaction: מעקב אחרי הפיגור המקסימלי של טרנזקציות בשניות. אם הערך גדול מ-10, תופעל התראה.
  • db_node_up: עוקב אחרי הסטטוס של Pods במסד הנתונים. הערך 0 מציין ש-Pod מושבת ומפעיל התראה.

כדי להגדיר התראות:

  1. הגדרת התראות באמצעות Terraform.

    EMAIL=YOUR_EMAIL
    cd alerting/terraform
    terraform init
    terraform plan -var project_id=$PROJECT_ID -var email_address=$EMAIL
    terraform apply -var project_id=$PROJECT_ID -var email_address=$EMAIL
    

    מחליפים את הערכים הבאים:

    • YOUR_EMAIL: כתובת האימייל שלכם.

    הפלט אמור להיראות כך :

    Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
    
  2. מתחברים ל-Pod של הלקוח.

    cd ../../../
    kubectl exec -it --namespace postgresql pg-client -- /bin/bash
    
  3. תכין בדיקת עומס כדי לבדוק את ההתראה db_max_transaction.

    pgbench -i -h $HOST_PGPOOL -U postgres -s 200 postgres
    

    הפלט אמור להיראות כך:

    dropping old tables...
    creating tables...
    generating data (client-side)...
    20000000 of 20000000 tuples (100%) done (elapsed 163.22 s, remaining 0.00 s)
    vacuuming...
    creating primary keys...
    done in 191.30 s (drop tables 0.14 s, create tables 0.01 s, client-side generate 165.62 s, vacuum 4.52 s, primary keys 21.00 s).
    

    ההתראה מופעלת ונשלח אימייל אל YOUR_EMAIL עם שורת נושא שמתחילה ב-‎[ALERT] Max Lag of transaction‎.

  4. במסוף Google Cloud , עוברים לדף Alert Policy.

    מעבר למדיניות ההתראות

  5. בוחרים באפשרות db_max_transaction מתוך רשימת כללי המדיניות. בתרשים אמורה להופיע עלייה חדה כתוצאה מבדיקת העומס, שחורגת מסף ההחזקה של 10 למדד Prometheus‏ pg_stat_activity_max_tx_duration/gauge.

  6. יוצאים מ-Pod של לקוח postgres.

    exit
    

ניהול שדרוגים של PostgreSQL ו-GKE

עדכוני גרסה ל-PostgreSQL ול-Kubernetes מתפרסמים בלוח זמנים קבוע. מומלץ לפעול לפי שיטות מומלצות תפעוליות כדי לעדכן את סביבת התוכנה באופן קבוע. כברירת מחדל, GKE מנהל את השדרוגים של האשכולות ומאגרי הצמתים.

שדרוג של PostgreSQL

בקטע הזה מוסבר איך לשדרג את הגרסה של PostgreSQL. במדריך הזה נשתמש בעדכון בהדרגה לשדרוג ה-Pods, כך שאף אחד מהם לא יושבת.

כדי לשדרג את הגרסה, פועלים לפי השלבים הבאים:

  1. מעבירים בדחיפה גרסה מעודכנת של תמונת postgresql-repmgr אל Artifact Registry. מגדירים את הגרסה החדשה (לדוגמה, postgresql-repmgr 15.1.0-debian-11-r1).

    NEW_IMAGE=us-docker.pkg.dev/$PROJECT_ID/main/bitnami/postgresql-repmgr:15.1.0-debian-11-r1
    ./scripts/gcr.sh bitnami/postgresql-repmgr 15.1.0-debian-11-r1
    
  2. מפעילים עדכון הדרגתי באמצעות kubectl.

    kubectl set image statefulset -n postgresql postgresql-postgresql-ha-postgresql postgresql=$NEW_IMAGE
    kubectl rollout restart statefulsets -n postgresql postgresql-postgresql-ha-postgresql
    kubectl rollout status statefulset -n postgresql postgresql-postgresql-ha-postgresql
    

    תראו ש-StatefulSet משלים עדכון הדרגתי, החל מהרפליקה עם המספר הסידורי הגבוה ביותר ועד לרפליקה עם המספר הסידורי הנמוך ביותר.

    הפלט אמור להיראות כך:

    Waiting for 1 pods to be ready...
    waiting for statefulset rolling update to complete 1 pods at revision postgresql-postgresql-ha-postgresql-5c566ccf49...
    Waiting for 1 pods to be ready...
    Waiting for 1 pods to be ready...
    waiting for statefulset rolling update to complete 2 pods at revision postgresql-postgresql-ha-postgresql-5c566ccf49...
    Waiting for 1 pods to be ready...
    Waiting for 1 pods to be ready...
    statefulset rolling update complete 3 pods at revision postgresql-postgresql-ha-postgresql-5c566ccf49...
    

תכנון שדרוגים של GKE באשכולות Standard

הקטע הזה רלוונטי אם אתם מפעילים אשכולות רגילים. אתם יכולים לנקוט צעדים יזומים ולהגדיר הגדרות כדי לצמצם את הסיכון ולשדרג את האשכול בצורה חלקה יותר כשאתם מפעילים שירותים עם שמירת מצב, כולל:

  • פועלים לפי השיטות המומלצות לשדרוג אשכולות ב-GKE. כדי לוודא שהשדרוגים יתבצעו במהלך חלון הזמנים לתחזוקה, צריך לבחור אסטרטגיית שדרוג מתאימה:

    • כדאי לבחור באפשרות שדרוגים בזמן שיא אם אופטימיזציה של העלויות חשובה לכם, ואם עומסי העבודה שלכם יכולים לעמוד בהשבתה מסודרת תוך פחות מ-60 דקות.
    • מומלץ לבחור באפשרות שדרוגים מסוג blue-green אם עומסי העבודה שלכם פחות סובלניים לשיבושים, ואם אתם מוכנים לספוג עלייה זמנית בעלויות בגלל שימוש גבוה יותר במשאבים.

    מידע נוסף זמין במאמר בנושא שדרוג אשכול שמריץ עומס עבודה עם שמירת מצב.

  • כדי למנוע שיבושים בשירות, כדאי להשתמש בשירות Recommender כדי לבדוק אם יש תובנות והמלצות לגבי הוצאה משימוש.

  • כדאי להשתמש בחלונות תחזוקה כדי לוודא שהשדרוגים יתבצעו בזמן שאתם רוצים. לפני חלון זמן לתחזוקה, חשוב לוודא שגיבויי מסד הנתונים בוצעו בהצלחה.

  • לפני שמאפשרים תעבורה לצמתים המשודרגים, משתמשים בבדיקות מוכנות ובדיקות פעילות כדי לוודא שהם מוכנים לתעבורה.

  • יוצרים בדיקות שמעריכות אם השכפול מסונכרן לפני אישור התנועה. אפשר לעשות את זה באמצעות סקריפטים בהתאמה אישית, בהתאם למורכבות ולגודל של מסד הנתונים.

אימות הזמינות של מסד הנתונים במהלך שדרוגים של אשכולות Standard

הקטע הזה רלוונטי אם אתם מפעילים אשכולות רגילים. כדי לוודא שהזמינות של PostgreSQL נשמרת במהלך השדרוגים, התהליך הכללי הוא יצירת תנועה אל מסד הנתונים של PostgreSQL במהלך תהליך השדרוג. לאחר מכן, משתמשים ב-pgbench כדי לבדוק שהמסד יכול להתמודד עם רמת בסיס של תנועה במהלך שדרוג, בהשוואה למצב שבו המסד זמין באופן מלא.

  1. מתחברים למופע PostgreSQL.

    ./scripts/launch-client.sh
    

    הפלט אמור להיראות כך:

    Launching Pod pg-client in the namespace postgresql ...
    pod/pg-client created
    waiting for the Pod to be ready
    Copying script files to the target Pod pg-client ...
    Pod: pg-client is healthy
    
  2. ב-Cloud Shell, נכנסים ל-Pod של הלקוח.

    kubectl exec -it -n postgresql pg-client -- /bin/bash
    
  3. מפעילים את pgbench .

    pgbench -i -h $HOST_PGPOOL -U postgres postgres
    
  4. כדי לקבל תוצאות בסיסיות שיעזרו לכם לוודא שאפליקציית PostgreSQL שלכם תישאר זמינה מאוד במהלך חלון הזמן של השדרוג, תוכלו להשתמש בפקודה הבאה. כדי לקבל תוצאת בסיס, מריצים בדיקה עם כמה חיבורים באמצעות כמה משימות (threads) למשך 30 שניות.

    pgbench -h $HOST_PGPOOL -U postgres postgres -c10 -j4 -T 30 -R 200
    

    הפלט אמור להיראות כך:

    pgbench (14.5)
    starting vacuum...end.
    transaction type: <builtin: TPC-B (sort of)>
    scaling factor: 1
    query mode: simple
    number of clients: 10
    number of threads: 4
    duration: 30 s
    number of transactions actually processed: 5980
    latency average = 7.613 ms
    latency stddev = 2.898 ms
    rate limit schedule lag: avg 0.256 (max 36.613) ms
    initial connection time = 397.804 ms
    tps = 201.955497 (without initial connection time)
    
  5. כדי להבטיח זמינות במהלך השדרוגים, אפשר ליצור עומס מסוים על מסד הנתונים ולוודא שאפליקציית PostgreSQL מספקת שיעור תגובה עקבי במהלך השדרוג. כדי לבצע את הבדיקה הזו, צריך ליצור עומס תנועה קל במסד הנתונים באמצעות הפקודה pgbench. הפקודה הבאה תפעל pgbench למשך שעה, תטרגט 200 TPS (עסקאות לשנייה) ותציג את קצב הבקשות כל 2 שניות.

    pgbench -h $HOST_PGPOOL -U postgres postgres --client=10 --jobs=4 --rate=200 --time=3600 --progress=2 --select-only
    

    כאשר:

    • --client: מספר הלקוחות המדומה, כלומר מספר הסשנים בו-זמנית במסד הנתונים.
    • --jobs: מספר ה-worker threads ב-pgbench. שימוש ביותר משרשור אחד יכול להיות שימושי במכונות עם כמה מעבדים. הלקוחות מחולקים באופן שווה ככל האפשר בין השרשורים הזמינים. ערך ברירת המחדל הוא 1.
    • --rate: השיעור מוצג בעסקאות לשנייה
    • --progress: הצגת דוח התקדמות כל sec שניות.

    הפלט אמור להיראות כך:

    pgbench (14.5)
    starting vacuum...end.
    progress: 5.0 s, 354.8 tps, lat 25.222 ms stddev 15.038
    progress: 10.0 s, 393.8 tps, lat 25.396 ms stddev 16.459
    progress: 15.0 s, 412.8 tps, lat 24.216 ms stddev 14.548
    progress: 20.0 s, 405.0 tps, lat 24.656 ms stddev 14.066
    
  6. במסוף Google Cloud , חוזרים למרכז הבקרה PostgreSQL Overview ב-Cloud Monitoring. שימו לב לעלייה החדה בתרשימים Connection per DB (חיבור לכל מסד נתונים) ו-Connection per Pod (חיבור לכל Pod).

  7. יוצאים מ-Pod הלקוח.

    exit
    
  8. מוחקים את ה-Pod של הלקוח.

    kubectl delete pod -n postgresql pg-client
    

סימולציה של הפרעה בשירות PostgreSQL

בקטע הזה נדמה שיבוש בשירות באחת מהרפליקות של PostgreSQL על ידי עצירה של שירות ניהול הרפליקציה. כך לא תהיה אפשרות להעביר תנועה אל העותקים המשוכפלים של ה-Pod ואל בדיקות הפעילות שלו.

  1. פותחים סשן חדש ב-Cloud Shell ומגדירים גישה לשורת הפקודה של האשכול הראשי kubectl.

    gcloud container clusters get-credentials $SOURCE_CLUSTER \
    --location=$REGION --project=$PROJECT_ID
    
  2. הצגת אירועי PostgreSQL שמופקים ב-Kubernetes.

    kubectl get events -n postgresql --field-selector=involvedObject.name=postgresql-postgresql-ha-postgresql-0 --watch
    
  3. בסשן הקודם של Cloud Shell, מדמים כשל בשירות על ידי עצירה של PostgreSQL repmgr.

    1. מצרפים את הסשן למאגר מסד הנתונים.

      kubectl exec -it -n $NAMESPACE postgresql-postgresql-ha-postgresql-0 -c postgresql -- /bin/bash
      
    2. מפסיקים את השירות באמצעות repmgr, ומסירים את נקודת הבדיקה ואת הארגומנט dry-run.

      export ENTRY='/opt/bitnami/scripts/postgresql-repmgr/entrypoint.sh'
      export RCONF='/opt/bitnami/repmgr/conf/repmgr.conf'
      $ENTRY repmgr -f $RCONF node service --action=stop --checkpoint
      

בתוך חמש שניות, בדיקת הפעילות שהוגדרה עבור מאגר PostgreSQL תתחיל להיכשל. הפעולה הזו חוזרת על עצמה כל עשר שניות, עד שמגיעים לסף הכישלון של שישה כישלונות. כשהערך failureThreshold מושג, הקונטיינר מופעל מחדש. אפשר להגדיר את הפרמטרים האלה כדי להקטין את הסבילות של בדיקת הפעילות, וכך להתאים את דרישות ה-SLO של הפריסה.

בזרם האירועים, תראו שהבדיקות של הפעילות והמוכנות של ה-Pod נכשלו, והודעה שלפיה צריך להפעיל מחדש את הקונטיינר. הפלט אמור להיראות כך:

0s          Normal    Killing                pod/postgresql-postgresql-ha-postgresql-0   Container postgresql failed liveness probe, will be restarted
0s          Warning   Unhealthy              pod/postgresql-postgresql-ha-postgresql-0   Readiness probe failed: psql: error: connection to server at "127.0.0.1", port 5432 failed: Connection refused...
0s          Normal    Pulled                 pod/postgresql-postgresql-ha-postgresql-0   Container image "us-docker.pkg.dev/psch-gke-dev/main/bitnami/postgresql-repmgr:14.5.0-debian-11-r10" already present on machine
0s          Normal    Created                pod/postgresql-postgresql-ha-postgresql-0   Created container postgresql
0s          Normal    Started                pod/postgresql-postgresql-ha-postgresql-0   Started container postgresql

היערכות להתאוששות מאסון

כדי לוודא שעומסי העבודה של הייצור יישארו זמינים במקרה של אירוע שגורם להפרעה בשירות, כדאי להכין תוכנית התאוששות מאסון (DR). מידע נוסף על תכנון התאוששות מאסון זמין במדריך לתכנון התאוששות מאסון.

אפשר להטמיע תוכנית התאוששות מאסון (DR) ל-Kubernetes בשני שלבים:

  • גיבוי כולל יצירת תמונת מצב של הסטטוס או הנתונים שלכם בנקודת זמן מסוימת לפני שמתרחש אירוע שגורם להפרעה בשירות.
  • שחזור כולל שחזור של המצב או הנתונים שלכם מעותק גיבוי אחרי אסון.

כדי לגבות ולשחזר את עומסי העבודה באשכולות GKE, אפשר להשתמש ב-Backup for GKE. אפשר להפעיל את השירות הזה באשכולות חדשים וקיימים. הפעולה הזו תפרוס סוכן של Backup for GKE שפועל באשכולות שלכם. הסוכן אחראי לתיעוד נתוני הגיבוי של ההגדרות והנפח, ולתיאום השחזור.

אפשר להגדיר את היקף הגיבויים והשחזורים לכל האשכול, למרחב שמות או לאפליקציה (מוגדר באמצעות כלים לבחירה כמו matchLabels).

תרחיש לדוגמה של גיבוי ושחזור ב-PostgreSQL

בדוגמה שבקטע הזה מוסבר איך לבצע פעולת גיבוי ושחזור בהיקף האפליקציה באמצעות ProtectedApplication Custom Resource.

בתרשים הבא מוצגים משאבי הרכיבים ב-ProtectedApplication, כלומר StatefulSet שמייצג את האפליקציה postgresql-ha ופריסה של pgpool, שמשתמשים באותה תווית (app.kubernetes.io/name: postgresql-ha).

דיאגרמה שמציגה פתרון לדוגמה לגיבוי ושחזור של אשכול PostgreSQL עם זמינות גבוהה.
איור 2: דוגמה לפתרון גיבוי ושחזור עבור אשכול PostgreSQL עם זמינות גבוהה.

כדי להתכונן לגיבוי ולשחזור של עומס העבודה של PostgreSQL, פועלים לפי השלבים הבאים:

  1. מגדירים את משתני הסביבה. בדוגמה הזו תשתמשו ב-ProtectedApplication כדי לשחזר את עומס העבודה של PostgreSQL ואת נפחי האחסון שלו מאשכול GKE המקור (us-central1), ואז תשחזרו לאשכול GKE אחר באזור אחר (us-west1).

    export SOURCE_CLUSTER=cluster-db1
    export TARGET_CLUSTER=cluster-db2
    export REGION=us-central1
    export DR_REGION=us-west1
    export NAME_PREFIX=g-db-protected-app
    export BACKUP_PLAN_NAME=$NAME_PREFIX-bkp-plan-01
    export BACKUP_NAME=bkp-$BACKUP_PLAN_NAME
    export RESTORE_PLAN_NAME=$NAME_PREFIX-rest-plan-01
    export RESTORE_NAME=rest-$RESTORE_PLAN_NAME
    
  2. מוודאים שהגיבוי ל-GKE מופעל באשכולות. הוא אמור להיות מופעל כבר כחלק מהגדרת Terraform שביצעתם קודם.

    gcloud container clusters describe $SOURCE_CLUSTER \
        --project=$PROJECT_ID  \
        --location=$REGION \
        --format='value(addonsConfig.gkeBackupAgentConfig)'
    

    אם הגיבוי ל-GKE מופעל, הפלט של הפקודה יציג enabled=True.

הגדרת תוכנית גיבוי וביצוע שחזור

גיבוי ל-GKE מאפשר ליצור תוכנית גיבוי כמשימת cron. תוכנית גיבוי מכילה הגדרת גיבוי, כולל אשכול המקור, בחירת עומסי העבודה לגיבוי והאזור שבו מאוחסנים פריטי הגיבוי שנוצרו במסגרת התוכנית הזו.

כדי לבצע גיבוי ושחזור, פועלים לפי השלבים הבאים:

  1. מאמתים את הסטטוס של ProtectedApplication ב-cluster-db1.

    kubectl get ProtectedApplication -A
    

    הפלט אמור להיראות כך:

    NAMESPACE    NAME            READY TO BACKUP
    postgresql   postgresql-ha   true
    
  2. יוצרים תוכנית גיבוי ל-ProtectedApplication.

    export NAMESPACE=postgresql
    export PROTECTED_APP=$(kubectl get ProtectedApplication -n $NAMESPACE | grep -v 'NAME' | awk '{ print $1 }')
    
    gcloud beta container backup-restore backup-plans create $BACKUP_PLAN_NAME \
    --project=$PROJECT_ID \
    --location=$DR_REGION \
    --cluster=projects/$PROJECT_ID/locations/$REGION/clusters/$SOURCE_CLUSTER \
    --selected-applications=$NAMESPACE/$PROTECTED_APP \
    --include-secrets \
    --include-volume-data \
    --cron-schedule="0 3 * * *" \
    --backup-retain-days=7 \
    --backup-delete-lock-days=0
    
  3. יצירת גיבוי באופן ידני.

    gcloud beta container backup-restore backups create $BACKUP_NAME \
    --project=$PROJECT_ID \
    --location=$DR_REGION \
    --backup-plan=$BACKUP_PLAN_NAME \
    --wait-for-completion
    
  4. מגדירים תוכנית שחזור.

    gcloud beta container backup-restore restore-plans create $RESTORE_PLAN_NAME \
      --project=$PROJECT_ID \
      --location=$DR_REGION \
      --backup-plan=projects/$PROJECT_ID/locations/$DR_REGION/backupPlans/$BACKUP_PLAN_NAME \
      --cluster=projects/$PROJECT_ID/locations/$DR_REGION/clusters/$TARGET_CLUSTER \
      --cluster-resource-conflict-policy=use-existing-version \
      --namespaced-resource-restore-mode=delete-and-restore \
      --volume-data-restore-policy=restore-volume-data-from-backup \
      --selected-applications=$NAMESPACE/$PROTECTED_APP \
      --cluster-resource-scope-selected-group-kinds="storage.k8s.io/StorageClass","scheduling.k8s.io/PriorityClass"
    
  5. משחזרים מהגיבוי.

    gcloud beta container backup-restore restores create $RESTORE_NAME \
      --project=$PROJECT_ID \
      --location=$DR_REGION \
      --restore-plan=$RESTORE_PLAN_NAME \
      --backup=projects/$PROJECT_ID/locations/$DR_REGION/backupPlans/$BACKUP_PLAN_NAME/backups/$BACKUP_NAME \
      --wait-for-completion
    

אימות השחזור של האשכול

כדי לוודא שבאשכול המשוחזר יש את כל משאבי ה-Pod,‏ PersistentVolume ו-StorageClass הצפויים, פועלים לפי השלבים הבאים:

  1. מגדירים kubectl גישה לשורת הפקודה לאשכול הגיבוי cluster-db2.

    gcloud container clusters get-credentials $TARGET_CLUSTER --location $DR_REGION --project $PROJECT_ID
    
  2. מוודאים שה-StatefulSet מוכן עם 3/3 פודים.

    kubectl get all -n $NAMESPACE
    

    הפלט אמור להיראות כך:

    NAME                                                   READY   STATUS    RESTARTS        AGE
    pod/postgresql-postgresql-ha-pgpool-778798b5bd-k2q4b   1/1     Running   0               4m49s
    pod/postgresql-postgresql-ha-postgresql-0              2/2     Running   2 (4m13s ago)   4m49s
    pod/postgresql-postgresql-ha-postgresql-1              2/2     Running   0               4m49s
    pod/postgresql-postgresql-ha-postgresql-2              2/2     Running   0               4m49s
    
    NAME                                                   TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)    AGE
    service/postgresql-postgresql-ha-pgpool                ClusterIP   192.168.241.46    <none>        5432/TCP   4m49s
    service/postgresql-postgresql-ha-postgresql            ClusterIP   192.168.220.20    <none>        5432/TCP   4m49s
    service/postgresql-postgresql-ha-postgresql-headless   ClusterIP   None              <none>        5432/TCP   4m49s
    service/postgresql-postgresql-ha-postgresql-metrics    ClusterIP   192.168.226.235   <none>        9187/TCP   4m49s
    
    NAME                                              READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/postgresql-postgresql-ha-pgpool   1/1     1            1           4m49s
    
    NAME                                                         DESIRED   CURRENT   READY   AGE
    replicaset.apps/postgresql-postgresql-ha-pgpool-778798b5bd   1         1         1       4m49s
    
    NAME                                                   READY   AGE
    statefulset.apps/postgresql-postgresql-ha-postgresql   3/3     4m49s
    
  3. מוודאים שכל ה-Pods במרחב השמות postgres פועלים.

    kubectl get pods -n $NAMESPACE
    

    הפלט אמור להיראות כך:

    postgresql-postgresql-ha-pgpool-569d7b8dfc-2f9zx   1/1     Running   0          7m56s
    postgresql-postgresql-ha-postgresql-0              2/2     Running   0          7m56s
    postgresql-postgresql-ha-postgresql-1              2/2     Running   0          7m56s
    postgresql-postgresql-ha-postgresql-2              2/2     Running   0          7m56s
    
  4. מאמתים את ה-PersistentVolumes ואת ה-StorageClass. במהלך תהליך השחזור,‏ Backup for GKE יוצר Proxy Class בעומס העבודה של היעד כדי להחליף את ה-StorageClass שהוקצה בעומס העבודה של המקור (gce-pd-gkebackup-dn בפלט לדוגמה).

    kubectl get pvc -n $NAMESPACE
    

    הפלט אמור להיראות כך:

    NAME                                         STATUS   VOLUME                 CAPACITY   ACCESS MODES   STORAGECLASS          AGE
    data-postgresql-postgresql-ha-postgresql-0   Bound    pvc-be91c361e9303f96   8Gi        RWO            gce-pd-gkebackup-dn   10m
    data-postgresql-postgresql-ha-postgresql-1   Bound    pvc-6523044f8ce927d3   8Gi        RWO            gce-pd-gkebackup-dn   10m
    data-postgresql-postgresql-ha-postgresql-2   Bound    pvc-c9e71a99ccb99a4c   8Gi        RWO            gce-pd-gkebackup-dn   10m
    

בדיקה שהנתונים שציפיתם להם שוחזרו

כדי לוודא שהנתונים שציפיתם להם שוחזרו, פועלים לפי השלבים הבאים:

  1. מתחברים למופע PostgreSQL.

    ./scripts/launch-client.sh
    kubectl exec -it pg-client -n postgresql -- /bin/bash
    
  2. בודקים את מספר השורות בכל טבלה.

    psql -h $HOST_PGPOOL -U postgres -a -q -f /tmp/scripts/count-rows.sql
    select COUNT(*) from tb01;
    

    אמורה להתקבל תוצאה דומה לנתונים שכתבתם קודם בקטע יצירת מערך נתונים לבדיקה. הפלט אמור להיראות כך:

    300000
    (1 row)
    
  3. יוצאים מ-Pod הלקוח.

    exit
    

הסרת המשאבים

כדי להימנע מחיובים בחשבון Google Cloud בגלל השימוש במשאבים שנעשה במסגרת המדריך הזה, אפשר למחוק את הפרויקט שמכיל את המשאבים, או להשאיר את הפרויקט ולמחוק את המשאבים בנפרד.

מחיקת הפרויקט

הדרך הקלה ביותר להימנע מחיוב היא למחוק את הפרויקט שיצרתם בשביל המדריך.

כדי למחוק Google Cloud פרויקט:

gcloud projects delete PROJECT_ID

המאמרים הבאים