פריסה וניהול של AlloyDB Omni ב-Kubernetes (אשכול GKE או אשכול משלכם)

1. מבוא

ב-Codelab הזה תלמדו איך להתקין את AlloyDB Omni Kubernetes operator (מנהל הקונטיינרים) באשכול Google Kubernetes Engine (GKE) Autopilot או באשכול Kubernetes משלכם, ולנהל תהליכי עבודה מלאים מקצה לקצה של מחזור החיים של מסד הנתונים וחוויות שימוש הכרחיות (CUJ).

‫AlloyDB Omni היא גרסה של AlloyDB שאפשר להוריד ולהריץ בכל מקום – מסביבות מקומיות ועד Google Cloud או מחשוב קצה (edge computing). באמצעות כלי התזמור של קונטיינרים, AlloyDB Omni הופך את הפעולות הבאות לאוטומטיות: זמינות גבוהה, יתירות כשל אוטומטית, תיקון עצמי, תחזוקה שוטפת עם זמן השבתה מינימלי, מאגר חיבורים, גיבויים אוטומטיים ושחזור מערכת מנקודה מסוימת בזמן (PITR).

בחירת נתיב הסביבה

אפשר להשלים את ה-Codelab הזה באחת משתי הדרכים הבאות:

  1. אפשרות 1: יש לכם חשבון Google Cloud‏ (GKE Autopilot) – אתם יכולים להקצות אשכול GKE Autopilot בניהול מלא באמצעות Google Cloud Shell או מסוף Google Cloud.
  2. מסלול 2: אין לכם חשבון Google Cloud (שימוש באשכול Kubernetes משלכם) – שימוש באשכול Kubernetes קיים (גרסה 1.21 ואילך) עם kubectl ו-helm שמוגדרים בתחנת העבודה שלכם. לא צריך חשבון Google Cloud או gcloud CLI.

דרישות מוקדמות

  • היכרות בסיסית עם המושגים של Kubernetes (kubectl, ‏ Helm, ‏ Custom Resource Definitions).
  • במסלול 1 (Google Cloud או GKE Autopilot):
    • פרויקט ב-Google Cloud שהחיוב מופעל בו.
    • גישה ל-Google Cloud Shell או לתחנת עבודה שמוגדרת עם gcloud,‏ kubectl ו-helm.
  • לאפשרות 2 (שימוש באשכול Kubernetes משלכם):
    • אשכול Kubernetes שפועל בגרסה 1.21 ואילך עם StorageClass שמוגדר כברירת מחדל להקצאה דינמית של PersistentVolume.
    • צומתי עובדים שמריצים את ליבת Linux בגרסה 4.18 ואילך עם cgroup v2 מופעל (x86-64/AMD64), ולפחות 8 מעבדי vCPU ו-‎24 GiB של זיכרון RAM שניתן להקצות באשכול.
    • תחנת עבודה שמוגדרת עם kubectl ו-helm שמחוברת לאשכול.

מה תלמדו

  • איך מקצים אשכול GKE Autopilot (נתיב 1) או מאמתים אשכול Kubernetes קיים (נתיב 2).
  • איך מתקינים את cert-manager ואת אופרטור AlloyDB Omni Kubernetes באמצעות Helm.
  • איך פורסים מכונה אחת של AlloyDB Omni DBCluster.
  • איך להגדיל את הזמינות (HA) באמצעות המתנה סינכרונית ולהפעיל יכולת המתנה לקריאה בלבד.
  • איך מגדירים גיבויים אוטומטיים מתוזמנים למאגר אחסון מקומי (ואופציונלית ל-Google Cloud Storage בנתיב 1).
  • איך לבצע גיבויים על פי דרישה ולוודא שחזור נתונים למצב קודם.
  • איך מבצעים שחזור מערכת מנקודה מסוימת בזמן (PITR) לאשכול חדש של מסדי נתונים משוכפלים.
  • איך פורסים מאגר חיבורים של PgBouncer כדי לשנות את קנה המידה של חיבורי לקוחות.
  • איך פורסים את pgAdmin4 כדי לנהל את מסד הנתונים ולשלוח אליו שאילתות באופן חזותי.
  • איך מבצעים תחזוקה עם זמן השבתה קצר (LDTM) כדי לשנות את קנה המידה של משאבי המעבד (CPU) והזיכרון.

מה תצטרכו

  • אפשרות 1: Google Cloud Shell עם כלי השירות gcloud,‏ kubectl ו-helm שמותקנים מראש.
  • אפשרות 2: מסוף עם kubectl ו-helm שמחובר לאשכול Kubernetes.
  • למאמרי עזרה, אפשר לעיין במדריך הרשמי לפריסת AlloyDB Omni.

