פריסה של מסדי נתונים של Oracle בניהול עצמי עם זמינות גבוהה

במדריך הזה מוסבר איך לפרוס הגדרה של Oracle Data Guard עם זמינות גבוהה באשכול רגיל של Google Distributed Cloud (GDC) עם air gap. ההגדרה הזו משתמשת ב-Oracle Database Enterprise Edition ומנצלת את היכולות הקיימות של GDC לאחסון ולרשתות.

הפריסה הזו משתמשת ב-Oracle Database Operator for Kubernetes הרשמי, שמבצע אוטומציה של ניהול מחזור החיים של מסד הנתונים.

ארכיטקטורה

הארכיטקטורה מתארת פריסה של מסד נתונים של Oracle בזמינות גבוהה, שמנוהל על ידי Oracle Database Operator באשכול רגיל של GDC. פריסה בזמינות גבוהה כוללת מסד נתונים ראשי ומסד נתונים במצב המתנה, שמוגדרים עם Data Guard לרפליקציה וליתירות כשל.

דיאגרמת ארכיטקטורה של פריסת מסד נתונים של Oracle עם זמינות גבוהה באמצעות Data Guard.

הרכיבים העיקריים הם:

  • ‫פרויקט GDC: מאגר הפרויקט של המשאבים שלכם.
  • אשכול Kubernetes רגיל: אשכול רגיל שמספק את משאבי המחשוב.
  • ‫Oracle Database Operator: אופרטור של Kubernetes שמבצע אוטומציה של הקצאת משאבים, ניהול מחזור חיים וניטור של מסדי נתונים של Oracle. הוא מפשט משימות מורכבות כמו תיקון, גיבוי ושחזור, ומקל על הפעלת עומסי עבודה של Oracle עם שמירת מצב בסביבה בקונטיינרים.
  • מסד נתונים ראשי: המכונה הפעילה של מסד הנתונים בקונטיינר לקריאה ולכתיבה.
  • מסד נתונים במצב המתנה: מופע מסד הנתונים של הרפליקה לקריאה בלבד (או לקריאה וכתיבה במהלך יתירות כשל).
  • ‫Data Guard Broker: מתזמר את ההגדרה ואת מעברי התפקידים (מעבר/יתירות כשל) בין מסדי הנתונים.
  • ‫Harbor: ה-Container Registry הפרטי שמשמש לאירוח קובצי האימג' של מסד הנתונים, ה-operator והלקוח בסביבה עם air gap.
  • ‫Cert-manager: המפעיל מסתמך על cert-manager לניהול אישורי ה-webhook. ‫cert-manager מותקן מראש באשכולות רגילים של GDC.

במדריך הזה, אתם פורסים את האופרטור במרחב שמות משלו (oracle-database-operator-system) ואת המכונה של מסד הנתונים במרחב שמות נפרד (oracle-dbs). מרחבי השמות האלה מוצגים בתיבות עם גבולות מקווקווים בדיאגרמת הארכיטקטורה.

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

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

