שכפול דיסק באמצעות שיבוטים

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

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

במאמר הזה מוסבר איך פועלים שיבוטי דיסקים ואיך יוצרים שיבוט דיסק.

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

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

סיכום של תרחישי השימוש

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

בטבלה הזו מפורטים סוגי השיבוטים השונים שנתמכים ב-Compute Engine.

סוג השכפול מתי משתמשים סוגי הדיסקים הנתמכים
שכפול של דיסק אחסון מקומי מדיסק אחסון מקומי יצירת עותק זהה של דיסק באותו אזור לכל אחת מהמשימות הבאות:
  • הרחבה אופקית של עומסי עבודה על ידי שכפול דיסקים קיימים למכונות וירטואליות חדשות.
  • סביבות Staging, ניפוי באגים או בדיקה עם נתוני ייצור.
  • סריקת דיסק שנמצא בייצור לאיתור תוכנות זדוניות.
  • העברת דיסק לפרויקט חדש.
  • Persistent Disk: דיסק מתמיד רגיל, מאוזן ו-SSD
  • ‫Google Cloud Hyperdisk: כל סוגי ה-Hyperdisk, חוץ מ-Hyperdisk Balanced High Availability
שכפול אזורי של דיסק אחסון מקומי
  • הפיכת עומס עבודה אזורי לזמין מאוד על ידי הוספת רפליקה של הנתונים באזור אחר.
  • סריקת דיסק שנמצא בייצור לאיתור תוכנות זדוניות.
  • יצירת דיסק אתחול אזורי מדיסק אתחול של אזור.
  • Persistent Disk: דיסק מתמיד רגיל, מאוזן ו-SSD
  • ‫Hyperdisk: ‏Hyperdisk Extreme ו-Hyperdisk Balanced
שכפול אזורי של דיסק אזורי יצירת עותק זהה של דיסק אזורי באותו אזור בשביל:
  • בדיקה או הרחבה אופקית בהתאם לעומס (scale out) של עומסי עבודה אזוריים עם זמינות גבוהה (HA).
  • שמירה על יתירות נתונים בשני אזורים בזמן ביצוע משימות ניהול או בדיקות.
  • יצירת עותקים של אמצעי אחסון של מסד נתונים בזמינות גבוהה (HA) לצורך אימות.
  • Persistent Disk: דיסק מתמיד מאוזן אזורי, SSD ודיסק מתמיד סטנדרטי
  • ‫Hyperdisk: ‏Hyperdisk Balanced High Availability

איך פועל שכפול דיסקים

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

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

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

  • ביצועים: בנפחי Hyperdisk, אפשר לציין מגבלת ביצועים שונה לשכפול. שיבוטים אזוריים של נפחי Hyperdisk אזוריים הם נפחי Hyperdisk Balanced High Availability, ויכול להיות שיש להם מגבלות ביצועים שונות.

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

  • סוג: שיבוטים אזוריים של נפחי Hyperdisk Balanced או Hyperdisk Extreme באזור הם נפחי Hyperdisk Balanced High Availability.

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

בדרך כלל, Compute Engine משכפל דיסקים של נתונים (לא לאתחול) בקנה מידה של מפתחים עד 32GiB בפחות מ-10 שניות. בדיסקים של נתונים ברמה ארגונית, שנבדקו ב-1 TiB, שכפולים בדרך כלל מסתיימים תוך פחות מדקה.

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

נפחי Hyperdisk אזוריים ששוכפלו מנפחי Hyperdisk באזורים ספציפיים

שיבוט אזורי של נפח Hyperdisk קיים באזור תמיד יהיה נפח Hyperdisk Balanced High Availability חדש. הסיבה לכך היא ש-Hyperdisk Balanced High Availability הוא ה-Hyperdisk האזורי היחיד שנתמך.

הדרך ליצור Hyperdisk אזורי מ-Hyperdisk של אזור מסוים תלויה בסוג שלו.

ביצועים של נפחי Hyperdisk Balanced High Availability ששוכפלו מדיסקים אזוריים

כשיוצרים נפח חדש של Hyperdisk Balanced High Availability מנפח של Hyperdisk Balanced או Hyperdisk Extreme, הדיסק החדש מקבל את הגודל של דיסק המקור, אבל אפשר לציין גודל אחר.

יכול להיות שהביצועים המקסימליים שהוקצו לדיסק החדש יהיו נמוכים יותר מאלה של דיסק המקור, כי מגבלות הביצועים של Hyperdisk Extreme ו-Hyperdisk Balanced גבוהות יותר מאלה של Hyperdisk Balanced High Availability, כמו שמופיע בטבלה הבאה.

סוג Hyperdisk מספר מקסימלי של פעולות קלט/פלט לשנייה (IOPS) קצב העברת נתונים מקסימלי ( MiB לשנייה)
Hyperdisk Balanced High Availability 100,000 2,400
Hyperdisk Balanced 160,000 2,400
Hyperdisk Extreme 350,000 5,000

אתם יכולים לציין מגבלות לדיסק האזורי החדש, אבל המגבלות לא יכולות לחרוג ממגבלות הביצועים המקסימליות של Hyperdisk Balanced High Availability – ‏100,000‎ IOPS ו-2,400MiB לשנייה.

אם לא מציינים מגבלת ביצועים לדיסק החדש, Compute Engine מקצה את הדיסק עם קצב ה-IOPS וקצב העברת הנתונים שמוגדרים כברירת מחדל, בהתאם לגודל של נפח ה-Hyperdisk Balanced High Availability. במאמר מגבלות ברירת המחדל של הגודל והביצועים של Hyperdisk Balanced High Availability מפורטות מגבלות ברירת המחדל.

כדי להגיע ל-100,000 פעולות קלט/פלט לשנייה, הנפח של Hyperdisk Balanced High Availability צריך להיות לפחות 200GiB, אז יכול להיות שתצטרכו גם להגדיל את הנפח שהוקצה לשכפול האזורי.

דוגמה

נניח שיש לכם נפח Hyperdisk Extreme של ‎150 GiB,‏ hdx-1, שהוקצו לו 180,000‎ IOPS.

אם יוצרים עותק אזורי של hdx-1 ולא מציינים גודל חדש או מגבלת ביצועים, הדיסק האזורי החדש הוא נפח Hyperdisk Balanced High Availability בגודל 150GiB עם מגבלת ברירת המחדל של IOPS לגודל הזה: 3,900 IOPS.

מספר ה-IOPS המקסימלי שאפשר לציין לנפח Hyperdisk Balanced High Availability של 150GiB הוא 75,000, על סמך הנוסחאות שמתוארות בקטע מגבלות על IOPS שניתן להגדרה לנפחי Hyperdisk Balanced High Availability.

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