2. הגדרה ודרישות

בוחרים באפשרות Path 1 אם משתמשים בחשבון Google Cloud כדי ליצור אשכול GKE Autopilot, או באפשרות Path 2 אם משתמשים באשכול Kubernetes משלכם בלי חשבון Google Cloud.

מסלול 1: הגדרת פרויקט ב-Google Cloud‏ (GKE Autopilot)

  1. במסוף Google Cloud, בוחרים פרויקט קיים או יוצרים פרויקט חדש.
  2. מוודאים שהחיוב מופעל בפרויקט. איך בודקים את סטטוס החיוב
  3. כדי לפתוח את Google Cloud Shell, לוחצים על הסמל Activate Cloud Shell בפינה הימנית העליונה של מסוף Google Cloud, או נכנסים לכתובת shell.cloud.google.com. Cloud Shell מקצה סביבת מחשוב שנטענת עם gcloud, ‏ kubectl ו-helm.
  4. מגדירים את מזהה הפרויקט בתור משתנה סביבה ומגדירים את gcloud:
export PROJECT_ID="<YOUR_PROJECT_ID>"
export REGION="us-central1"
export CLUSTER_NAME="omni-autopilot-cluster"

gcloud config set project ${PROJECT_ID}
gcloud config set compute/region ${REGION}
  1. מפעילים את ממשקי ה-API הנדרשים של Google Cloud ל-GKE ול-Cloud Storage:
gcloud services enable container.googleapis.com \
    storage.googleapis.com \
    cloudresourcemanager.googleapis.com

אפשרות 2: הגדרת אשכול משלכם (ללא חשבון Google Cloud)

אם אין לכם חשבון Google Cloud ואתם משתמשים באשכול Kubernetes משלכם, לפני שתמשיכו, ודאו שהתנאים המוקדמים הבאים מתקיימים מהטרמינל שלכם:

  1. מוודאים ש-kubectl ו-helm יכולים להגיע לאשכול, ושהצמתים הם Ready:
kubectl get nodes
helm version
  1. מוודאים שלקלאסטר יש ברירת מחדל של StorageClass שמסומנת ב-(default). המניפסטים DBCluster ו-BackupPlan מקצים באופן דינמי PersistentVolumeClaims באמצעות ברירת המחדל של האשכול StorageClass:
kubectl get storageclass

אם אין StorageClass שמסומן כ(default), צריך להגדיר אחד כברירת מחדל לפני שממשיכים:

kubectl patch storageclass <YOUR_STORAGE_CLASS_NAME> \
  -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
  1. מוודאים שצומתי העובדים עומדים בדרישות החומרה ומערכת ההפעלה של המפעיל:
    • מערכת הפעלה וליבה: ליבת Linux בגרסה 4.18 ואילך עם cgroup v2 מופעלת בצומתי x86-64/AMD64.
    • קיבולת האשכול: לפחות 8 מעבדי vCPU ו-‎24 GiB של זיכרון שניתן להקצות בצמתים העובדים, כדי להריץ בו-זמנית את מכונות מסד הנתונים של הזמינות הגבוהה (שבשלב 12 הוגדלו ל-2 מעבדי vCPU ו-‎8 GiB כל אחת), את המכונה המשוכפלת של PITR, את PgBouncer ואת pgAdmin4.
    • גישה לרשת: גישה יוצאת לאינטרנט כדי לשלוף קובצי אימג' של קונטיינרים מ-gcr.io/alloydb-omni, מ-quay.io/jetstack ומ-docker.io.

3. הקצאה או התחברות לאשכול Kubernetes

אם אתם פועלים לפי מסלול 1 (חשבון Google Cloud),‏ GKE Autopilot מספק מצב Kubernetes מנוהל לחלוטין, שבו Google מנהלת את תשתית האשכול, הקצאת הצמתים וההתאמה האוטומטית לעומס (automatic scaling). אתם יכולים ליצור את אשכול GKE Autopilot באמצעות Google Cloud CLI או מסוף Google Cloud.

אפשרות א': יצירת אשכול GKE Autopilot באמצעות CLI (נתיב 1)

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

gcloud container clusters create-auto ${CLUSTER_NAME} \
    --region=${REGION} \
    --project=${PROJECT_ID}

אפשרות ב': יצירת אשכול GKE Autopilot דרך מסוף Google Cloud (נתיב 1)

  1. פותחים את Kubernetes Engine במסוף Google Cloud.
  2. בחלונית הניווט שמימין, לוחצים על Clusters.
  3. לוחצים על יצירה.
  4. בקטע GKE Autopilot, לוחצים על Configure.
  5. מציינים את שם האשכול (לדוגמה, omni-autopilot-cluster) ובוחרים את האזור הרצוי (us-central1).
  6. לוחצים על יצירה.