לפני שמתחילים את הפריסה, צריך לוודא שהסביבה עומדת בדרישות הבאות:

  • יוצרים פרויקט שיכיל את כל המשאבים שייווצרו במהלך המדריך הזה.
  • מקצים למשתמש את התפקידים "אדמין של אשכול" ו"אדמין של אשכול רגיל" בפרויקט. כך אפשר ליצור אשכול Kubernetes רגיל ולנהל את המשאבים שלו:

    export PROJECT_ID=PROJECT_ID
    export USER_NAME=USER_NAME
    
    gdcloud projects add-iam-policy-binding ${PROJECT_ID} \
      --member="user:${USER_NAME}" \
      --role=cluster-admin
    
    gdcloud projects add-iam-policy-binding ${PROJECT_ID} \
      --member="user:${USER_NAME}" \
      --role=standard-cluster-admin
    
  • יוצרים מכונה של Harbor ופרויקט ב-Harbor כדי לארח את קובצי האימג' של הקונטיינרים שדרושים למדריך הזה.

  • כדי להעלות קובצי אימג' למכונה של Harbor, צריך לתת למשתמש את התפקיד Harbor Instance Admin:

    gdcloud projects add-iam-policy-binding ${PROJECT_ID} \
      --member="user:${USER_NAME}" \
      --role=harbor-instance-admin
    
  • יוצרים חשבון רובוט של Harbor בפרויקט Harbor. בהמשך המדריך, פרטי הכניסה של חשבון הרובוט יאוחסנו בסודות של Kubernetes, כדי לאפשר לאשכול לשלוף קובצי אימג' מ-Harbor בזמן יצירת קונטיינרים.

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

    kubectl --kubeconfig MGMT_API_KUBECONFIG create -f - <<EOF
    apiVersion: cluster.gdc.goog/v1
    kind: Cluster
    metadata:
      name: ${CLUSTER_NAME}
      namespace: ${PROJECT_ID}
    spec:
      nodePools:
      - machineTypeName: n3-standard-8-gdc
        nodeCount: 2
        name: ${CLUSTER_NAME}-node-pool
    EOF
    
  • מגדירים את משתני הסביבה. המשתנים האלה ישמשו לאורך המדריך ליצירת משאבים ולהפניה אליהם:

    הערות:

    • במדריך הזה, לשני המכונות של מסד הנתונים קוראים באופן שרירותי blue ו-green. בהתחלה, המכונה blue היא הראשית והמכונה green היא המשנית.
    # General info
    export PROJECT_ID="PROJECT_ID"
    export ZONE="ZONE"
    export ORG_NAME="ORG_NAME"
    export CLUSTER_NAME="CLUSTER_NAME"
    
    # Software versions
    export ORACLE_OPERATOR_VERSION="2.1.0"
    export ORACLE_DB_VERSION="21.3.0.0"
    
    # Namespaces
    export ORACLE_OPERATOR_NAMESPACE="ORACLE_OPERATOR_NAMESPACE"
    export DB_NAMESPACE="DATABASE_NAMESPACE"
    
    # Harbor config
    export HARBOR_INSTANCE_PROJECT_ID="HARBOR_PROJECT_ID"
    export HARBOR_INSTANCE_NAME="HARBOR_INSTANCE_NAME"
    export HARBOR_INSTANCE_URL="HARBOR_INSTANCE_URL"
    export HARBOR_PROJECT="HARBOR_PROJECT"
    export HARBOR_PULL_SECRET_NAME="HARBOR_PULL_SECRET_NAME"
    export HARBOR_ROBOT_ACCOUNT="robot\$HARBOR_PROJECT+ROBOT_NAME"
    export HARBOR_ROBOT_SECRET="HARBOR_ROBOT_SECRET"
    
    # Oracle database config
    export ADMIN_PASSWORD="ADMIN_PASSWORD"
    export ADMIN_PASSWORD_SECRET_NAME="ADMIN_PASSWORD_SECRET_NAME"
    
    # Database names
    export DB_NAME_BLUE="database-blue"
    export DB_NAME_GREEN="database-green"
    
  • הערה לגבי הרשת: ההנחה במדריך הזה היא שההפעלה מתבצעת מצומת באסטיון שיש לו גישה לממשקי ה-API של GDC וגם גישה לאינטרנט, כדי להוריד את המניפסטים ואת קובצי האימג' של הקונטיינרים של Oracle Operator. אם אתם מריצים את הפקודה ממכונה ללא גישה לאינטרנט, אתם צריכים להשיג את הנכסים האלה בנפרד (לדוגמה, באמצעות docker save כדי לייצא תמונות ממכונה מחוברת ו-docker load כדי לייבא אותן) ולהעלות אותן באופן מאובטח לסביבה שלכם לפני שתמשיכו.

  • לפני שממשיכים, צריך ליצור חשבון ולקבל אסימון API בכתובת container-registry.oracle.com, ואז לאשר את הסכם הרישיון של קובצי האימג' של Oracle Database Enterprise Edition ושל Oracle Instant Client.

טעינת קובצי אימג' ל-Harbor

מכיוון שאשכולות ב-Google Distributed Cloud במודל Air-gapped לא יכולים לגשת למרשמים חיצוניים, צריך לשקף את קובצי האימג' הנדרשים למכונה הפרטית של Harbor.

כניסה ל-Oracle Container Registry

