שכפול נפחי אחסון באופן אסינכרוני

בדף הזה מוסבר איך להגדיר ולבצע רפליקציה אסינכרונית של נפחי אחסון בבלוקים של Google Distributed Cloud (GDC) air-gapped.

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

מנהלי פלטפורמות שמנהלים PVC באמצעות KRM API יכולים לקרוא את המאמר שכפול אסינכרוני של נפחים למנהלי פלטפורמות.

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

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

לאחר מכן, ודאו שיש לכם את התפקיד app-volume-replication-admin-global כדי לנהל את המשאב VolumeReplicationRelationship. במקרים שבהם ה-API הגלובלי לא זמין, אפשר להשתמש בתפקיד volume-replication-admin כדי לשנות ישירות את המשאב VolumeReplicationRelationshipReplica ברמת האזור.

הגדרת רפליקציה

המשאב המותאם אישית (CR) של VolumeReplicationRelationship משרת את ה-API של שכפול הבלוקים האסינכרוני. התגובה המוכנה מראש הזו קיימת ב-Management API הגלובלי. כדי להפעיל רפליקציה של התקן בלוקים, צריך ליצור VolumeReplicationRelationship CR ב-Management API לניהול גלובלי:

Replicate PVC API

kubectl --kubeconfig MANAGEMENT_API_SERVER apply -f - <<EOF
apiVersion: storage.global.gdc.goog/v1
kind: VolumeReplicationRelationship
metadata:
  name: VRR_NAME
  namespace: PROJECT
spec:
  source:
    pvc:
      clusterRef: SOURCE_USER_CLUSTER_NAME
      pvcRef: PVC_NAME
    zoneRef: SOURCE_ZONE_NAME
  destination:
    pvc:
      clusterRef: DESTINATION_USER_CLUSTER_NAME
    zoneRef: DESTINATION_ZONE_NAME
EOF

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

  • ‫MANAGEMENT_API_SERVER: הנתיב של kubeconfig לשרת ה-API האזורי.
  • ‫VRR_NAME: השם של המשאב VolumeReplicationRelationship.
  • ‫PROJECT: מרחב השמות של משאב הפרויקט.
  • ‫SOURCE_USER_CLUSTER_NAME: השם של משאב אשכול המשתמשים במקור שרוצים לחבר.
  • ‫PVC_NAME: השם של המשאב PersistentVolumeClaim.
  • ‫SOURCE_ZONE_NAME: השם של משאב האזור המקורי.
  • ‫DESTINATION_USER_CLUSTER_NAME: השם של משאב אשכול המשתמשים שאליו רוצים להתחבר.
  • ‫DESTINATION_ZONE_NAME: השם של משאב האזור של היעד.

בדוגמה הזו, נניח שפרויקט בשם PROJECT נוצר בארגון בשם my-org, ושהוקצה כבר PVC בשם PVC_NAME. ‫SOURCE_USER_CLUSTER_NAME הוא השם של אשכול המקור שבו נמצא ה-PVC, ו-DESTINATION_USER_CLUSTER_NAME הוא השם של אשכול היעד שבו יהיה PVC חדש.

השדות source ו-destination במפרט מציינים מאיפה ולאן הנתונים משוכפלים, בהתאמה. בדוגמה הזו, הנתונים משוכפלים מ-SOURCE_ZONE_NAME אל DESTINATION_ZONE_NAME.

שכפול דיסקים של מכונות וירטואליות

‫VolumeReplicationRelationship גם משרת את ה-API של הרפליקציה האסינכרונית של דיסק המכונה הווירטואלית (VM disk). הדיסק המקורי שמשוכפל נקרא הדיסק הראשי. הדיסק שאליו משכפלים נקרא הדיסק המשני. כשמתחילים רפליקציה אסינכרונית בדיסק ראשי, הדיסק המשני נוצר באופן אוטומטי.

בקשת הרשאות וגישה

כדי לשכפל דיסקים של מכונות וירטואליות, צריך את התפקיד "אדמין של פרויקט מכונות וירטואליות". מוודאים שיש לכם את התפקיד "אדמין של פרויקט מכונה וירטואלית" (project-vm-admin) במרחב השמות של הפרויקט שבו נמצא הדיסק של המכונה הווירטואלית.

כדי לבצע פעולות במכונה וירטואלית באמצעות ה-CLI של gdcloud, בקשו מהאדמין של הפרויקט ב-IAM להקצות לכם את התפקיד "אדמין של פרויקט מכונה וירטואלית" ואת התפקיד "צפייה בפרויקט" (project-viewer).