נפחים של דיסקים לאחסון מתמיד אזורי ששוכפלו מנפחים של דיסקים לאחסון מתמיד של תחום מוגדר

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

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

  • מגבלות ביצועים נמוכות יותר: יכול להיות שלשכפולים אזוריים של Persistent Disk יהיו מגבלות ביצועים נמוכות יותר של IOPS ותפוקה מאשר לדיסק המקור. הסיבה לכך היא שב-Persistent Disk אזורי יש מגבלות ביצועים מקסימליות גבוהות יותר למכונות. לדוגמה, לדיסק אחסון מתמיד מאוזן אזורי יש מגבלת מכונה מקסימלית של 80,000 פעולות קלט/פלט לשנייה בכתיבה, אבל לדיסק אחסון מתמיד מאוזן אזורי יש מגבלה של 60,000 פעולות קלט/פלט לשנייה בכתיבה.

    כדי לראות את מגבלות הביצועים המפורטות, השוו בין מגבלות הביצועים של Persistent Disk אזורי לבין מגבלות הביצועים של Persistent Disk של תחום מוגדר.

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

סוגי הדיסקים הנתמכים

אתם יכולים לשכפל את כל הסוגים של Persistent Disk ו-Hyperdisk, אם השכפול נמצא באותו מיקום (אזור או תחום) כמו דיסק המקור.

אפשר לשכפל דיסק אזורי לדיסק אזורי רק בסוגי הדיסקים הבאים:

  • Hyperdisk:

    • Hyperdisk Balanced
    • Hyperdisk Extreme

    כדי ליצור דיסק אזורי מנפח Hyperdisk ML או Hyperdisk Throughput, פועלים לפי השלבים שמפורטים במאמר שינוי דיסק אזורי לנפח Hyperdisk Balanced High Availability.

  • Persistent Disk:

    • דיסק אחסון מתמיד מאוזן
    • דיסק מתמיד שמבוסס על SSD
    • דיסק מתמיד סטנדרטי

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

הגבלות

ההגבלות והמגבלות הבאות חלות על שיבוטי דיסקים.

מגבלות כלליות

המגבלות הבאות חלות על כל פעולות השכפול של דיסקים.

  • אי אפשר לשכפל דיסק שנמצא במאגר Hyperdisk.
  • הגודל של השכפול חייב להיות לפחות בגודל של דיסק המקור. אם יוצרים שכפול באמצעות מסוף Google Cloud , אי אפשר לציין את גודל הדיסק, והשכפול יהיה באותו גודל של דיסק המקור.
  • אי אפשר ליצור שיבוט של דיסק אחסון מקומי קיים באזור אחר.
  • אי אפשר למחוק את דיסק המקור בזמן שנוצר השיבוט שלו.
  • אי אפשר להפעיל את המכונה שאליה מחובר דיסק המקור בזמן שנוצר השיבוט.
  • אם דיסק המקור סומן למחיקה יחד עם המכונה שאליה הוא מחובר, אי אפשר למחוק את המכונה בזמן שנוצר השיבוט.
  • אם משכפלים נפח של Hyperdisk או Persistent Disk ממסוף Google Cloud , אי אפשר לציין את הביצועים שהוקצו לדיסק המשוכפל.
  • אם אתם משתמשים במפתח הצפנה באספקת הלקוח (CSEK) (הוצא משימוש) או במפתח הצפנה בניהול הלקוח (CMEK) כדי להצפין את דיסק המקור, אתם צריכים להשתמש באותו מפתח כדי להצפין את השכפול.

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

  • אי אפשר ליצור דיסק אחסון מקומי על ידי שכפול של דיסק אחסון אזורי.

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

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

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

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

  • אי אפשר ליצור דיסק אזורי על ידי שכפול של דיסק המקור אם דיסק המקור הוא נפח Hyperdisk ML או Hyperdisk Throughput. צריך ליצור נפח חדש של Hyperdisk Balanced High Availability מקובץ snapshot של הדיסק האזורי.

מגבלות קצב לשכפול דיסקים

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

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

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

    • אפשר ליצור שיבוט אחד של דיסק מקור נתון או של השיבוטים שלו כל 30 שניות.
    • אפשר ליצור עד 1,000 שיבוטים בו-זמנית של דיסק מקור נתון או של השיבוטים שלו. חריגה מהמגבלה הזו מחזירה את השגיאה internalError. עם זאת, אם יוצרים שיבוט של דיסק ומוחקים אותו מאוחר יותר, השיבוט שנמחק לא נכלל במגבלה הזו.
    • אחרי שמשכפלים דיסק, כל השכפולים הבאים של הדיסק הזה או של השכפולים שלו נספרים במגבלה של 1,000 שכפולי דיסקים בו-זמנית לדיסק המקור המקורי, ונספרים במגבלה של יצירת שכפול אחד לכל היותר כל 30 שניות.
  • אם אתם יוצרים דיסק אזורי על ידי שכפול של דיסק אחסון מקומי, אתם יכולים לשכפל עד 1TiB של קיבולת כל 15 דקות, עם מגבלת בקשות מתפרצות של 257TiB.

הודעות שגיאה

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

RATE LIMIT: ERROR: (gcloud.compute.disks.create) Could not fetch resource:
 - Operation rate exceeded for resource RESOURCE. Too frequent operations from the source resource.

יצירת שיבוטים של דיסקים

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

בקטעים הבאים מפורטים השלבים ליצירת שיבוט של דיסק, בהתאם לסוג השיבוט:

יצירת שיבוט של דיסק באותו מיקום של המקור

בקטע הזה מוסבר איך ליצור שכפול של דיסק קיים שנמצא באותו תחום (zone) כמו דיסק המקור, לדיסקים אחסון מקומי, או באותו אזור כמו דיסק המקור, לדיסקים אזוריים. אפשר להשתמש במסוף Google Cloud , ב-Google Cloud CLI, ב-REST או בספריות הלקוח ב-Cloud.

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

מסוף Google Cloud

  1. נכנסים לדף Disks במסוף Google Cloud .

    לפתיחת הדף Disks

  2. ברשימת הדיסקים, עוברים לדיסק שרוצים לשכפל.

  3. בעמודה Actions, לוחצים על לחצן התפריט ובוחרים באפשרות Clone disk.

    יוצרים שיבוט.

    בחלונית Clone disk שמופיעה:

    1. בשדה Name, מציינים שם לדיסק המשוכפל.
    2. אופציונלי: עבור דיסקי אחסון מקומי, תחת Location, ודאו שהאפשרות Single zone מסומנת.
    3. בקטע Properties, בודקים את הפרטים האחרים של הדיסק המשוכפל.
    4. כדי לסיים את יצירת הדיסק המשוכפל, לוחצים על Create.

Google Cloud CLI

כדי לשכפל דיסק מקור אזורי וליצור דיסק אזורי חדש, מריצים את הפקודה disks create ומציינים את הדגל --source-disk:

gcloud compute disks create TARGET_DISK_NAME \
    --description="cloned disk" \
    --source-disk=projects/PROJECT_ID/zones/ZONE/disks/SOURCE_DISK_NAME

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

  • ‫TARGET_DISK_NAME: השם של הדיסק החדש.
  • ‫PROJECT_ID: מזהה הפרויקט שבו רוצים לשכפל את הדיסק.
  • ‫ZONE: האזור של המקור והדיסק החדש.
  • ‫SOURCE_DISK_NAME: שם דיסק המקור.

Terraform

כדי ליצור שכפול של דיסק, משתמשים במשאב google_compute_disk.

resource "google_compute_disk" "default" {
  name  = "disk-name1"
  type  = "pd-ssd"
  zone  = "us-central1-a"
  image = "debian-13-trixie-v20260908"
  labels = {
    environment = "dev"
  }
  physical_block_size_bytes = 4096
}