כדי לשלוף את קובצי האימג' הבסיסיים, קודם צריך לבצע אימות מול המרשם הרשמי של Oracle:

docker --config=./docker-oracle login container-registry.oracle.com

אחרי התחברות מוצלחת, פרטי הכניסה יישמרו ב-./docker-oracle/config.json.

התחברות ל-Harbor

מאמתים באמצעות המכונה הפרטית של Harbor:

docker --config=./docker-harbor login ${HARBOR_INSTANCE_URL} \
  -u ${HARBOR_ROBOT_ACCOUNT} \
  -p ${HARBOR_ROBOT_SECRET}

אחרי התחברות מוצלחת, פרטי הכניסה של החשבון הרובוטי יישמרו ב-./docker-harbor/config.json.

שליפה, תיוג ודחיפה של קובצי אימג'

מורידים את קובצי האימג' מ-Container Registry הרשמי של Oracle ומעבירים אותם לפרויקט הפנימי ב-Harbor. תשכפלו את האופרטור, את מסד הנתונים של הארגון ואת ה-instant client לצורך בדיקה.

  1. משכפלים את קובץ האימג' של האופרטור של מסד הנתונים של Oracle:

    docker --config=./docker-oracle pull \
      container-registry.oracle.com/database/operator:${ORACLE_OPERATOR_VERSION} \
      --platform linux/amd64
    
    docker tag container-registry.oracle.com/database/operator:${ORACLE_OPERATOR_VERSION} \
      ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-operator:${ORACLE_OPERATOR_VERSION}
    
    docker --config=./docker-harbor push \
      ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-operator:${ORACLE_OPERATOR_VERSION}
    
  2. משכפלים את קובץ האימג' של Oracle Database Enterprise:

    docker --config=./docker-oracle pull \
      container-registry.oracle.com/database/enterprise:${ORACLE_DB_VERSION} \
      --platform linux/amd64
    
    docker tag container-registry.oracle.com/database/enterprise:${ORACLE_DB_VERSION} \
      ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-enterprise:${ORACLE_DB_VERSION}
    
    docker --config=./docker-harbor push \
      ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-enterprise:${ORACLE_DB_VERSION}
    
  3. משכפלים את קובץ האימג' של Oracle Instant Client:

    docker --config=./docker-oracle pull \
      container-registry.oracle.com/database/instantclient:latest \
      --platform linux/amd64
    
    docker tag container-registry.oracle.com/database/instantclient:latest \
      ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-instantclient:latest
    
    docker --config=./docker-harbor push \
      ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-instantclient:latest
    

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

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

  1. מאחזרים את הקובץ kubeconfig של האשכול הרגיל:

    KUBECONFIG=kubeconfig-${CLUSTER_NAME}.yaml gdcloud clusters \
      get-credentials ${CLUSTER_NAME} \
      --standard \
      --project ${PROJECT_ID} \
      --zone ${ZONE}
    
  2. יוצרים את הכינוי kk כדי לפשט את הפקודות הבאות:

    alias kk="kubectl --kubeconfig kubeconfig-${CLUSTER_NAME}.yaml"
    

יצירת סודות