אימות הקישוריות של האשכול (נתיב 1 ונתיב 2)

אם יצרתם אשכול GKE Autopilot במסלול 1, אתם צריכים להגדיר את פרטי הכניסה ל-kubectl:

gcloud container clusters get-credentials ${CLUSTER_NAME} --region=${REGION} --project=${PROJECT_ID}

גם בנתיב 1 וגם בנתיב 2, בודקים את הקישוריות לאשכול Kubernetes:

kubectl get nodes

4. התקנת Operator Prerequisites ו-Operator

כדי לנהל אישורי TLS של תגובות לפעולות לפיתוח האפליקציה (webhooks) של אימות, אופרטור AlloyDB Omni Kubernetes דורש את cert-manager.

1. התקנת cert-manager

מתקינים את cert-manager באמצעות תרשים Helm הרשמי:

helm install \
  cert-manager oci://quay.io/jetstack/charts/cert-manager \
  --version v1.21.2 \
  --namespace cert-manager \
  --create-namespace \
  --set crds.enabled=true \
  --set global.leaderElection.namespace=cert-manager

מוודאים שה-pods של cert-manager פועלים:

kubectl wait --namespace cert-manager \
  --for=condition=ready pod \
  --selector=app.kubernetes.io/instance=cert-manager \
  --timeout=120s

2. התקנת אופרטור AlloyDB Omni

פורסים את האופרטור של AlloyDB Omni Kubernetes במרחב השמות alloydb-omni-system באמצעות Helm:

helm install alloydbomni-operator oci://gcr.io/alloydb-omni/alloydbomni-operator \
  --version 1.8.2 \
  --create-namespace \
  --namespace alloydb-omni-system \
  $(helm install --help | grep -q -- '--rollback-on-failure' && echo '--rollback-on-failure' || echo '--atomic') \
  --timeout 5m

מוודאים שה-pods של המפעיל תקינים ופועלים:

kubectl get pods -n alloydb-omni-system

5. יצירת אשכול של מסד נתונים עם מכונה אחת

בשלב הזה, תיצרו מרחב שמות ייעודי לאפליקציה ותפרסו מכונה אחת של AlloyDB Omni DBCluster.

1. יצירת מרחב שמות וסוד של פרטי כניסה של אדמין

יוצרים מרחב שמות omni-demo לעומסי עבודה של מסד נתונים:

kubectl create namespace omni-demo

יוצרים סוד של Kubernetes שבו מאוחסנת הסיסמה של משתמש ברירת המחדל של מנהל מסד הנתונים של postgres:

kubectl apply -n omni-demo -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
  name: db-pw-adbo
type: Opaque
data:
  adbo: "Q2hhbmdlTWUxMjM=" # Base64 for "ChangeMe123"
EOF

2. פריסת אשכול מסד נתונים עם מכונה אחת

יוצרים מניפסט DBCluster של מכונה אחת:

kubectl apply -n omni-demo -f - <<EOF
apiVersion: alloydbomni.dbadmin.goog/v1
kind: DBCluster
metadata:
  name: adbo
spec:
  databaseVersion: "18.3.0"
  primarySpec:
    adminUser:
      passwordRef:
        name: db-pw-adbo
    resources:
      cpu: 1
      memory: 4Gi
      disks:
      - name: DataDisk
        size: 10Gi
EOF

3. אימות המוכנות של האשכול

עוקבים אחרי סטטוס האשכול עד שהערך של DBCLUSTERPHASE מגיע ל-DBClusterReady. ההקצאה הראשונית יכולה להימשך כמה דקות: המפעיל צריך ליצור את הנפח הקבוע ולמשוך את קובץ האימג' של מסד הנתונים, וב-GKE Autopilot יכול להיות שקודם צריך להקצות צומת חדש.

kubectl get dbcluster -n omni-demo -w

כדי לצאת ממצב צפייה, צריך ללחוץ על Ctrl+C כשהערך של DBCLUSTERPHASE מגיע ל-DBClusterReady.

פלט לדוגמה:

NAME   PRIMARYENDPOINT   PRIMARYPHASE   DBCLUSTERPHASE   HAREADYSTATUS   HAREADYREASON
adbo   10.128.0.45       Ready          DBClusterReady

שימו לב לכתובת ה-IP של PRIMARYENDPOINT, שהיא ה-ClusterIP של שירות Kubernetes לקריאה ולכתיבה al-adbo-rw-ilb. ‫AlloyDB Omni מאזין ליציאת ברירת המחדל של PostgreSQL‏ 5432.

בודקים את המשאבים שהאופרטור התאים מהמניפסט היחיד של DBCluster – ה-Pod של מסד הנתונים, ה-PersistentVolumeClaim של DataDisk והשירות של al-adbo-rw-ilb:

kubectl get pods,svc,pvc -n omni-demo

6. שדרוג לזמינות גבוהה (HA) והפעלת מצב המתנה לקריאה בלבד

‫AlloyDB Omni מספק זמינות גבוהה (HA) מובנית עם שכפול סטרימינג, מעקב אוטומטי אחרי תקינות, יתירות כשל אוטומטית ושירות של עותק לקריאה בלבד.

1. הפעלת זמינות גבוהה (HA) ויכולת קריאה של רפליקה

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

kubectl patch dbcluster adbo -n omni-demo --type=merge -p '{
  "spec": {
    "availability": {
      "numberOfStandbys": 1,
      "enableStandbyAsReadReplica": true
    }
  }
}'

2. אימות הייצוב של HA

מחכים שהמכונה במצב המתנה תוקצה ותגיע לרפליקה תקינה של סטרימינג (HAREADYSTATUS מגיע ל-True ו-HAREADYREASON מגיע ל-Ready), ואז לוחצים על Ctrl+C כדי לצאת ממצב צפייה:

kubectl get dbcluster adbo -n omni-demo -w

בודקים את תנאי הסטטוס של HAReady:

kubectl get dbcluster.alloydbomni.dbadmin.goog adbo -n omni-demo -o jsonpath='{.status.conditions[?(@.type == "HAReady")]}'

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

kubectl describe dbcluster adbo -n omni-demo | grep -A 8 "Endpoints:"

פלט לדוגמה:

Endpoints:
  Name: Read-Write
  Value: 10.128.0.45:5432
  Name: Read-Only
  Value: 10.128.0.46:5432

נקודת הקצה לקריאה ולכתיבה (שירות al-adbo-rw-ilb) מנתבת למסד הנתונים הראשי, ונקודת הקצה לקריאה בלבד (שירות al-adbo-ro-ilb) מפיצה שאילתות קריאה בין מכונות במצב המתנה.

7. הגדרת Automated BackupPlans (מקומי ו-GCS)

ב-AlloyDB Omni אפשר לבצע גיבויים פיזיים וארכוב WAL באמצעות המשאב המותאם אישית BackupPlan. אתם יכולים להגדיר את משך השמירה של הגיבוי, לוחות זמנים אוטומטיים של cron ויעדי גיבוי (נפחי אחסון מקומיים קבועים או Google Cloud Storage).

1. יצירת תוכנית גיבוי מקומית

יוצרים BackupPlan שכותב גיבויים לאחסון מקומי של Kubernetes שמצורף למכונות של מסד הנתונים:

kubectl apply -n omni-demo -f - <<EOF
apiVersion: alloydbomni.dbadmin.goog/v1
kind: BackupPlan
metadata:
  name: backupplan-local
spec:
  dbclusterRef: adbo
  backupSchedules:
    full: "0 2 * * *" # Daily at 02:00 UTC
    incremental: "0 */4 * * *" # Every 4 hours
  backupRetainDays: 7
EOF

מוודאים שה-BackupPlan המקומי מוכן:

kubectl get backupplan backupplan-local -n omni-demo

צריך להמתין עד ש-PHASE ידווח על Ready ו-NEXTBACKUPTIME יתוזמן.

2. יצירת GCS BackupPlan (אפשרות 1: Google Cloud בלבד – אופציונלי)

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

  1. יוצרים קטגוריה של Cloud Storage:
export BUCKET_NAME="${PROJECT_ID}-omni-backups"
gcloud storage buckets create gs://${BUCKET_NAME} --location=${REGION}
  1. יוצרים חשבון שירות עם הרשאות אדמין של אובייקטים ב-Cloud Storage, ויוצרים לו מפתח:

export SA_NAME="omni-backup-sa"
gcloud iam service-accounts create ${SA_NAME} --display-name="AlloyDB Omni Backup SA"

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
  --member="serviceAccount:${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role="roles/storage.objectAdmin"

gcloud iam service-accounts keys create /tmp/gcs-key.json \
  --iam-account="${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"
  1. יוצרים את הסוד במרחב השמות של Kubernetes:
kubectl create secret generic gcs-backup-secret \
  --from-file=key.json=/tmp/gcs-key.json \
  -n omni-demo
rm /tmp/gcs-key.json
  1. מחילים את המניפסט של GCS BackupPlan. השדה key הוא התיקייה בקטגוריה שאליה המפעיל כותב את הגיבויים. הוא חייב להתחיל ב-/.
kubectl apply -n omni-demo -f - <<EOF
apiVersion: alloydbomni.dbadmin.goog/v1
kind: BackupPlan
metadata:
  name: backupplan-gcs