כדי ללמוד איך להחיל הגדרות ב-Terraform או להסיר אותן, ראו פקודות בסיסיות ב-Terraform.

המשך

Go

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Go במדריך למתחילים של Compute Engine באמצעות ספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Compute Engine Go API.

כדי לבצע אימות ב-Compute Engine, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
	"google.golang.org/protobuf/proto"
)

// createDiskFromDisk creates a new disk with the contents of
// an already existitng disk. Type, and size and zone may differ.
func createDiskFromDisk(
	w io.Writer,
	projectID, zone, diskName, diskType, sourceDiskLink string,
	diskSizeGb int64,
) error {
	// projectID := "your_project_id"
	// zone := "us-west3-b" // should match diskType below
	// diskName := "your_disk_name"
	// diskType := "zones/us-west3-b/diskTypes/pd-ssd"
	// sourceDiskLink := "projects/your_project_id/global/disks/disk_name"
	// diskSizeGb := 120

	ctx := context.Background()
	disksClient, err := compute.NewDisksRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewDisksRESTClient: %w", err)
	}
	defer disksClient.Close()

	req := &computepb.InsertDiskRequest{
		Project: projectID,
		Zone:    zone,
		DiskResource: &computepb.Disk{
			Name:       proto.String(diskName),
			Zone:       proto.String(zone),
			Type:       proto.String(diskType),
			SourceDisk: proto.String(sourceDiskLink),
			SizeGb:     proto.Int64(diskSizeGb),
		},
	}

	op, err := disksClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create disk: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Disk created\n")

	return nil
}

Java

Java

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Java במדריך למתחילים של Compute Engine באמצעות ספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Compute Engine Java API.

כדי לבצע אימות ב-Compute Engine, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.


import com.google.cloud.compute.v1.Disk;
import com.google.cloud.compute.v1.DisksClient;
import com.google.cloud.compute.v1.Operation;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateFromSource {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Cloud project you want to use.
    String project = "YOUR_PROJECT_ID";

    // Name of the zone in which you want to create the disk.
    String zone = "europe-central2-b";

    // Name of the disk you want to create.
    String diskName = "YOUR_DISK_NAME";

    // The type of disk you want to create. This value uses the following format:
    // "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
    // For example: "zones/us-west3-b/diskTypes/pd-ssd"
    String diskType = String.format("zones/%s/diskTypes/pd-ssd", zone);

    // Size of the new disk in gigabytes.
    int diskSizeGb = 10;

    // A link to the disk you want to use as a source for the new disk.
    // This value uses the following format:
    // "projects/{project_name}/zones/{zone}/disks/{disk_name}"
    String diskLink = String.format("projects/%s/zones/%s/disks/%s", "PROJECT_NAME", "ZONE",
        "DISK_NAME");

    createDiskFromDisk(project, zone, diskName, diskType, diskSizeGb, diskLink);
  }

  // Creates a disk in a project in a given zone.
  public static void createDiskFromDisk(String project, String zone, String diskName,
      String diskType, int diskSizeGb, String diskLink)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the `disksClient.close()` method on the client to safely
    // clean up any remaining background resources.
    try (DisksClient disksClient = DisksClient.create()) {

      // Create the disk.
      Disk disk = Disk.newBuilder()
          .setZone(zone)
          .setSizeGb(diskSizeGb)
          .setSourceDisk(diskLink)
          .setType(diskType)
          .setName(diskName)
          .build();

      // Wait for the insert instance operation to complete.
      Operation operation = disksClient.insertAsync(project, zone, disk)
          .get(3, TimeUnit.MINUTES);

      if (operation.hasError()) {
        System.out.println("Disk creation failed!");
        throw new Error(operation.getError().toString());
      }
      System.out.println(
          "Disk created from source. Operation Status: " + operation.getStatus());
    }
  }
}

Python

Python

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Python במדריך למתחילים של Compute Engine באמצעות ספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Compute Engine Python API.

כדי לבצע אימות ב-Compute Engine, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

from __future__ import annotations

import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    Waits for the extended (long-running) operation to complete.

    If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result


def create_disk_from_disk(
    project_id: str,
    zone: str,
    disk_name: str,
    disk_type: str,
    disk_size_gb: int,
    disk_link: str,
) -> compute_v1.Disk:
    """
    Creates a disk in a project in a given zone.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone in which you want to create the disk.
        disk_name: name of the disk you want to create.
        disk_type: the type of disk you want to create. This value uses the following format:
            "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
            For example: "zones/us-west3-b/diskTypes/pd-ssd"
        disk_size_gb: size of the new disk in gigabytes
        disk_link: a link to the disk you want to use as a source for the new disk.
            This value uses the following format: "projects/{project_name}/zones/{zone}/disks/{disk_name}"

    Returns:
        An attachable disk.
    """
    disk_client = compute_v1.DisksClient()
    disk = compute_v1.Disk()
    disk.zone = zone
    disk.size_gb = disk_size_gb
    disk.source_disk = disk_link
    disk.type_ = disk_type
    disk.name = disk_name
    operation = disk_client.insert(project=project_id, zone=zone, disk_resource=disk)

    wait_for_extended_operation(operation, "disk creation")

    return disk_client.get(project=project_id, zone=zone, disk=disk_name)

REST

כדי לשכפל דיסק מקור אזורי וליצור דיסק אזורי חדש, שולחים בקשת POST ל-method compute.disks.insert. בגוף הבקשה, מציינים את הפרמטרים name ו-sourceDisk. הדיסק המשוכפל יורש את כל המאפיינים שהושמטו מדיסק המקור.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/disks

{
  "name": "TARGET_DISK_NAME"
  "sourceDisk": "projects/PROJECT_ID/zones/ZONE/disks/SOURCE_DISK_NAME"
}

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

  • ‫PROJECT_ID: מזהה הפרויקט שבו רוצים לשכפל את הדיסק.
  • ‫ZONE: האזור של המקור והדיסק החדש.
  • ‫TARGET_DISK_NAME: השם של הדיסק החדש.
  • ‫SOURCE_DISK_NAME: השם של דיסק המקור

יצירת שיבוט של דיסק אזורי מדיסק אחסון מקומי

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

  • Hyperdisk Balanced
  • Hyperdisk Extreme
  • דיסק מתמיד רגיל, מאוזן ו-SSD

אי אפשר ליצור דיסק אזורי על ידי שכפול של דיסק המקור אם דיסק המקור הוא נפח Hyperdisk ML או Hyperdisk Throughput. צריך ליצור נפח חדש של Hyperdisk Balanced High Availability מקובץ snapshot של הדיסק האזורי.

אם דיסק המקור הוא נפח Hyperdisk Balanced או Hyperdisk Extreme, הדיסק האזורי הוא תמיד נפח Hyperdisk Balanced High Availability והוא לא מקבל בירושה את הביצועים שהוקצו לדיסק האחסון המקומי. אם לא מציינים גודל, או אם משכפלים את הדיסק באמצעות מסוף Google Cloud , ‏Compute Engine יוצר את הדיסק החדש עם מגבלות הביצועים שמוגדרות כברירת מחדל לגודל שלו.