התחלת רפליקציה אסינכרונית

כדי להתחיל רפליקציה אסינכרונית בדיסק של VM, משתמשים ב-gdcloud CLI או ב-kubectl:

gdcloud

gdcloud compute disks start-async-replication PRIMARY_DISK_NAME \
  --project PROJECT --zone PRIMARY_ZONE \
  --secondary-disk SECONDARY_DISK_NAME --secondary-zone SECONDARY_ZONE

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

משתנההגדרה
PRIMARY_DISK_NAME שם דיסק המקור שמשוכפל.
PROJECT הפרויקט ב-GDC של הדיסק הראשי.
PRIMARY_ZONE האזור שבו נמצא הדיסק הראשי.
SECONDARY_DISK_NAME שם הדיסק שאליו רוצים לשכפל.
SECONDARY_ZONE האזור שבו הדיסק המשני צריך להיות.

VM Disk API

כדי להתחיל רפליקציה אסינכרונית בדיסק של VM, משתמשים ב-kubectl:

kubectl --kubeconfig MANAGEMENT_API_SERVER apply -f - <<EOF
apiVersion: storage.global.gdc.goog/v1
kind: VolumeReplicationRelationship
metadata:
  name: VRR_NAME
  namespace: PROJECT
spec:
  destination:
    volumeOverrideName: VIRTUAL_MACHINE_DESTINATION_DISK_NAME
    zoneRef: DESTINATION_ZONE_NAME
  source:
    virtualMachineDisk:
      virtualMachineDiskRef: VIRTUAL_MACHINE_SOURCE_DISK_NAME
    zoneRef: SOURCE_ZONE_NAME
EOF

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

  • ‫MANAGEMENT_API_SERVER: הנתיב של kubeconfig לשרת ה-API האזורי.
  • ‫VRR_NAME: השם של המשאב VolumeReplicationRelationship.
  • ‫PROJECT: מרחב השמות של משאב הפרויקט.
  • ‫VIRTUAL_MACHINE_DESTINATION_DISK_NAME: השם של המשאב VirtualMachineDisk ביעד.
  • ‫DESTINATION_ZONE_NAME: השם של משאב האזור של היעד.
  • ‫VIRTUAL_MACHINE_SOURCE_DISK_NAME: השם של המשאב VirtualMachineDisk במקור.
  • ‫SOURCE_ZONE_NAME: השם של משאב האזור המקורי.

בדוגמה הזו, נניח שנוצר פרויקט בשם PROJECT בארגון בשם my-org, ושהוקצה כבר VirtualMachineDisk בשם VIRTUAL_MACHINE_SOURCE_DISK_NAME למשאב VirtualMachine.

השדות source ו-destination במפרט מציינים מאיפה הנתונים משוכפלים ולאן, בהתאמה. בדוגמה הזו, הנתונים משוכפלים מ-SOURCE_ZONE_NAME אל DESTINATION_ZONE_NAME.

אימות

כדי לבדוק את הסטטוס של קשר הרפליקציה, מאחזרים את ה-CR של VolumeReplicationRelationship מה-API הגלובלי. הדוגמה הבאה ממחישה את זה. שימו לב שהפלט קוצר כדי לפשט את הדוגמה:

kubectl --kubeconfig MANAGEMENT_API_SERVER get volumereplicationrelationship VRR_NAME \
        -n PROJECT -o yaml

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

PVC API

apiVersion: storage.global.gdc.goog/v1
kind: VolumeReplicationRelationship
metadata:
  name: my-pvc-repl
  namespace: my-project
spec:
  destination:
    pvc:
      clusterRef: my-pvc-cluster
    zoneRef: zone2
  source:
    pvc:
      clusterRef: my-pvc-cluster
      pvcRef: my-block-pvc
    zoneRef: zone1
status:
  zones:
  - name: zone1
    replicaStatus:
      message: SnapMirror relationship has been established. Please check the destination
        zone for relationship state
      replicationID: a096621e-f062-11ef-ad24-00a0b89f23fb
      state: Established
  - name: zone2
    replicaStatus:
      exportedSnapshotName: snapmirror.c34f8845-e8c0-11ef-ad24-00a0b89f23fb_2150007868.2025-02-21_150000
      message: SnapMirror relationship has been successfully established
      replicationID: a096621e-f062-11ef-ad24-00a0b89f23fb
      state: Idle