spec:
  dbclusterRef: adbo
  backupSchedules:
    full: "0 1 * * *"
    incremental: "0 */6 * * *"
  backupRetainDays: 14
  backupLocation:
    type: GCS
    gcsOptions:
      bucket: ${BUCKET_NAME}
      key: /omni-backups/adbo
      secretRef:
        name: gcs-backup-secret
        namespace: omni-demo
EOF

מאמתים את הסטטוס של GCS BackupPlan:

kubectl get backupplan backupplan-gcs -n omni-demo

צריך להמתין עד ש-PHASE ידווח על Ready ו-NEXTBACKUPTIME יתוזמן.

8. הוספת נתונים, הפעלת גיבוי ובדיקת שחזור

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

1. אכלוס נתונים ראשוניים

מריצים pod זמני של לקוח PostgreSQL כדי להתחבר למסד הנתונים דרך שירות הקריאה והכתיבה שלו al-adbo-rw-ilb בתור המשתמש postgres:

kubectl run pg-client --rm -i --tty --image=postgres:16 --restart=Never -n omni-demo -- \
  psql -h al-adbo-rw-ilb -U postgres -d postgres -c "
    CREATE TABLE customers (id SERIAL PRIMARY KEY, name TEXT, created_at TIMESTAMPTZ DEFAULT pg_catalog.now());
    INSERT INTO customers (name) VALUES ('Alpha Co'), ('Beta LLC');
    SELECT * FROM customers;
  "

כשמופיעה בקשה להזין סיסמה, כותבים ChangeMe123. זו הסיסמה שקידדתם ב-Base64 בסוד db-pw-adbo בשלב 5.

2. הפעלת גיבוי לפי דרישה

יוצרים משאב ידני בהתאמה אישית של Backup שמפנה ל-BackupPlan המקומי:

kubectl apply -n omni-demo -f - <<EOF
apiVersion: alloydbomni.dbadmin.goog/v1
kind: Backup
metadata:
  name: initial-customer-backup
spec:
  dbclusterRef: adbo
  backupPlanRef: backupplan-local
  manual: true
EOF

עוקבים אחרי התקדמות הגיבוי:

kubectl get backup initial-customer-backup -n omni-demo -w

מחכים עד שהסטטוס של PHASE ישתנה ל-Succeeded.

3. שינוי נתונים (הוספת רשומות חדשות)

הוספת רשומות נוספות אחרי הגיבוי:

kubectl run pg-client --rm -i --tty --image=postgres:16 --restart=Never -n omni-demo \
  --env="PGPASSWORD=ChangeMe123" -- \
  psql -h al-adbo-rw-ilb -U postgres -d postgres -c "
    INSERT INTO customers (name) VALUES ('Gamma Inc'), ('Delta Corp');
    SELECT * FROM customers;
  "

עכשיו יש במסד הנתונים 4 שורות.

4. שחזור מהגיבוי

הפעלת שחזור למצב שתועד ב-initial-customer-backup:

kubectl apply -n omni-demo -f - <<EOF
apiVersion: alloydbomni.dbadmin.goog/v1
kind: Restore
metadata:
  name: restore-to-initial
spec:
  sourceDBCluster: adbo
  backup: initial-customer-backup
EOF

עוקבים אחרי פעולת השחזור:

kubectl get restore restore-to-initial -n omni-demo -w

מחכים עד שהערך של PHASE יגיע ל-ProvisionSucceeded, ומוודאים שהערך של DBCluster חוזר ל-DBClusterReady:

kubectl get dbcluster adbo -n omni-demo -w

5. אימות מצב הנתונים ששוחזרו

שולחים שאילתה לטבלה customers כדי לוודא שקיימות רק הרשומות שלפני הגיבוי:

kubectl run pg-client --rm -i --tty --image=postgres:16 --restart=Never -n omni-demo \
  --env="PGPASSWORD=ChangeMe123" -- \
  psql -h al-adbo-rw-ilb -U postgres -d postgres -c "
    SELECT * FROM customers;
  "

הפלט מאשר שקיימות רק 2 שורות (Alpha Co ו-Beta LLC), ומוודא שמסד הנתונים שוחזר למצב הגיבוי המדויק.

9. שחזור מערכת מנקודה מסוימת בזמן (PITR) למסד נתונים משוכפל

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

מכיוון שהמפעיל מעביר באופן רציף את יומן הכתיבה מראש (WAL) לארכיון, בעזרת PITR אפשר להתאושש מטעויות אנוש או מטעויות באפליקציה – לדוגמה, DELETE או DROP TABLE לא מכוונים בשעה 14:15:00 – על ידי שכפול של מסד הנתונים לשנייה המדויקת לפני שהטעות קרתה (14:14:59), בלי לגעת באשכול המקורי.