כדי להגדיר את הגודל, ובדיסקים מסוג Hyperdisk Balanced High Availability, את הביצועים שהוקצו לדיסק האזורי, צריך לשכפל את הדיסק באמצעות Google Cloud CLI או REST. אי אפשר להשתמש במסוף Google Cloud .

המסוף

  1. נכנסים לדף Disks במסוף Google Cloud .

    לפתיחת הדף Disks

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

  3. בעמודה Actions, לוחצים על לחצן התפריט ובוחרים באפשרות Clone disk.

    יוצרים שיבוט.

    בחלונית Clone disk שמופיעה:

    1. בשדה Name, מציינים שם לדיסק המשוכפל.
    2. בשדה Location, בוחרים באפשרות Regional ואז בוחרים את אזור הרפליקה המשני של הדיסק המשוכפל האזורי החדש.
    3. בקטע Properties, בודקים את הפרטים האחרים של הדיסק המשוכפל.
    4. כדי לסיים את יצירת הדיסק המשוכפל, לוחצים על Create.

gcloud

כדי ליצור שיבוט של דיסק אזורי מדיסק מקומי, מריצים את הפקודה gcloud compute disks create ומציינים את הפרמטרים --region ו---replica-zones.

אם הדיסק האזורי הוא נפח Hyperdisk Balanced או Hyperdisk Extreme, צריך לציין את הדגל --type=hyperdisk-balanced-high-availability כי הדיסק האזורי חייב להיות נפח Hyperdisk Balanced High Availability. אם אתם מציינים ביצועים שהוקצו, אתם צריכים לציין גם את גודל הדיסק, גם אם הוא זהה לגודל של דיסק המקור.

כדי לשכפל דיסק לאחסון מתמיד, משמיטים את הדגל --type.

gcloud compute disks create TARGET_DISK_NAME \
  --description="zonal to regional cloned disk" \
  --region=CLONED_REGION \
  --source-disk=SOURCE_DISK_NAME \
  --source-disk-zone=SOURCE_DISK_ZONE \
  --replica-zones=SOURCE_DISK_ZONE,REPLICA_ZONE_2 \
  --project=PROJECT_ID \
  --type=hyperdisk-balanced-high-availability  \
  --size=DISK_SIZE \
  --provisioned-iops=IOPS_LIMIT  \
  --provisioned-throughput=THROUGHPUT_LIMIT

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

  • ‫TARGET_DISK_NAME: השם של השכפול החדש של הדיסק האזורי.
  • ‫CLONED_REGION: האזור של דיסק המקור והדיסק המשוכפל.
  • ‫SOURCE_DISK_NAME: השם של הדיסק האזורי שרוצים לשכפל.
  • ‫SOURCE_DISK_ZONE: האזור של דיסק המקור. זה יהיה גם אזור הרפליקה הראשון של השכפול של הדיסק האזורי.
  • ‫REPLICA_ZONE_2: אזור הרפליקה השני של השכפול החדש של הדיסק האזורי.
  • ‫PROJECT_ID: מזהה הפרויקט שבו רוצים לשכפל את הדיסק.
  • ‫DISK_SIZE: אופציונלי: הגודל של הדיסק האזורי החדש, ב-GB. הגודל חייב להיות לפחות כמו הגודל של דיסק המקור. אם אתם מציינים מגבלת IOPS או מגבלת תפוקה, אתם צריכים להשתמש בדגל הזה כדי לציין את גודל הדיסק, גם אם הוא זהה לדיסק המקור.
  • ‫IOPS_LIMIT: אופציונלי: כדי ליצור דיסק Hyperdisk Balanced High Availability אזורי, אפשר לציין מספר פעולות IOPS שהדיסק יכול לבצע, עד 100,000 פעולות IOPS. אם כוללים את הדגל הזה, צריך לציין גם את גודל הדיסק באמצעות הדגל --size.
  • ‫THROUGHPUT_LIMIT: אופציונלי: כדי ליצור דיסק אזורי מסוג Hyperdisk Balanced High Availability, אתם יכולים לציין את קצב הנתונים המקסימלי ב-MiB לשנייה שהדיסק יכול להגיע אליו, עד 2,400MiB לשנייה. אם כוללים את הדגל הזה, צריך לציין גם את גודל הדיסק באמצעות הדגל --size.

Terraform

כדי ליצור שיבוט של דיסק אזורי מדיסק של אזור, משתמשים במשאב הבא. אם דיסק המקור הוא נפח Hyperdisk Balanced או Hyperdisk Extreme, מגדירים את הארגומנט type לערך hyperdisk-balanced-high-availability.

resource "google_compute_region_disk" "regiondisk" {
  name                      = "region-disk-name"
  snapshot                  = google_compute_snapshot.snapdisk.id
  type                      = "pd-ssd"
  region                    = "us-central1"
  physical_block_size_bytes = 4096
  size                      = 11

  replica_zones = ["us-central1-a", "us-central1-f"]
}

כדי ללמוד איך להחיל הגדרות ב-Terraform או להסיר אותן, ראו פקודות בסיסיות ב-Terraform.

המשך

Go

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Go במדריך למתחילים של Compute Engine באמצעות ספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Compute Engine Go API.

כדי לבצע אימות ב-Compute Engine, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
	"google.golang.org/protobuf/proto"
)

// createRegionalDiskFromDisk creates a new regional disk with the contents of
// an already existitng zonal disk. Disk type and size may differ.
func createRegionalDiskFromDisk(
	w io.Writer,
	projectID, region string, replicaZones []string,
	diskName, diskType, sourceDiskLink string,
	diskSizeGb int64,
) error {
	// projectID := "your_project_id"
	// region := "us-west3" // should match diskType below
	// diskName := "your_disk_name"
	// diskType := "regions/us-west3/diskTypes/pd-ssd"
	// sourceDiskLink := "projects/your_project_id/global/disks/disk_name"
	// diskSizeGb := 120

	// Exactly two replica zones must be specified
	replicaZoneURLs := []string{
		fmt.Sprintf("projects/%s/zones/%s", projectID, replicaZones[0]),
		fmt.Sprintf("projects/%s/zones/%s", projectID, replicaZones[1]),
	}

	ctx := context.Background()
	disksClient, err := compute.NewRegionDisksRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewRegionDisksRESTClient: %w", err)
	}
	defer disksClient.Close()

	req := &computepb.InsertRegionDiskRequest{
		Project: projectID,
		Region:  region,
		DiskResource: &computepb.Disk{
			Name:         proto.String(diskName),
			Region:       proto.String(region),
			Type:         proto.String(diskType),
			SourceDisk:   proto.String(sourceDiskLink),
			SizeGb:       proto.Int64(diskSizeGb),
			ReplicaZones: replicaZoneURLs,
		},
	}

	op, err := disksClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create disk: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Disk created\n")

	return nil
}

Java

Java

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Java במדריך למתחילים של Compute Engine באמצעות ספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Compute Engine Java API.

כדי לבצע אימות ב-Compute Engine, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.