VM Disk API

apiVersion: storage.global.gdc.goog/v1
kind: VolumeReplicationRelationship
metadata:
  name: my-vmdisk-vrr
  namespace: my-project
spec:
  destination:
    zoneRef: zone2
  source:
    virtualMachineDisk:
      virtualMachineDiskRef: my-vmdisk
    zoneRef: zone1
status:
  zones:
  - name: zone1
    replicaStatus:
      message: SnapMirror relationship has been established. Please check the destination
        zone for relationship state
      replicationID: a096621e-f062-11ef-ad24-00a0b89f23fb
      state: Established
  - name: zone2
    replicaStatus:
      exportedSnapshotName: snapmirror.c34f8845-e8c0-11ef-ad24-00a0b89f23fb_2150007868.2025-02-21_150000
      message: SnapMirror relationship has been successfully established
      replicationID: a096621e-f062-11ef-ad24-00a0b89f23fb
      state: Idle

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

אם אזור המקור לא זמין מסיבה כלשהי, אפשר ליצור בקשת שינוי (CR) של VolumeFailover במישור הניהול של הארגון באזור היעד. בארגון בגרסה 2, זה יהיה שרת ה-API לניהול. בארגון בגרסה 1, זה יהיה אשכול האדמין של הארגון. לדוגמה, אם נוצר VolumeReplicationRelationship שמציין את zone2 כאזור היעד, וקיימים PVC או VirtualMachineDisk בארגון my-org, אז ה-CR של VolumeFailover נוצר במישור הניהול של my-org ב-zone2. הפעולה הזו מנתקת את קשר הרפליקציה בין שני האזורים, ומאפשרת לעומס עבודה לטעון את ה-PVC או את VirtualMachineDisk באזור היעד:

  kubectl --kubeconfig MANAGEMENT_API_SERVER apply -f - <<EOF
  apiVersion: storage.gdc.goog/v1
  kind: VolumeFailover
  metadata:
    name: FAILOVER_NAME
    namespace: PROJECT
  spec:
    volumeReplicationRelationshipRef: VRR_NAME
  EOF

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

  • ‫FAILOVER_NAME: השם של המשאב VolumeFailover.
  • ‫MANAGEMENT_API_SERVER: הנתיב של kubeconfig לשרת ה-API האזורי.
  • ‫VRR_NAME: השם של המשאב VolumeReplicationRelationship.
  • ‫PROJECT: מרחב השמות של משאב הפרויקט.

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

  kubectl --kubeconfig MANAGEMENT_API_SERVER get volumefailover FAILOVER_NAME \
          -n PROJECT -o yaml
  • הפלט אמור להיראות כך:

    apiVersion: storage.gdc.goog/v1
    kind: VolumeFailover
    metadata:
      name: my-failover
      namespace: my-project
    spec:
      volumeReplicationRelationshipRef: my-vrr-repl
    status:
        state: Completed
    
  • אחרי שנוצרת יתירות כשל, ה-my-vrr-repl VolumeReplicationRelationship עובר למצב Broken Off. עכשיו אפשר לטעון את ה-PVC או את ה-VirtualMachineDisk ב-zone2.

  • בשלב הזה, ה-VolumeReplicationRelationship ייראה דומה לדוגמה הבאה. גם כאן, הפלט קוצר כדי לפשט את הדברים:

    kubectl --kubeconfig MANAGEMENT_API_SERVER get volumereplicationrelationship VRR_NAME \
            -n PROJECT -o yaml
    
  • הפלט אמור להיראות כך:

PVC API

apiVersion: storage.global.gdc.goog/v1
kind: VolumeReplicationRelationship
metadata:
  name: my-vrr-repl
  namespace: my-project
spec:
  destination:
    pvc:
      clusterRef: my-pvc-cluster
    zoneRef: zone2
  source:
    pvc:
      clusterRef: my-pvc-cluster
      pvcRef: my-block-pvc
    zoneRef: zone1
status:
  zones:
  - name: zone1
    replicaStatus:
      message: SnapMirror relationship has been broken off
      replicationID: a096621e-f062-11ef-ad24-00a0b89f23fb
      state: Broken Off
  - name: zone2
    replicaStatus:
      exportedSnapshotName: snapmirror.c34f8845-e8c0-11ef-ad24-00a0b89f23fb_2150007868.2025-02-21_150000
      message: SnapMirror relationship has been broken off
      replicationID: a096621e-f062-11ef-ad24-00a0b89f23fb
      state: Broken Off