1. תיעוד של חותמת הזמן הנוכחית ושינוי הנתונים

מאחזרים את חותמת הזמן הנוכחית ב-UTC:

export PITR_TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
echo "PITR Target Timestamp: ${PITR_TIMESTAMP}"

הוספת רשומת בדיקה שמייצגת שינוי לא רצוי אחרי חותמת הזמן הזו:

kubectl run pg-client --rm -i --tty --image=postgres:16 --restart=Never -n omni-demo \
  --env="PGPASSWORD=ChangeMe123" -- \
  psql -h al-adbo-rw-ilb -U postgres -d postgres -c "
    INSERT INTO customers (name) VALUES ('Unwanted Record Post-Timestamp');
    SELECT * FROM customers;
  "

2. ביצוע שחזור לנקודת זמן ספציפית

מחילים את המשאב המותאם אישית Restore שמגדיר את pointInTime ו-clonedDBClusterConfig:

kubectl apply -n omni-demo -f - <<EOF
apiVersion: alloydbomni.dbadmin.goog/v1
kind: Restore
metadata:
  name: restore-pitr-clone
spec:
  sourceDBCluster: adbo
  pointInTime: "${PITR_TIMESTAMP}"
  clonedDBClusterConfig:
    dbclusterName: adbo-cloned
EOF

עוקבים אחרי פעולת השחזור עד שהערך של PHASE מגיע ל-ProvisionSucceeded:

kubectl get restore restore-pitr-clone -n omni-demo -w

3. אימות מסד הנתונים המשוכפל

בסיום השחזור, מחכים עד שה-DBCluster המשוכפל החדש יגיע ל-DBClusterReady (לוחצים על Ctrl+C כדי לצאת ממצב הצפייה):

kubectl get dbcluster adbo-cloned -n omni-demo -w

שולחים שאילתה למסד הנתונים המשוכפל adbo-cloned דרך שירות הקריאה והכתיבה שלו al-adbo-cloned-rw-ilb:

kubectl run pg-client --rm -i --tty --image=postgres:16 --restart=Never -n omni-demo \
  --env="PGPASSWORD=ChangeMe123" -- \
  psql -h al-adbo-cloned-rw-ilb -U postgres -d postgres -c "
    SELECT * FROM customers;
  "

שימו לב ש-Unwanted Record Post-Timestamp לא נמצא באשכול המשוכפל, מה שמוכיח שהשחזור בוצע בצורה מדויקת לנקודת הזמן הרצויה.

10. פריסת מאגר החיבורים של PgBouncer

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

‫PostgreSQL יוצר תהליך נפרד במערכת ההפעלה לכל חיבור של לקוח, כך שמאות חיבורים בו-זמניים משירותי אינטרנט, ממיקרו-שירותים או מסוכני AI יכולים לנצל את כל הזיכרון של מסד הנתונים. ‫PgBouncer נמצא לפני מסד הנתונים ומבצע ריבוב של הרבה חיבורי לקוח קצרי-טווח (עד max_client_conn) למאגר קטן של חיבורי שרת PostgreSQL ארוכי-טווח (default_pool_size לכל זוג משתמש/מסד נתונים, עד למגבלה של max_db_connections).

1. פריסת PgBouncer

פורסים מאגר PgBouncer עם 2 רפליקות שמקושר לאשכול adbo:

kubectl apply -n omni-demo -f - <<EOF
apiVersion: alloydbomni.dbadmin.goog/v1
kind: PgBouncer
metadata:
  name: omni-pgbouncer
spec:
  dbclusterRef: adbo
  allowSuperUserAccess: true
  replicaCount: 2
  parameters:
    pool_mode: transaction
    default_pool_size: "20"
    max_client_conn: "500"
    max_db_connections: "100"
  podSpec:
    resources:
      cpu: 1
      memory: 1Gi
    image: "gcr.io/alloydb-omni/operator/g-pgbouncer:1.4.0"
  serviceOptions:
    type: ClusterIP
EOF

2. אימות הסטטוס של PgBouncer

עוקבים אחרי הסטטוס של PgBouncer עד שהערך של PHASE הוא Ready:

kubectl get pgbouncer omni-pgbouncer -n omni-demo -w

בודקים את הפודים והשירות של PgBouncer שפועלים:

kubectl get pods -n omni-demo
kubectl get svc al-omni-pgbouncer-pgb-svc -n omni-demo

3. התחברות באמצעות PgBouncer

מחברים לקוח דרך שירות PgBouncer ביציאה 6432:

kubectl run pg-client --rm -i --tty --image=postgres:16 --restart=Never -n omni-demo \
  --env="PGPASSWORD=ChangeMe123" -- \
  psql -h al-omni-pgbouncer-pgb-svc -p 6432 -U postgres -d postgres -c "
    SELECT pg_catalog.version();
    SELECT * FROM customers;
  "