import com.google.cloud.compute.v1.Disk;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.RegionDisksClient;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class RegionalCreateFromSource {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Cloud project you want to use.
    String project = "YOUR_PROJECT_ID";

    // Name of the zone in which you want to create the disk.
    String region = "europe-central2";

    // An iterable collection of zone names in which you want to keep
    // the new disks' replicas. One of the replica zones of the clone must match
    // the zone of the source disk.
    List<String> replicaZones = new ArrayList<>();

    // Name of the disk you want to create.
    String diskName = "YOUR_DISK_NAME";

    // The type of disk you want to create. This value uses the following format:
    // "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
    // For example: "zones/us-west3-b/diskTypes/pd-ssd"
    String diskType = String.format("zones/%s/diskTypes/pd-ssd", "ZONE_NAME");

    // Size of the new disk in gigabytes.
    int diskSizeGb = 10;

    // A link to the disk you want to use as a source for the new disk.
    // This value uses the following format:
    // "projects/{project_name}/zones/{zone}/disks/{disk_name}"
    String diskLink = String.format("projects/%s/zones/%s/disks/%s", "PROJECT_NAME", "ZONE",
        "DISK_NAME");

    // A link to the snapshot you want to use as a source for the new disk.
    // This value uses the following format:
    // "projects/{project_name}/global/snapshots/{snapshot_name}"
    String snapshotLink = String.format("projects/%s/global/snapshots/%s", "PROJECT_NAME",
        "SNAPSHOT_NAME");

    createRegionalDisk(project, region, replicaZones, diskName, diskType, diskSizeGb,
        Optional.ofNullable(diskLink), Optional.ofNullable(snapshotLink));
  }

  // Creates a regional disk from an existing zonal disk in a given project.
  public static void createRegionalDisk(
      String project, String region, List<String> replicaZones, String diskName, String diskType,
      int diskSizeGb, Optional<String> diskLink, Optional<String> snapshotLink)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the `regionDisksClient.close()` method on the client to safely
    // clean up any remaining background resources.
    try (RegionDisksClient regionDisksClient = RegionDisksClient.create()) {

      Disk.Builder diskBuilder = Disk.newBuilder()
          .addAllReplicaZones(replicaZones)
          .setName(diskName)
          .setType(diskType)
          .setSizeGb(diskSizeGb)
          .setRegion(region);

      // Set source disk if diskLink is not empty.
      diskLink.ifPresent(diskBuilder::setSourceDisk);

      // Set source snapshot if the snapshot link is not empty.
      snapshotLink.ifPresent(diskBuilder::setSourceSnapshot);

      // Wait for the operation to complete.
      Operation operation = regionDisksClient.insertAsync(project, region, diskBuilder.build())
          .get(3, TimeUnit.MINUTES);

      if (operation.hasError()) {
        System.out.println("Disk creation failed!");
        throw new Error(operation.getError().toString());
      }
      System.out.println(
          "Regional disk created. Operation Status: " + operation.getStatus());
    }
  }
}

Python

Python

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Python במדריך למתחילים של Compute Engine באמצעות ספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Compute Engine Python API.

כדי לבצע אימות ב-Compute Engine, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

from __future__ import annotations

from collections.abc import Iterable
import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    Waits for the extended (long-running) operation to complete.

    If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result


def create_regional_disk(
    project_id: str,
    region: str,
    replica_zones: Iterable[str],
    disk_name: str,
    disk_type: str,
    disk_size_gb: int,
    disk_link: str | None = None,
    snapshot_link: str | None = None,
) -> compute_v1.Disk:
    """
    Creates a regional disk from an existing zonal disk in a given project.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        region: name of the region in which you want to create the disk.
        replica_zones: an iterable collection of zone names in which you want to keep
            the new disks' replicas. One of the replica zones of the clone must match
            the zone of the source disk.
        disk_name: name of the disk you want to create.
        disk_type: the type of disk you want to create. This value uses the following format:
            "regions/{region}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
            For example: "regions/us-west3/diskTypes/pd-ssd"
        disk_size_gb: size of the new disk in gigabytes
        disk_link: a link to the disk you want to use as a source for the new disk.
            This value uses the following format: "projects/{project_name}/zones/{zone}/disks/{disk_name}"
        snapshot_link: a link to the snapshot you want to use as a source for the new disk.
            This value uses the following format: "projects/{project_name}/global/snapshots/{snapshot_name}"

    Returns:
        An attachable regional disk.
    """
    disk_client = compute_v1.RegionDisksClient()
    disk = compute_v1.Disk()
    disk.replica_zones = replica_zones
    disk.size_gb = disk_size_gb
    if disk_link:
        disk.source_disk = disk_link
    if snapshot_link:
        disk.source_snapshot = snapshot_link
    disk.type_ = disk_type
    disk.region = region
    disk.name = disk_name
    operation = disk_client.insert(
        project=project_id, region=region, disk_resource=disk
    )

    wait_for_extended_operation(operation, "disk creation")

    return disk_client.get(project=project_id, region=region, disk=disk_name)

REST

כדי ליצור שיבוט של דיסק אזורי מדיסק של אזור, שולחים בקשת POST אל ה-method‏ compute.disks.insert ומציינים את הפרמטרים sourceDisk ו-replicaZone.

אם דיסק האחסון המקומי הוא נפח Hyperdisk Balanced או Hyperdisk Extreme, צריך לכלול את השדה type כדי ליצור נפח Hyperdisk Balanced High Availability. אם אתם מציינים ביצועים שהוקצו, אתם צריכים לציין גם את גודל הדיסק, גם אם הוא זהה לגודל של דיסק המקור.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/CLONED_REGION/disks

{
  "name": "TARGET_DISK_NAME",
  "sourceDisk": "projects/PROJECT_ID/zones/SOURCE_DISK_ZONE/disks/SOURCE_DISK_NAME",
  "replicaZone": "SOURCE_DISK_ZONE,REPLICA_ZONE_2",
  "type": "projects/PROJECT_ID/regions/CLONED_REGION/diskTypes/hyperdisk-balanced-high-availability",
  "sizeGb": "DISK_SIZE",
  "provisionedIops": "IOPS_LIMIT",
  "provisionedThroughput": "THROUGHPUT_LIMIT"
}

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

  • ‫PROJECT_ID: מזהה הפרויקט שבו רוצים לשכפל את הדיסק.
  • ‫TARGET_DISK_NAME: השם של השכפול החדש של הדיסק האזורי.
  • ‫CLONED_REGION: האזור של דיסק המקור והדיסק המשוכפל.
  • ‫SOURCE_DISK_NAME: השם של הדיסק האזורי שרוצים לשכפל.
  • ‫SOURCE_DISK_ZONE: האזור של דיסק המקור. זה יהיה גם אזור הרפליקה הראשון של השכפול של הדיסק האזורי.
  • ‫REPLICA_ZONE_2: אזור הרפליקה השני של השכפול החדש של הדיסק האזורי.
  • ‫DISK_SIZE: אופציונלי: הגודל של הדיסק האזורי החדש, ב-GB. הגודל חייב להיות לפחות כמו הגודל של דיסק המקור. אם מציינים מגבלת IOPS או מגבלת קצב העברת נתונים, צריך לכלול את השדה הזה כדי לציין את גודל הדיסק, גם אם הוא זהה לדיסק המקור.
  • ‫IOPS_LIMIT: אופציונלי: כדי ליצור דיסק Hyperdisk Balanced High Availability אזורי, אפשר לציין את מספר פעולות ה-IOPS שהדיסק יכול לטפל בהן, עד 100,000 פעולות IOPS. אם כוללים את השדה הזה, צריך לציין גם את גודל הדיסק בשדה size.
  • ‫THROUGHPUT_LIMIT: אופציונלי: כדי ליצור דיסק Hyperdisk Balanced High Availability אזורי, אפשר לציין את קצב הנתונים המקסימלי ב-MiB לשנייה שהדיסק יכול לספק, עד 2,400MiB לשנייה. אם כוללים את השדה הזה, צריך לציין גם את גודל הדיסק בשדה size.