יוצרים סוד של Kubernetes כדי לאפשר לאשכול לשלוף קובצי אימג' מ-Harbor באמצעות פרטי הכניסה שנשמרו בקובץ ./docker-harbor/config.json המקומי. הסוד הזה נדרש גם במרחב השמות של המפעיל (כדי לשלוף את קובץ האימג' של המפעיל) וגם במרחב השמות של מסד הנתונים (כדי לשלוף את קובץ האימג' של מסד הנתונים).

  1. יוצרים את מרחב השמות של האופרטור:

    kk create ns ${ORACLE_OPERATOR_NAMESPACE}
    
  2. יוצרים את הסוד למשיכה של האופרטור:

    kk create secret docker-registry ${HARBOR_PULL_SECRET_NAME} \
      --from-file=.dockerconfigjson=./docker-harbor/config.json \
      -n ${ORACLE_OPERATOR_NAMESPACE}
    
  3. יוצרים את מרחב השמות של מסדי הנתונים:

    kk create ns ${DB_NAMESPACE}
    
  4. יוצרים את הסוד לשליפת קובץ האימג' של קונטיינרי מסד הנתונים:

    kk create secret docker-registry ${HARBOR_PULL_SECRET_NAME} \
      --from-file=.dockerconfigjson=./docker-harbor/config.json \
      -n ${DB_NAMESPACE}
    
  5. יוצרים את הסוד לסיסמת הניהול של מסדי הנתונים:

    kk create secret generic ${ADMIN_PASSWORD_SECRET_NAME} \
      --from-literal=password=${ADMIN_PASSWORD} \
      -n ${DB_NAMESPACE}
    

התקנת Oracle Database Operator

עכשיו מתקינים את Oracle Database Operator באשכול באמצעות החלת שלושה מניפסטים:

  1. Cluster Role Binding: הגדרת ההרשאות הנדרשות לאופרטור כדי לפעול בכל האשכול.

    kk apply -f https://raw.githubusercontent.com/oracle/oracle-database-operator/refs/tags/v${ORACLE_OPERATOR_VERSION}/rbac/cluster-role-binding.yaml
    
  2. ‫Node RBAC: נותן הרשאות לקרוא את הטופולוגיה של הצומת, שחיונית לתזמון נכון של pod.

    kk apply -f https://raw.githubusercontent.com/oracle/oracle-database-operator/refs/tags/v${ORACLE_OPERATOR_VERSION}/rbac/node-rbac.yaml
    
  3. פריסת האופרטור: פריסת הפודים של האופרטור והגדרות המשאבים בהתאמה אישית. הפקודה הזו מורידה את המניפסט הרשמי, מחליפה את נתיב התמונה בכתובת ה-URL של Harbor, מוסיפה את ההגדרות של imagePullSecrets כדי ש-Kubernetes יוכל לבצע אימות מול Harbor, ומחילה את התוצאה:

    curl -L https://raw.githubusercontent.com/oracle/oracle-database-operator/refs/tags/v${ORACLE_OPERATOR_VERSION}/oracle-database-operator.yaml \
      | sed "s|container-registry.oracle.com/database/operator:latest|${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-operator:${ORACLE_OPERATOR_VERSION}|g" \
      | awk "/terminationGracePeriodSeconds: 10/{print; print \"      imagePullSecrets:\n      - name: ${HARBOR_PULL_SECRET_NAME}\"; next}1" \
      | kk apply -f -
    

    מחכים שהפודים של המפעיל יפעלו:

    kk get pods -n ${ORACLE_OPERATOR_NAMESPACE} --watch
    

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

    NAME                                                           READY   STATUS    RESTARTS   AGE
    oracle-database-operator-controller-manager-5f7b56874d-k9v4z   1/1     Running   0          45s
    oracle-database-operator-controller-manager-5f7b56874d-n2x8m   1/1     Running   0          45s
    oracle-database-operator-controller-manager-5f7b56874d-r6z7q   1/1     Running   0          45s
    

פריסת מסדי נתונים ראשיים ומשניים

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

פריסת המכונה הראשית

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

    apiVersion: database.oracle.com/v4
    kind: SingleInstanceDatabase
    metadata:
      name: ${DB_NAME_BLUE}
      namespace: ${DB_NAMESPACE}
    spec:
      replicas: 1
      edition: enterprise
      image:
        pullFrom: "${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-enterprise:${ORACLE_DB_VERSION}"
        pullSecrets: ${HARBOR_PULL_SECRET_NAME}
        prebuiltDB: true
      sid: ORCLBLUE
      pdbName: ORCLPDB1
      archiveLog: true
      flashBack: true
      forceLog: true
      adminPassword:
        secretName: "${ADMIN_PASSWORD_SECRET_NAME}"
        secretKey: "password"
      persistence:
        size: "50Gi"
        storageClass: "standard-rwo"
        accessMode: "ReadWriteOnce"
      resources:
        requests:
          memory: "4Gi"
    

    פרמטרים מרכזיים להגדרה:

    • ‫sid / pdbName: מגדיר את מזהה המערכת (SID) ואת השם של מסד הנתונים המתחבר (PDB).
    • ‫edition: מציין את מהדורת מסד הנתונים (enterprise במקרה הזה).
    • ‫image: מפנה לתמונת המאגר הפרטי של Harbor.
    • ‫persistence: בקשה לנפח אחסון מתמיד של 50Gi באמצעות StorageClass‏ standard-rwo, שיוצר דיסק לאחסון מתמיד של תחום ב-GDC.
    • ‫replicas: הגדרת מספר הפודים ל-1 במכונה.
    • ‫archiveLog: הפעלת מצב Archive Log, שנדרש ל-Data Guard.
    • ‫flashBack: הפעלת Flashback Database, שמאפשרת להחזיר את מסד הנתונים לנקודת זמן קודמת.
    • ‫forceLog: מפעיל את Force Logging, כדי לוודא שכל השינויים נרשמים ביומן, גם לפעולות שבדרך כלל לא נרשמות ביומן.

    רשימה מלאה של אפשרויות ההגדרה, כולל פרמטרים מותאמים אישית של init ומגבלות על משאבים, מופיעה במסמכי התיעוד הרשמיים.

    יצירת מסד הנתונים דורשת הרבה משאבים ויכולה להימשך בין 10 ל-20 דקות.

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

    מחכים עד שה-pod של מסד הנתונים יהיה במצב Running:

    kk get po -n ${DB_NAMESPACE} -l app=${DB_NAME_BLUE} -w
    

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

    NAME                   READY   STATUS    RESTARTS   AGE
    database-blue-i5xdj   0/1     Pending   0          0s
    database-blue-i5xdj   0/1     Pending   0          0s
    database-blue-i5xdj   0/1     Pending   0          1s
    database-blue-i5xdj   0/1     Init:0/1   0          1s
    database-blue-i5xdj   0/1     PodInitializing   0          98s
    database-blue-i5xdj   0/1     Running           0          99s
    database-blue-i5xdj   1/1     Running           0          99s
    

    אחר כך עוקבים אחרי היומנים ומחכים להודעה DATABASE IS READY TO USE!:

    kk logs -n ${DB_NAMESPACE} -l app=${DB_NAME_BLUE} -f
    

    הפלט צריך לכלול את הפרטים הבאים:

    #########################
    DATABASE IS READY TO USE!
    #########################
    
  2. מוודאים שהסטטוס הוא Healthy והתפקיד הוא PRIMARY:

    kk get sidb -n ${DB_NAMESPACE} ${DB_NAME_BLUE}
    

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

    NAME            EDITION      STATUS    ROLE
    database-blue   Enterprise   Healthy   PRIMARY
    

פריסת המכונה במצב המתנה

אחרי שהמכונה הראשית תקינה, פורסים את המכונה במצב המתנה. שימו לב שהפרמטרים של Data Guard‏ (archiveLog,‏ flashBack,‏ forceLog) עוברים בירושה מהראשי, ואין לציין אותם במניפסט של הגיבוי:

  1. פורסים את המכונה במצב המתנה:

    apiVersion: database.oracle.com/v4
    kind: SingleInstanceDatabase
    metadata:
      name: ${DB_NAME_GREEN}
      namespace: ${DB_NAMESPACE}
    spec:
      replicas: 1
      edition: enterprise
      image:
        pullFrom: "${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-enterprise:${ORACLE_DB_VERSION}"
        pullSecrets: ${HARBOR_PULL_SECRET_NAME}
        prebuiltDB: true
      sid: ORCLGREEN
      pdbName: ORCLPDB1
      adminPassword:
        secretName: "${ADMIN_PASSWORD_SECRET_NAME}"
        secretKey: "password"
      createAs: standby
      primaryDatabaseRef: ${DB_NAME_BLUE}
      persistence:
        size: "50Gi"
        storageClass: "standard-rwo"
        accessMode: "ReadWriteOnce"
      resources:
        requests:
          memory: "4Gi"
    

    מחכים עד שה-pod של מסד הנתונים יהיה במצב Running:

    kk get po -n ${DB_NAMESPACE} -l app=${DB_NAME_GREEN} -w
    

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

    NAME                   READY   STATUS    RESTARTS   AGE
    database-green-q1gur   0/1     Pending   0          0s
    database-green-q1gur   0/1     Pending   0          0s
    database-green-q1gur   0/1     Pending   0          1s
    database-green-q1gur   0/1     Init:0/1   0          1s
    database-green-q1gur   0/1     PodInitializing   0          98s
    database-green-q1gur   0/1     Running           0          99s
    database-green-q1gur   1/1     Running           0          99s
    

    אחר כך עוקבים אחרי היומנים ומחכים להודעה DATABASE IS READY TO USE!:

    kk logs -n ${DB_NAMESPACE} -l app=${DB_NAME_GREEN} -f
    

    הפלט צריך לכלול את הפרטים הבאים:

    #########################
    DATABASE IS READY TO USE!
    #########################
    
  2. מוודאים שהסטטוס הוא Healthy והתפקיד הוא PHYSICAL_STANDBY:

    kk get sidb -n ${DB_NAMESPACE}
    

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

    NAME             EDITION      STATUS    ROLE
    database-blue    Enterprise   Healthy   PRIMARY
    database-green                Healthy   PHYSICAL_STANDBY
    

הגדרת Data Guard Broker

  1. פורסים את DataguardBroker כדי לנהל את ההגדרות של Data Guard:

    apiVersion: database.oracle.com/v4
    kind: DataguardBroker
    metadata:
      name: broker-blue-green
      namespace: ${DB_NAMESPACE}
    spec:
      primaryDatabaseRef: ${DB_NAME_BLUE}
      standbyDatabaseRefs:
        - ${DB_NAME_GREEN}
      protectionMode: MaxAvailability
      fastStartFailover: false
      loadBalancer: true
    

    פרמטרים מרכזיים להגדרה:

    • ‫protectionMode: מוגדר לערך MaxAvailability כדי לוודא שלא יאבדו נתונים אם לפחות שרת המתנה אחד זמין, ועובר למצב אסינכרוני אם אפשר להגיע לפחות לשרת המתנה אחד.
    • ‫fastStartFailover: מוגדר לערך false כדי להשבית את יתירות הכשל האוטומטית. כשהאפשרות הזו מופעלת, תהליך Observer יכול להפעיל באופן אוטומטי יתירות כשל אם מסד הנתונים הראשי לא זמין.
    • ‫loadBalancer: צריך להגדיר את הערך true כדי ליצור שירות LoadBalancer של Kubernetes בשביל ה-broker, שמספק כתובת IP חיצונית יציבה שתמיד מנתבת למסד הנתונים הראשי הנוכחי.
  2. עוקבים אחרי הסטטוס של ה-broker עד שמופיע הדיווח Healthy:

    kk get dataguardbroker -n ${DB_NAMESPACE} -w
    

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

    NAME                PRIMARY   STANDBYS   PROTECTION MODE   CONNECT STR   STATUS     FSFO
    broker-blue-green                        MaxAvailability                 Creating
    broker-blue-green                        MaxAvailability                 Creating
    broker-blue-green   ORCLBLUE   ORCLGREEN   MaxAvailability   10.0.0.25:32345/DATAGUARD   Creating   false
    broker-blue-green   ORCLBLUE   ORCLGREEN   MaxAvailability   10.0.0.25:32345/DATAGUARD   Healthy    false
    
  3. ה-DataguardBroker יוצר שירות Kubernetes‏ (broker-blue-green) שמנתב באופן אוטומטי את התנועה למסד הנתונים הראשי הנוכחי. כך נוצרת נקודת חיבור יציבה לאפליקציות. איך מקבלים את השירות:

    kk get svc -n ${DB_NAMESPACE} broker-blue-green
    

    הפלט אמור להיראות כך: שימו לב להקצאה של CLUSTER-IP ללקוחות בתוך האשכול, ושל EXTERNAL-IP ללקוחות חיצוניים באמצעות מאזן עומסים:

    NAME                TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)                         AGE
    broker-blue-green   LoadBalancer   10.0.19.198   100.66.38.138   1521:31116/TCP,5500:31842/TCP   8m
    
  4. בודקים את נקודות הקצה של שירות הברוקר. בהתחלה הוא צריך להצביע על כתובת ה-IP של הפוד הכחול:

    kk get endpoints -n ${DB_NAMESPACE} broker-blue-green
    

    הפלט אמור להיראות כך, כשכתובת ה-IP של ה-Pod הכחול אמורה להופיע במקום BLUE_POD_IP:

    NAME                ENDPOINTS
    broker-blue-green   [BLUE_POD_IP]:5500,[BLUE_POD_IP]:1521
    
  5. בודקים את ה-pods של מסד הנתונים כדי להתאים את כתובת ה-IP:

    kk get pod -n ${DB_NAMESPACE} -o wide
    