‫PgBouncer מעביר את השאילתה בצורה חלקה למסד הנתונים הראשי של AlloyDB Omni.

11. פריסת pgAdmin4 כדי לגשת למסד הנתונים

אתם יכולים להריץ את pgAdmin4 ישירות בתוך אשכול Kubernetes כדי לספק מסוף ניהול מבוסס-אינטרנט לשליחת שאילתות, לניהול ולבדיקה של AlloyDB Omni.

1. התקנת pgAdmin4 באמצעות Helm

מתקינים את pgadmin4 במרחב השמות omni-demo:

helm install my-pgadmin oci://docker.io/dpage/pgadmin4-helm \
  --namespace omni-demo \
  --set ingress.enabled=false \
  --set image.tag=latest \
  --set auth.email="admin@example.com" \
  --set auth.password="AdminPassword123"

התרשים הזה נותן למשאבי ה-Kubernetes שלו את השם pgadmin4 (Deployment, ‏ Service, ‏ PersistentVolumeClaim) ומתייג את ה-Pods שלו ב-app=pgadmin4, בלי קשר לשם של גרסת ה-Helm‏ (my-pgadmin).

מוודאים שה-Pod של pgAdmin4 פועל:

kubectl wait --namespace omni-demo \
  --for=condition=ready pod \
  --selector=app=pgadmin4 \
  --timeout=300s

2. העברת יציאה וגישה לממשק המשתמש באינטרנט

מעבירים את pgAdmin4 ליציאה אחרת בסביבה המקומית או ב-Cloud Shell:

kubectl port-forward service/pgadmin4 5050:80 -n omni-demo

‫kubectl port-forward ממשיך לפעול בחזית כל עוד משתמשים בממשק המשתמש של pgAdmin4 באינטרנט. פותחים טרמינל שני (או כרטיסייה חדשה ב-Cloud Shell) לפקודות אחרות, ולוחצים על Ctrl+C בטרמינל הזה כשמוכנים לעבור לשלב הבא.

פותחים את ממשק האינטרנט של pgAdmin4:

  • אפשרות 1 (Google Cloud Shell): לוחצים על הכפתור Web Preview בתפריט שבפינה הימנית העליונה, בוחרים באפשרות Change port, מזינים 5050 ולוחצים על Change and Preview.
  • דרך 2 (תחנת עבודה מקומית): פותחים את http://localhost:5050 בדפדפן בזמן שהפקודה kubectl port-forward פועלת.

מתחברים באמצעות:

  • אימייל: admin@example.com
  • סיסמה: AdminPassword123

3. ‫רישום של AlloyDB Omni ב-pgAdmin4

  1. ב-pgAdmin4, לוחצים לחיצה ימנית על Servers‏ > Register‏ > Server...‎.
  2. בכרטיסייה כללי:
    • שם: AlloyDB Omni Primary
  3. בכרטיסייה חיבור:
    • הכתובת/השם של המארח: al-adbo-rw-ilb.omni-demo.svc.cluster.local (או al-omni-pgbouncer-pgb-svc.omni-demo.svc.cluster.local ל-PgBouncer)
    • ‫Port: ‏ 5432 (או 6432 ל-PgBouncer)
    • מסד נתונים לתחזוקה: postgres
    • שם משתמש: postgres
    • סיסמה: ChangeMe123
  4. לוחצים על Save ומאמתים את הסשן הפעיל של מסד הנתונים והטבלאות.

12. שינוי קנה המידה של המעבד (CPU) והזיכרון באמצעות תחזוקה עם זמן השבתה קצר (LDTM)

כשמגדילים את המחשוב והזיכרון במסד נתונים בסביבת ייצור, עדכונים רגילים גורמים להפרעות בהפעלה מחדש של מסד הנתונים. ב-AlloyDB Omni יש תחזוקה עם זמן השבתה קצר (LDTM), שמאפשרת להריץ עדכונים דרך רפליקות עם מינימום הפרעות לאפליקציה.

1. הפעלת הערות LDTM

מוסיפים הערה ל-DBCluster כדי להפעיל את LDTM לעדכונים:

kubectl annotate dbclusters.alloydbomni.dbadmin.goog adbo -n omni-demo dbcluster.dbadmin.goog/enableLDTM=true --overwrite

2. שינוי משאבי המעבד (CPU) והזיכרון

מעדכנים את המשאבים הראשיים מ-cpu: 1, memory: 4Gi ל-cpu: 2, memory: 8Gi:

kubectl patch dbcluster adbo -n omni-demo --type=merge -p '{
  "spec": {
    "primarySpec": {
      "resources": {
        "cpu": 2,
        "memory": "8Gi"
      }
    }
  }
}'

3. ‫Monitor LDTM Scaling Progress

עוקבים אחרי העדכון בהדרגה (rolling) ואחרי התנאים למעבר מגיבוי לראשי:

kubectl get dbcluster adbo -n omni-demo -o yaml | grep -A 5 -B 2 "LDTMScalingInProgress"

צפו בתרמילים מתגלגלים בחן:

kubectl get pods -n omni-demo -w

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

מאמתים את הקצאת המשאבים המעודכנת:

kubectl get dbcluster adbo -n omni-demo -o jsonpath='{.spec.primarySpec.resources}'

13. מחיקת משאבים

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

אם אתם מריצים את הניקוי בסשן חדש של מסוף (נתיב 1), משתני הסביבה מהשלבים הקודמים כבר לא מוגדרים. מייצאים אותם מחדש עם אותם ערכים שבהם השתמשתם קודם:

export PROJECT_ID="<YOUR_PROJECT_ID>"
export REGION="us-central1"
export CLUSTER_NAME="omni-autopilot-cluster"
export BUCKET_NAME="${PROJECT_ID}-omni-backups"
export SA_NAME="omni-backup-sa"
gcloud config set project ${PROJECT_ID}

1. מחיקת עומסי עבודה של מסדי נתונים (נתיב 1 ונתיב 2)

מסמנים את שני האשכולות כמחוקים כדי לעבור את הבדיקות של ה-webhook לאימות, ממתינים עד שהמפעיל יסיר את המשאבים של DBCluster ואז מוחקים את מרחב השמות:

kubectl patch dbcluster adbo -n omni-demo --type=merge -p '{"spec":{"isDeleted":true}}'
kubectl patch dbcluster adbo-cloned -n omni-demo --type=merge -p '{"spec":{"isDeleted":true}}'
kubectl wait --for=delete dbcluster/adbo dbcluster/adbo-cloned -n omni-demo --timeout=300s
kubectl delete namespace omni-demo

אם השתמשתם באשכול Kubernetes משלכם (נתיב 2) ואתם רוצים להסיר גם את אופרטור AlloyDB Omni ואת cert-manager:

helm uninstall alloydbomni-operator -n alloydb-omni-system
kubectl delete namespace alloydb-omni-system
helm uninstall cert-manager -n cert-manager
kubectl delete namespace cert-manager

2. מחיקת קטגוריית GCS וחשבון שירות IAM (דרך 1 בלבד)

אם יצרתם את הקטגוריה של Google Cloud Storage ואת חשבון השירות במסלול 1:

gcloud storage rm --recursive gs://${BUCKET_NAME}
gcloud projects remove-iam-policy-binding ${PROJECT_ID} \
  --member="serviceAccount:${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role="roles/storage.objectAdmin"
gcloud iam service-accounts delete ${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com --quiet

3. מחיקת אשכול GKE (נתיב 1 בלבד)

אם הקציתם אשכול GKE Autopilot בנתיב 1:

gcloud container clusters delete ${CLUSTER_NAME} --region=${REGION} --quiet

14. מזל טוב

מעולה! סיימתם את ה-Codelab של AlloyDB Omni ב-Kubernetes.

מה למדנו

  • הקצאת אשכול GKE Autopilot (נתיב 1) או הכנת אשכול Kubernetes קיים (נתיב 2).
  • פרסתם את cert-manager ואת אופרטור AlloyDB Omni Kubernetes באמצעות Helm.
  • פריסת מכונה אחת של AlloyDB Omni DBCluster.
  • שדרוג האשכול לזמינות גבוהה (HA) עם המתנות סינכרוניות והפעלת ניתוב המתנה לקריאה בלבד.
  • יצרנו משאבי BackupPlan אוטומטיים גם לאחסון מתמיד מקומי וגם ל-Google Cloud Storage ‏ (GCS).
  • ביצעתי גיבויים לפי דרישה ואימתתי שחזורים של מסדי נתונים.
  • ביצוע שחזור מערכת מנקודה מסוימת בזמן (PITR) לאשכול חדש של מסד נתונים משוכפל.
  • הטמעת מאגר חיבורים של PgBouncer לחיבורי לקוחות שניתנים להתאמה לעומס.
  • פריסה וחיבור של pgAdmin4 לניהול מסדי נתונים.
  • הפעלת תחזוקה עם זמן השבתה קצר (LDTM) כדי לשנות באופן דינמי את משאבי המחשוב והזיכרון.

השלבים הבאים

15. סקר

איך המדריך הזה ישמש אותך?

רק קראתי אותו קראתי אותו וביצעתי את התרגילים