יצירת שיבוט של דיסק מקור שמוצפן באמצעות CMEK או CSEK

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

יצירת שיבוטים של דיסקים שמוצפנים באמצעות CSEK

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

המסוף

  1. נכנסים לדף Disks במסוף Google Cloud .

    לפתיחת הדף Disks

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

  3. בעמודה Actions, לוחצים על לחצן התפריט ובוחרים באפשרות Clone disk.

    יוצרים שיבוט.

    בחלונית Clone disk שמופיעה:

    1. בשדה Name, מציינים שם לדיסק המשוכפל.
    2. בשדה Decryption and encryption, מזינים את מפתח ההצפנה של דיסק המקור.
    3. בקטע Properties, בודקים את הפרטים האחרים של הדיסק המשוכפל.
    4. כדי לסיים את יצירת הדיסק המשוכפל, לוחצים על Create.

gcloud

כדי ליצור שכפול של דיסק מקור שמוצפן באמצעות CSEK, מריצים את הפקודה gcloud compute disks create ומציינים את מפתח ההצפנה של דיסק המקור באמצעות הדגל --csek-key-file. אם אתם משתמשים במפתח עטוף ב-RSA, השתמשו בפקודה gcloud beta compute disks create.

gcloud compute disks create TARGET_DISK_NAME \
  --description="cloned disk" \
  --source-disk=projects/PROJECT_ID/zones/ZONE/disks/SOURCE_DISK_NAME \
  --csek-key-file example-key-file.json

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

  • ‫TARGET_DISK_NAME: השם של הדיסק החדש.
  • ‫PROJECT_ID: מזהה הפרויקט שבו רוצים לשכפל את הדיסק.
  • ‫ZONE: האזור של המקור והדיסק החדש.
  • ‫SOURCE_DISK_NAME: השם של דיסק המקור

המשך

Go

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Go במדריך למתחילים של Compute Engine באמצעות ספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Compute Engine Go API.

כדי לבצע אימות ב-Compute Engine, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
	"google.golang.org/protobuf/proto"
)

// Creates a zonal non-boot persistent disk in a project with the copy of data from an existing disk.
// The encryption key must be the same for the source disk and the new disk.
// The disk type and size may differ.
func createDiskFromCustomerEncryptedDisk(
	w io.Writer,
	projectID, zone, diskName, diskType string,
	diskSizeGb int64,
	diskLink, encryptionKey string,
) error {
	// projectID := "your_project_id"
	// zone := "us-west3-b" // should match diskType below
	// diskName := "your_disk_name"
	// diskType := "zones/us-west3/diskTypes/pd-ssd"
	// diskSizeGb := 120
	// diskLink := "projects/your_project_id/global/disks/disk_name"
	// encryptionKey := "SGVsbG8gZnJvbSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0=" // in base64

	ctx := context.Background()
	disksClient, err := compute.NewDisksRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewDisksRESTClient: %w", err)
	}
	defer disksClient.Close()

	req := &computepb.InsertDiskRequest{
		Project: projectID,
		Zone:    zone,
		DiskResource: &computepb.Disk{
			Name:       proto.String(diskName),
			Zone:       proto.String(zone),
			Type:       proto.String(diskType),
			SizeGb:     proto.Int64(diskSizeGb),
			SourceDisk: proto.String(diskLink),
			DiskEncryptionKey: &computepb.CustomerEncryptionKey{
				RawKey: &encryptionKey,
			},
		},
	}

	op, err := disksClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create disk: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Disk created\n")

	return nil
}

Java

Java

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Java במדריך למתחילים של Compute Engine באמצעות ספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Compute Engine Java API.

כדי לבצע אימות ב-Compute Engine, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.


import com.google.cloud.compute.v1.CustomerEncryptionKey;
import com.google.cloud.compute.v1.Disk;
import com.google.cloud.compute.v1.DisksClient;
import com.google.cloud.compute.v1.InsertDiskRequest;
import com.google.cloud.compute.v1.Operation;
import com.google.protobuf.ByteString;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CloneEncryptedDisk {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Cloud project you want to use.
    String project = "YOUR_PROJECT_ID";

    // Name of the zone in which you want to create the disk.
    String zone = "europe-central2-b";

    // Name of the disk you want to create.
    String diskName = "YOUR_DISK_NAME";

    // The type of disk you want to create. This value uses the following format:
    // "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
    // For example: "zones/us-west3-b/diskTypes/pd-ssd"
    String diskType = String.format("zones/%s/diskTypes/pd-ssd", zone);

    // Size of the new disk in gigabytes.
    int diskSizeGb = 10;

    // A link to the disk you want to use as a source for the new disk.
    // This value uses the following format:
    // "projects/{project_name}/zones/{zone}/disks/{disk_name}"
    String diskLink = String.format("projects/%s/zones/%s/disks/%s", "PROJECT_NAME", "ZONE",
        "DISK_NAME");

    // Customer-supplied encryption key used for encrypting data in the source disk.
    // The data will be encrypted with the same key in the new disk.
    byte[] encryptionKey = null;

    createDiskFromCustomerEncryptedKey(project, zone, diskName, diskType, diskSizeGb, diskLink,
        encryptionKey);
  }

  // Creates a zonal non-boot persistent disk in a project with the copy of data
  // from an existing disk.
  // The encryption key must be the same for the source disk and the new disk.
  public static void createDiskFromCustomerEncryptedKey(String project, String zone,
      String diskName, String diskType, int diskSizeGb, String diskLink, byte[] encryptionKey)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the `disksClient.close()` method on the client to safely
    // clean up any remaining background resources.
    try (DisksClient disksClient = DisksClient.create()) {

      // Create a disk and set the encryption key.
      Disk disk = Disk.newBuilder()
          .setZone(zone)
          .setName(diskName)
          .setType(diskType)
          .setSizeGb(diskSizeGb)
          .setSourceDisk(diskLink)
          .setDiskEncryptionKey(CustomerEncryptionKey
              .newBuilder()
              .setRawKeyBytes(ByteString.copyFrom(encryptionKey))
              .build())
          .build();

      // Wait for the insert disk operation to complete.
      Operation operation = disksClient.insertAsync(
          InsertDiskRequest.newBuilder()
              .setProject(project)
              .setZone(zone)
              .setDiskResource(disk)
              .build()).get(3, TimeUnit.MINUTES);

      if (operation.hasError()) {
        System.out.println("Disk creation failed!");
        throw new Error(operation.getError().toString());
      }
      System.out.println(
          "Disk cloned with customer encryption key. Operation Status: " + operation.getStatus());
    }
  }
}