VM Disk API

apiVersion: storage.global.gdc.goog/v1
kind: VolumeReplicationRelationship
metadata:
  name: my-vmdisk-vrr
  namespace: my-project
spec:
  destination:
    zoneRef: zone2
  source:
    virtualMachineDisk:
      virtualMachineDiskRef: my-vmdisk
    zoneRef: zone1
status:
  zones:
  - name: zone1
    replicaStatus:
      message: SnapMirror relationship has been broken off
      replicationID: a096621e-f062-11ef-ad24-00a0b89f23fb
      state: Broken Off
  - name: zone2
    replicaStatus:
      exportedSnapshotName: snapmirror.c34f8845-e8c0-11ef-ad24-00a0b89f23fb_2150007868.2025-02-21_150000
      message: SnapMirror relationship has been broken off
      replicationID: a096621e-f062-11ef-ad24-00a0b89f23fb
      state: Broken Off
  • עכשיו אפשר למחוק את VolumeReplicationRelationship כי זו הפעולה היחידה שנותרה שאפשר לבצע בבקשת השינוי הזו.

    kubectl --kubeconfig MANAGEMENT_API_SERVER delete volumereplicationrelationship VRR_NAME \
            -n PROJECT
    

שינוי הגודל של אמצעי האחסון

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

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

הצגת רשימה של קשרי רפליקציה אסינכרונית

הצגת רשימה של קשרי רפליקציה אסינכרונית בפרויקט באמצעות kubectl.

kubectl --kubeconfig MANAGEMENT_API_SERVER get volumereplicationrelationships -n PROJECT

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

  • ‫PROJECT: פרויקט GDC של הדיסק הראשי.
  • ‫MANAGEMENT_API_SERVER: קובץ ה-kubeconfig של שרת ה-API לניהול ברמת האזור.

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

NAME       AGE     SOURCE ZONE   SOURCE PVC   SOURCE PVC CLUSTER   SOURCE VM DISK      DEST. ZONE   DEST. PVC CLUSTER   DEST. VOLUME OVERRIDE     STATE
my-vrr     3m21s   zone1                                           my-vm-boot-disk     zone2                            my-vm-boot-disk-replica
test-vrr   7s      zone1                                           test-vm-boot-disk   zone2

הפסקת הרפליקציה האסינכרונית

כדי להפסיק את הרפליקציה האסינכרונית בדיסק של מכונה וירטואלית ראשית, משתמשים ב-gdcloud CLI או ב-kubectl:

gdcloud

gdcloud compute disks stop-async-replication PRIMARY_DISK_NAME \
  --project PROJECT --zone PRIMARY_ZONE

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

משתנההגדרה
PRIMARY_DISK_NAME שם דיסק המקור שמשוכפל.
PROJECT הפרויקט ב-GDC של הדיסק הראשי.
PRIMARY_ZONE האזור שבו נמצא הדיסק הראשי.

API

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

    kubectl --kubeconfig MANAGEMENT_API_SERVER get volumereplicationrelationships \
      -n PROJECT -o json | \
      jq -r '.items[] | select(.spec.source.virtualMachineDisk.virtualMachineDiskRef == "PRIMARY_DISK_NAME"
      and .spec.source.zoneRef == "PRIMARY_ZONE") | .metadata.name'
    
  2. מוחקים כל אחד מקשרי השכפול של הנפחים שמופיעים ברשימה מהשלב הקודם. מחליפים את VRR_NAMES בשמות של קשרי הרפליקציה של הנפח.

    kubectl --kubeconfig MANAGEMENT_API_SERVER delete volumereplicationrelationships \
      -n PROJECT VRR_NAMES
    

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

    משתנההגדרה
    MANAGEMENT_API_SERVER קובץ kubeconfig של שרת ה-API לניהול גלובלי.
    PROJECT הפרויקט ב-GDC של הדיסק הראשי.
    PRIMARY_DISK_NAME שם דיסק המקור שמשוכפל.
    PRIMARY_ZONE האזור שבו נמצא הדיסק הראשי.

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

חיבור הדיסק המשוכפל ל-VM

כשהרפליקציה מופעלת, אי אפשר לצרף את הדיסק המשני למכונה וירטואלית. אחרי שהרפליקציה נעצרת, אפשר לצרף את הדיסק המשני למכונה וירטואלית חדשה או למכונה וירטואלית קיימת.