בדיקת סנכרון הנתונים והתפקידים

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

כתיבה למסד נתונים ראשי באמצעות שירות תיווך

  1. פורסים pod זמני כדי להתחבר למסד הנתונים הראשי באמצעות שירות ה-broker היציב:

    kk run sqlplus -n ${DB_NAMESPACE} --rm -it --restart=Never \
      --image=${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-instantclient:latest \
      --image-pull-policy=Always \
      --overrides='{"spec": {"imagePullSecrets": [{"name": "'${HARBOR_PULL_SECRET_NAME}'"}]}}' \
      -- sqlplus sys/${ADMIN_PASSWORD}@broker-blue-green:1521/ORCLPDB1 as sysdba
    
  2. יוצרים טבלת בדיקה:

    CREATE TABLE employees (id NUMBER, name VARCHAR2(50));
    INSERT INTO employees VALUES (1, 'John Doe');
    COMMIT;
    SELECT * FROM employees;
    exit;
    

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

            ID NAME
    ---------- --------------------------------------------------
            1 John Doe
    

קריאה ממצב המתנה (גישה ישירה)

  1. פורסים pod זמני כדי להתחבר ישירות לשירות הגיבוי:

    kk run sqlplus -n ${DB_NAMESPACE} --rm -it --restart=Never \
      --image=${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-instantclient:latest \
      --image-pull-policy=Always \
      --overrides='{"spec": {"imagePullSecrets": [{"name": "'${HARBOR_PULL_SECRET_NAME}'"}]}}' \
      -- sqlplus sys/${ADMIN_PASSWORD}@${DB_NAME_GREEN}:1521/ORCLPDB1 as sysdba
    
  2. מאמתים את שכפול הנתונים:

    SELECT * FROM employees;
    exit;
    

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

            ID NAME
    ---------- --------------------------------------------------
            1 John Doe
    

ביצוע מעבר ידני

מפעילים מעבר ידני כדי להפוך את התפקידים, כך שמסד הנתונים הירוק יהיה הראשי החדש. המפעיל צריך את ה-SID (לדוגמה, ORCLGREEN) של יעד המעבר.

  1. מריצים את הפקודה הבאה:

    kk patch dataguardbroker broker-blue-green -n ${DB_NAMESPACE} --type='merge' \
      -p "{\"spec\":{\"setAsPrimaryDatabase\":\"ORCLGREEN\"}}"
    
  2. עוקבים אחרי התקדמות המעבר:

    kk get sidb -n ${DB_NAMESPACE} -w
    

    אחרי שהמעבר יושלם, הפלט אמור להיראות כך:

    NAME             EDITION      STATUS    ROLE
    database-blue    Enterprise   Healthy   PHYSICAL_STANDBY
    database-green                Healthy   PRIMARY
    
  3. מוודאים שהמכונות של מסד הנתונים החליפו תפקידים, ושהמסד הירוק הוא עכשיו הראשי:

    kk get dataguardbroker -n ${DB_NAMESPACE}
    

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

    NAME                PRIMARY     STANDBYS   PROTECTION MODE
    broker-blue-green   ORCLGREEN   ORCLBLUE   MaxAvailability
    
  4. מוודאים שנקודות הקצה של השירות broker-blue-green עודכנו כך שהן מצביעות על כתובת ה-IP של ה-pod הירוק:

    kk get endpoints -n ${DB_NAMESPACE} broker-blue-green
    

    הפלט אמור להיראות כך, כאשר כתובת ה-IP של ה-Pod הירוק אמורה להופיע במקום GREEN_POD_IP:

    NAME                ENDPOINTS
    broker-blue-green   [GREEN_POD_IP]:5500,[GREEN_POD_IP]:1521
    

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