Python

Python

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Python במדריך למתחילים של Compute Engine באמצעות ספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Compute Engine Python API.

כדי לבצע אימות ב-Compute Engine, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

from __future__ import annotations

import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    Waits for the extended (long-running) operation to complete.

    If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result


def create_disk_from_customer_encrypted_disk(
    project_id: str,
    zone: str,
    disk_name: str,
    disk_type: str,
    disk_size_gb: int,
    disk_link: str,
    encryption_key: bytes,
) -> compute_v1.Disk:
    """
    Creates a zonal non-boot persistent disk in a project with the copy of data from an existing disk.

    The encryption key must be the same for the source disk and the new disk.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone in which you want to create the disk.
        disk_name: name of the disk you want to create.
        disk_type: the type of disk you want to create. This value uses the following format:
            "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
            For example: "zones/us-west3-b/diskTypes/pd-ssd"
        disk_size_gb: size of the new disk in gigabytes
        disk_link: a link to the disk you want to use as a source for the new disk.
            This value uses the following format: "projects/{project_name}/zones/{zone}/disks/{disk_name}"
        encryption_key: customer-supplied encryption key used for encrypting
            data in the source disk. The data will be encrypted with the same key
            in the new disk.

    Returns:
        An attachable copy of an existing disk.
    """
    disk_client = compute_v1.DisksClient()
    disk = compute_v1.Disk()
    disk.zone = zone
    disk.size_gb = disk_size_gb
    disk.source_disk = disk_link
    disk.type_ = disk_type
    disk.name = disk_name
    disk.disk_encryption_key = compute_v1.CustomerEncryptionKey()
    disk.disk_encryption_key.raw_key = encryption_key
    operation = disk_client.insert(project=project_id, zone=zone, disk_resource=disk)

    wait_for_extended_operation(operation, "disk creation")

    return disk_client.get(project=project_id, zone=zone, disk=disk_name)

REST

כדי ליצור שכפול של דיסק מקור שמוצפן באמצעות CSEK, שולחים בקשת POST ל-method‏ compute.disks.insert ומספקים את מפתח ההצפנה של דיסק המקור באמצעות המאפיין diskEncryptionKey. אם אתם משתמשים במפתח עטוף ב-RSA, השתמשו בגרסה beta של ה-method.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/disks

{
  "name": "TARGET_DISK_NAME"
  "sourceDisk": "projects/PROJECT_ID/zones/ZONE/disks/SOURCE_DISK_NAME"
  "diskEncryptionKey": {
    "rsaEncryptedKey": "ieCx/NcW06PcT7Ep1X6LUTc/hLvUDYyzSZPPVCVPTVEohpeHASqC8uw5TzyO9U+Fka9JFHz0mBibXUInrC/jEk014kCK/NPjYgEMOyssZ4ZINPKxlUh2zn1bV+MCaTICrdmuSBTWlUUiFoDD6PYznLwh8ZNdaheCeZ8ewEXgFQ8V+sDroLaN3Xs3MDTXQEMMoNUXMCZEIpg9Vtp9x2oeQ5lAbtt7bYAAHf5l+gJWw3sUfs0/Glw5fpdjT8Uggrr+RMZezGrltJEF293rvTIjWOEB3z5OHyHwQkvdrPDFcTqsLfh+8Hr8g+mf+7zVPEC8nEbqpdl3GPv3A7AwpFp7MA=="
  },
}

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

  • ‫PROJECT_ID: מזהה הפרויקט שבו רוצים לשכפל את הדיסק.
  • ‫ZONE: האזור של המקור והדיסק החדש.
  • ‫TARGET_DISK_NAME: השם של הדיסק החדש.
  • ‫SOURCE_DISK_NAME: השם של דיסק המקור

יצירת שיבוטים של דיסקים שמוצפנים באמצעות CMEK

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

המסוף

‫Compute Engine מצפין באופן אוטומטי את השכפול באמצעות מפתח ההצפנה של דיסק המקור.

gcloud

כדי ליצור שכפול של דיסק מקור שמוצפן באמצעות CMEK, מריצים את הפקודה gcloud compute disks create ומציינים את מפתח ההצפנה של דיסק המקור באמצעות הדגל --kms-key. אם אתם משתמשים במפתח עטוף ב-RSA, השתמשו בפקודה gcloud beta compute disks create.

gcloud compute disks create TARGET_DISK_NAME \
  --description="cloned disk" \
  --source-disk=projects/PROJECT_ID/zones/ZONE/disks/SOURCE_DISK_NAME \
  --kms-key projects/KMS_PROJECT_ID/locations/REGION/keyRings/KEY_RING/cryptoKeys/KEY

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

  • ‫TARGET_DISK_NAME: השם של הדיסק החדש.
  • ‫PROJECT_ID: מזהה הפרויקט שבו רוצים לשכפל את הדיסק.
  • ‫ZONE: האזור של המקור והדיסק החדש.
  • ‫SOURCE_DISK_NAME: שם דיסק המקור.
  • ‫KMS_PROJECT_ID: מזהה הפרויקט של מפתח ההצפנה.
  • ‫REGION: האזור של מפתח ההצפנה.
  • ‫KEY_RING: אוסף המפתחות של מפתח ההצפנה.
  • ‫KEY: השם של מפתח ההצפנה.

המשך

Go

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Go במדריך למתחילים של Compute Engine באמצעות ספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Compute Engine Go API.

כדי לבצע אימות ב-Compute Engine, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
	"google.golang.org/protobuf/proto"
)

// Creates a zonal non-boot persistent disk in a project with the copy of data from an existing disk.
// The encryption key must be the same for the source disk and the new disk.
// The disk type and size may differ.
func createDiskFromKmsEncryptedDisk(
	w io.Writer,
	projectID, zone, diskName, diskType string,
	diskSizeGb int64,
	diskLink, kmsKeyLink string,
) error {
	// projectID := "your_project_id"
	// zone := "us-west3-b" // should match diskType below
	// diskName := "your_disk_name"
	// diskType := "zones/us-west3/diskTypes/pd-ssd"
	// diskSizeGb := 120
	// diskLink := "projects/your_project_id/global/disks/disk_name"
	// kmsKeyLink := "projects/your_kms_project_id/locations/us-central1/keyRings/your_key_ring/cryptoKeys/your_key"

	ctx := context.Background()
	disksClient, err := compute.NewDisksRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewDisksRESTClient: %w", err)
	}
	defer disksClient.Close()

	req := &computepb.InsertDiskRequest{
		Project: projectID,
		Zone:    zone,
		DiskResource: &computepb.Disk{
			Name:       proto.String(diskName),
			Zone:       proto.String(zone),
			Type:       proto.String(diskType),
			SizeGb:     proto.Int64(diskSizeGb),
			SourceDisk: proto.String(diskLink),
			DiskEncryptionKey: &computepb.CustomerEncryptionKey{
				KmsKeyName: &kmsKeyLink,
			},
		},
	}

	op, err := disksClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create disk: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Disk created\n")

	return nil
}

Java

Java

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Java במדריך למתחילים של Compute Engine באמצעות ספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Compute Engine Java API.

כדי לבצע אימות ב-Compute Engine, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.


import com.google.cloud.compute.v1.CustomerEncryptionKey;
import com.google.cloud.compute.v1.Disk;
import com.google.cloud.compute.v1.DisksClient;
import com.google.cloud.compute.v1.InsertDiskRequest;
import com.google.cloud.compute.v1.Operation;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CloneEncryptedDiskManagedKey {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Cloud project you want to use.
    String project = "YOUR_PROJECT_ID";

    // Name of the zone in which you want to create the disk.
    String zone = "europe-central2-b";

    // Name of the disk you want to create.
    String diskName = "YOUR_DISK_NAME";

    // The type of disk you want to create. This value uses the following format:
    // "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
    // For example: "zones/us-west3-b/diskTypes/pd-ssd"
    String diskType = String.format("zones/%s/diskTypes/pd-ssd", zone);

    // Size of the new disk in gigabytes.
    int diskSizeGb = 10;

    // A link to the disk you want to use as a source for the new disk.
    // This value uses the following format:
    // "projects/{project_name}/zones/{zone}/disks/{disk_name}"
    String diskLink = String.format("projects/%s/zones/%s/disks/%s", "PROJECT_NAME", "ZONE",
        "DISK_NAME");

    // URL of the key from KMS. The key might be from another project, as
    // long as you have access to it. The data will be encrypted with the same key
    // in the new disk. This value uses following format:
    // "projects/{kms_project_id}/locations/{region}/keyRings/{key_ring}/cryptoKeys/{key}"
    String kmsKeyName = "kms-key-name";

    createDiskFromKmsEncryptedDisk(project, zone, diskName, diskType, diskSizeGb, diskLink,
        kmsKeyName);
  }

  // Creates a zonal non-boot disk in a project with the copy of data from an existing disk.
  // The encryption key must be the same for the source disk and the new disk.
  public static void createDiskFromKmsEncryptedDisk(String project, String zone, String diskName,
      String diskType, int diskSizeGb, String diskLink, String kmsKeyName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the `disksClient.close()` method on the client to safely
    // clean up any remaining background resources.
    try (DisksClient disksClient = DisksClient.create()) {

      // Create a disk and set the KMS encryption key name.
      Disk disk = Disk.newBuilder()
          .setZone(zone)
          .setName(diskName)
          .setType(diskType)
          .setSizeGb(diskSizeGb)
          .setSourceDisk(diskLink)
          .setDiskEncryptionKey(CustomerEncryptionKey.newBuilder()
              .setKmsKeyName(kmsKeyName)
              .build())
          .build();

      // Wait for the insert disk operation to complete.
      Operation operation = disksClient.insertAsync(
          InsertDiskRequest.newBuilder()
              .setProject(project)
              .setZone(zone)
              .setDiskResource(disk)
              .build()).get(3, TimeUnit.MINUTES);

      if (operation.hasError()) {
        System.out.println("Disk creation failed!");
        throw new Error(operation.getError().toString());
      }
      System.out.println(
          "Disk cloned with KMS encryption key. Operation Status: " + operation.getStatus());
    }
  }
}

Python

Python

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Python במדריך למתחילים של Compute Engine באמצעות ספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Compute Engine Python API.

כדי לבצע אימות ב-Compute Engine, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

from __future__ import annotations

import sys
from typing import Any

from google.api_core.exceptions import BadRequest
from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    Waits for the extended (long-running) operation to complete.

    If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result


def create_disk_from_kms_encrypted_disk(
    project_id: str,
    zone: str,
    disk_name: str,
    disk_type: str,
    disk_size_gb: int,
    disk_link: str,
    kms_key_name: str,
) -> compute_v1.Disk:
    """
    Creates a zonal non-boot disk in a project with the copy of data from an existing disk.

    The encryption key must be the same for the source disk and the new disk.

    To run this method, the service-<project_id>@compute-system.iam.gserviceaccount.com
    service account needs to have the cloudkms.cryptoKeyEncrypterDecrypter role,
    as described in documentation:
    https://cloud.google.com/compute/docs/disks/customer-managed-encryption#before_you_begin

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone in which you want to create the disk.
        disk_name: name of the disk you want to create.
        disk_type: the type of disk you want to create. This value uses the following format:
            "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
            For example: "zones/us-west3-b/diskTypes/pd-ssd"
        disk_size_gb: size of the new disk in gigabytes
        disk_link: a link to the disk you want to use as a source for the new disk.
            This value uses the following format: "projects/{project_name}/zones/{zone}/disks/{disk_name}"
        kms_key_name: URL of the key from KMS. The key might be from another project, as
            long as you have access to it. The data will be encrypted with the same key
            in the new disk. This value uses following format:
            "projects/{kms_project_id}/locations/{region}/keyRings/{key_ring}/cryptoKeys/{key}"

    Returns:
        An attachable copy of an existing disk.
    """
    disk_client = compute_v1.DisksClient()
    disk = compute_v1.Disk()
    disk.zone = zone
    disk.size_gb = disk_size_gb
    disk.source_disk = disk_link
    disk.type_ = disk_type
    disk.name = disk_name
    disk.disk_encryption_key = compute_v1.CustomerEncryptionKey()
    disk.disk_encryption_key.kms_key_name = kms_key_name
    try:
        operation = disk_client.insert(
            project=project_id, zone=zone, disk_resource=disk
        )
    except BadRequest as err:
        if "Permission 'cloudkms.cryptoKeyVersions.useToEncrypt' denied" in err.message:
            print(
                f"Please provide the cloudkms.cryptoKeyEncrypterDecrypter role to"
                f"service-{project_id}@compute-system.iam.gserviceaccount.com"
            )
        raise err

    wait_for_extended_operation(operation, "disk creation")

    return disk_client.get(project=project_id, zone=zone, disk=disk_name)

REST

כדי ליצור שכפול של דיסק מקור שמוצפן באמצעות CMEK, שולחים בקשת POST ל-method‏ compute.disks.insert ומציינים את מפתח ההצפנה של דיסק המקור באמצעות המאפיין kmsKeyName. אם אתם משתמשים במפתח עטוף ב-RSA, השתמשו בגרסה beta של ה-method.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/disks

{
  "name": "TARGET_DISK_NAME"
  "sourceDisk": "projects/PROJECT_ID/zones/ZONE/disks/SOURCE_DISK_NAME"
  "diskEncryptionKey": {
    "kmsKeyName": "projects/KMS_PROJECT_ID/locations/REGION/keyRings/KEY_RING/cryptoKeys/KEY"
  },
}

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

  • ‫PROJECT_ID: מזהה הפרויקט שבו רוצים לשכפל את הדיסק.
  • ‫ZONE: האזור של המקור והדיסק החדש.
  • ‫TARGET_DISK_NAME: השם של הדיסק החדש.
  • ‫SOURCE_DISK_NAME: שם דיסק המקור.
  • ‫KMS_PROJECT_ID: מזהה הפרויקט של מפתח ההצפנה.
  • ‫REGION: האזור של מפתח ההצפנה.
  • ‫KEY_RING: אוסף המפתחות של מפתח ההצפנה.
  • ‫KEY: השם של מפתח ההצפנה.

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