כשמפעילים את סוכן הגיבוי ל-GKE באשכול Google Kubernetes Engine, Backup for GKE מספק CustomResourceDefinition שמציג סוג חדש של משאב Kubernetes: ProtectedApplication.
יצירת ProtectedApplication כוללת שלוש פעילויות:
בחירת קבוצת המשאבים שרוצים לגבות ולשחזר כחלק מהאפליקציה.
הגדרה של כללי תזמור מפורטים עבור קבוצת משנה של המשאבים האלה.
אימות של
ProtectedApplicationכדי לבדוק אם הוא מוכן לגיבוי.
משאבי ProtectedApplication מספקים את היכולות הבאות כשמתאימים אישית את הלוגיקה של הגיבוי והשחזור ברמת האפליקציה:
פעולות גיבוי ושחזור מפורטות יותר. בלי
ProtectedApplications, צריך להגדיר את היקף הגיבויים ברמהNamespace(על ידי בחירה באפשרות allNamespaces או באפשרות selectedNamespaces). לוגיקה דומה חלה על שחזור משאבים עם מרחב שמות. כשיוצרים משאביProtectedApplication, אפשר לתת שם לקבוצת משנה של המשאבים ב-Namespace. אחר כך תוכלו לגבות ולשחזר את קבוצת המשנה הזו על ידי ציון selectedApplications בהיקף הגיבוי (ובאופן דומה, גם בשביל restore).תיאום פרטים מדויקים של תהליך הגיבוי או השחזור, כולל:
דילוג על אמצעי האחסון שנבחרו במהלך הגיבוי.
שילוב טופולוגיית האפליקציה בגיבוי ובשחזור (לדוגמה, גיבוי רק של מופע אחד של מסד נתונים משוכפל ושימוש בו לשחזור של כמה מופעים).
ביצוע hooks שהוגדרו על ידי המשתמש לפני ואחרי יצירת תמונת מצב של נפחים. אפשר להשתמש בהם, למשל, כדי לנקות את מטמון הנתונים של עומס עבודה ולהעביר אותו למצב השהיה לפני יצירת תמונת מצב, ואז להוציא אותו ממצב השהיה.
יוצרים ProtectedApplication באמצעות kubectl כמו משאבי Kubernetes אחרים.
הן לגמרי אופציונליות. אם לא קיימים משאבי ProtectedApplication, Backup for GKE יוצר גיבויים של נפחים לכל הנפחים בהיקף הגיבוי, והגיבויים של הנפחים שיתקבלו יהיו עקביים במקרה של קריסה – כל הפעולות שבוצעו בכתיבה לדיסק בנקודת זמן מסוימת יתועדו (כלומר, לא יתועדו פעולות כתיבה חלקיות). עם זאת, יכול להיות שחלק מהאפליקציות ישמרו נתונים בזיכרון שלא נמחקו מהדיסק, ולכן היכולת של אפליקציה לשחזר גיבוי עקבי אחרי קריסה תלויה בלוגיקה של האפליקציה.
בחירת משאבים
השלב הראשון ביצירת משאב ProtectedApplication הוא לזהות את המשאבים האחרים באותו Namespace שרוצים לכלול כחלק מהאפליקציה. זהו קבוצת המשאבים שתגובה או תשוחזר אם תספקו את אפשרות ההיקף selectedApplications בהגדרות של BackupPlan.
המשאבים מזוהים באמצעות בורר תוויות.
לשם כך, צריך להוסיף לכל המשאבים את אותה תווית (באמצעות השדה metadata.label בכל משאב). חשוב לציין שההגדרה הזו חלה גם על משאבים שנוצרים באופן אוטומטי על ידי בקרי גישה. המשאבים שנוצרים באופן אוטומטי מסומנים בתווית לפי התבנית המתאימה.
שימו לב שבדרך כלל משתמשים באותה תווית שכבר משמשת לשיוך של Pods ו-PersistentVolumeClaims שנוצרו למשאב ההורה שלהם.
שיקולי השימוש כוללים את הדברים הבאים:
- אם רוצים להגן על משאבים שיוצרים משאבי צאצא, גם למשאבי ההורה (כמו
StatefulSet,DeploymentאוDaemonSet) וגם למשאבי הצאצא (כמוPodאוPersistentVolumeClaim) צריכה להיות התווית שמשמשת בשדהSelectorשל ה-ProtectedApplication. - אם חלק מהמשאבים שאליהם יש הפניה בבורר
ProtectedApplicationנוצרים באופן אוטומטי על ידי אופרטור, צריך לכלול בבוררProtectedApplicationגם את המשאבים המותאמים אישית של האופרטור. כך אפשר להימנע ממצב מרוץ תהליכים בזמן השחזור, שיכול לקרות כשהאופרטור מנסה ליצור משאב בזמן שהוא משוחזר מגיבוי.
בדוגמה הבאה אפשר לראות איך מוסיפים את התווית app: nginx למשאבים אחרים בנוסף ל-Deployment.
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-vars
namespace: webserver
labels:
app: nginx
data:
...
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-logs
namespace: webserver
labels:
app: nginx
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Mi
storageClassName: standard-rwo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: webserver
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
volumes:
- name: nginx-logs
persistentVolumeClaim:
claimName: nginx-logs
containers:
...
אחרי שתווית הבחירה תתווסף לכל משאבי היעד (ולתבניות שמהן נוצרים משאבים נוספים), תוכלו להפנות למשאבים האלה מתוך ProtectedApplication. לדוגמה:
kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1
metadata:
name: nginx
namespace: webserver
spec:
resourceSelection:
type: Selector
selector:
matchLabels:
app: nginx
...
הגדרת כללי תזמור
אחרי שתזהו את כל המשאבים ב-ProtectedApplication, תוכלו להגדיר כללי תזמור מפורטים לחלק מהמשאבים האלה. הכללים האלה חלים רק על שני סוגים של משאבים:
Deployments
ו-StatefulSets, והם מפורטים בקטע components של ProtectedApplication.
סקירה כללית של הרכיבים
הגדרת רכיב כוללת את הפעולות הבאות:
בחירת אסטרטגיה בסיסית לאופן שבו הגיבוי והשחזור יפעלו עבור הרכיב הזה. יש שלוש אסטרטגיות זמינות:
BackupAllRestoreAll– גיבוי של אמצעי האחסון שמשויכים לכל המופעים של הרכיב ושחזור של כולם מהגיבויים.
BackupOneRestoreAll– גיבוי של הכרכים רק ממופע אחד של הרכיב ושימוש בגיבויים האלה לשחזור כל המופעים.
DumpAndLoad– ייצוא נתונים מהאפליקציה לנפח אחסון יחיד בזמן הגיבוי וייבוא הנתונים האלה לאפליקציה בזמן השחזור.
הגדרת hooks להפעלה במהלך הגיבוי (ואולי גם במהלך השחזור, בהתאם לשיטה). Hook היא פקודה שמופעלת בקונטיינרים ספציפיים.
קטעי הוק (hooks) להפעלה
הוק הוא פקודת מעטפת ש-"גיבוי ל-GKE" מריץ בקונטיינר בשלב מסוים בתהליך הגיבוי או השחזור.
יש ארבעה סוגים שונים של הוקים:
pre hooks– הפקודות האלה מופעלות ממש לפני הגיבוי של אמצעי האחסון, ובדרך כלל הן אמורות להעביר את כל הנתונים מהזיכרון לדיסק, ואז להשעות את האפליקציה כדי שלא יתבצעו כתיבות חדשות בדיסק. ה-hooks האלה נמצאים בשימוש בשיטותBackupAllRestoreAllו-BackupOneRestoreAll.
post hooks– הפקודות האלה מופעלות במהלך תהליך הגיבוי של אמצעי האחסון, מיד אחרי השלב SNAPSHOTTING בתהליך הגיבוי של אמצעי האחסון (לפני השלב UPLOADING). בדרך כלל, שלב יצירת התמונה נמשך כמה שניות בלבד. באופן כללי, מצפים מהם לבטל את ההשבתה של האפליקציה (כלומר, לאפשר את המשך העיבוד הרגיל ואת הכתיבה לדיסק). ה-hooks האלה משמשים באסטרטגיותBackupAllRestoreAll,BackupOneRestoreAllו-DumpAndLoad.
dump hooks– הפקודות האלה מופעלות לפני שהגיבוי של אמצעי האחסון מתבצע במסגרת האסטרטגיהDumpAndLoad, ובדרך כלל הן מייצאות נתונים מהאפליקציה אל אמצעי האחסון המיועד לגיבוי.load hooks– הפקודות האלה מופעלות בזמן השחזור אחרי שמשחזרים את נפח הגיבוי במקרים של אסטרטגייתDumpAndLoad. בדרך כלל, הם אמורים לייבא את הנתונים מנפח הגיבוי אל האפליקציה.
אפשר לספק יותר מ-hook אחד לכל סוג, ו-Backup for GKE יפעיל אותם לפי הסדר שבו הגדרתם אותם.
מגדירים את ה-hooks כחלק מקטע הרכיבים במפרט ProtectedApplication. לכל ההגדרות של ה-hook יש את אותם שדות זמינים:
name– השם שאתם מקצים ל-hook.
container– (אופציונלי) שם הקונטיינר שבו תופעל הפקודה. אם לא תספקו את הקונטיינר, Backup for GKE יריץ את ה-hook בקונטיינר הראשון שהוגדר עבור יעד הגיבויPod(s).
command– זו הפקודה בפועל שנשלחת לקונטיינר, והיא מורכבת כמערך של מילים. המילה הראשונה במערך היא הנתיב לפקודה, והמילים הבאות הן הארגומנטים שיועברו לפקודה.
timeoutSeconds– (אופציונלי) הזמן שלפני ביטול ההפעלה של ה-hook. אם לא תציינו ערך, ברירת המחדל תהיה 30 שניות.
onError– (אופציונלי) התנהגות במקרה שה-hook נכשל. אפשר להגדיר את הערך כ-Ignoreאו כ-Fail(ברירת המחדל). אם מגדירים את האפשרות הזו לערךFail, הגיבוי של נפח האחסון ייכשל אם ה-hook ייכשל. אם מגדירים את הערךIgnore, המערכת מתעלמת מכשלים ב-hook הזה.
לפני שמחילים ווים של ProtectedApplication על האפליקציה, כדאי לבדוק את הפקודה באמצעות kubectl exec כדי לוודא שהווים פועלים כמצופה:
kubectl exec POD_NAME -- COMMAND
מחליפים את מה שכתוב בשדות הבאים:
-
POD_NAME: השם של ה-Pod שמכיל את משאבProtectedApplication. -
COMMAND: המערך שמכיל את הפקודה שרוצים להריץ בקונטיינר.
בחירת קבוצת משנה של נפחים לגיבוי
לפעמים אפליקציות כותבות לווליומים שלא מעניין לשחזר (למשל, ווליומים מסוימים של יומנים או של נתונים זמניים). אפשר למנוע את הגיבוי של אמצעי האחסון האלה באמצעות כלי לבחירת אמצעי אחסון.
כדי להשתמש בתכונה הזו, קודם צריך להחיל תוויות משותפות על משאבי PersistentVolumeClaim של אמצעי האחסון שרוצים לגבות. בנוסף, צריך להשאיר את התווית הזו מושבתת במשאבי PersistentVolumeClaim של נפחי אחסון שלא רוצים לגבות. לאחר מכן, מוסיפים סעיף volumeSelector להגדרת הרכיב, באופן הבא:
spec:
...
components:
...
strategy:
...
volumeSelector:
matchLabels:
label_name: label_value
אם מציינים volumeSelector לרכיב, רק אמצעי האחסון שהמשאבים שלהם ב-PersistentVolumeClaim כוללים את התווית הנתונה מגובים ומשוחזרים. בזמן השחזור, נפחי אחסון אחרים מוקצים כריקים במקום לשחזר אותם מגיבוי של נפח אחסון.
אסטרטגיה: BackupAllRestoreAll
זו האסטרטגיה הפשוטה ביותר, והיא מגבה את כל הכרכים של הרכיב בזמן הגיבוי ומשחזרת את כולם מהגיבויים של הכרכים בזמן השחזור.
זו האפשרות הכי טובה כשהאפליקציה לא משכפלת בין Pods.
השיטה הזו תומכת בפרמטרים הבאים:
backupPreHooks– (אופציונלי) רשימה מסודרת של hooks שמופעלים לפני גיבוי הנפחים. הפקודות האלה מופעלות בכלPodsברכיב.
backupPostHooks– (אופציונלי) רשימה ממוינת של הוקים שמופעלים אחרי שגיבויי הנפח הגיעו לשלב UPLOADING. הפקודות האלה מופעלות בכלPodsברכיב.
volumeSelector– (אופציונלי) לוגיקה להתאמת קבוצת משנה של נפחים לגיבוי.
בדוגמה הזו נוצר משאב ProtectedApplication שמשבית את מערכת הקבצים לפני גיבוי של נפח היומנים, ומפעיל אותה מחדש אחרי הגיבוי:
kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1
metadata:
name: nginx
namespace: sales
spec:
resourceSelection:
type: Selector
selector:
matchLabels:
app: nginx
components:
- name: nginx-app
resourceKind: Deployment
resourceNames: ["nginx-deployment"]
strategy:
type: BackupAllRestoreAll
backupAllRestoreAll:
backupPreHooks:
- name: freeze
container: nginx
command:
- bash
- "-c"
- |
# Add application logic to flush data to disk before snapshot
# and freeze the application from further changes.
echo "Freezing the application"
# Return 0 on successful freeze of application, and non-zero
# for errors
exit 0
backupPostHooks:
- name: unfreeze
container: nginx
command:
- bash
- "-c"
- |
# Add application logic to unfreeze the application.
echo "Unfreezing the application"
# Return 0 on successful freeze of application, and non-zero
# for errors
exit 0
אסטרטגיה: BackupOneAndRestoreAll
האסטרטגיה הזו מגבה עותק אחד של Pod שנבחר. העותק היחיד הזה הוא המקור לשחזור כל ה-Pods במהלך השחזור. השיטה הזו יכולה לעזור לצמצם את עלויות האחסון ואת זמן הגיבוי. השיטה הזו פועלת בהגדרת זמינות גבוהה כשפריט מופעל עם PersistentVolumeClaim ראשי אחד וכמה PersistentVolumeClaims משניים.
השיטה הזו תומכת בפרמטרים הבאים:
backupTargetName– (חובה) מציין את ה-Deployment או ה-StatefulSet שבהם רוצים להשתמש כדי לגבות את הנתונים. ה-Pod הכי טוב לגיבוי נבחר באופן אוטומטי. במערך עם זמינות גבוהה, מומלץ להגדיר את זה לאחת מהרפליקות של האפליקציה.
backupPreHooks– (אופציונלי) רשימה מסודרת של hooks שמופעלים ממש לפני גיבוי הווליומים. הפקודות האלה מופעלות רק בגיבוי שנבחרPod.
backupPostHooks– (אופציונלי) רשימה מסודרת של hooks שמופעלים אחרי שגיבויי הנפח מגיעים לשלב ההעלאה. הפקודות האלה מופעלות רק בגיבויPodשנבחר.
volumeSelector– (אופציונלי) לוגיקה להתאמת קבוצת משנה של נפחים לגיבוי.
אם רכיב מוגדר עם כמה פריסות או StatefulSets, לכל המשאבים צריכה להיות אותה מבנה PersistentVolume, כלומר הם צריכים לפעול לפי הכללים הבאים:
- מספר ה-
PersistentVolumeClaimsשמשמש את כל ה-Deployments או ה-StatefulSets חייב להיות זהה. - המטרה של
PersistentVolumeClaimsבאותו אינדקס חייבת להיות זהה. ב-StatefulSets, האינדקס מוגדר ב-volumeClaimTemplate. ב-Deployments, האינדקס מוגדר ב-Volumesומדלגים על כל הכרכים הלא קבועים. - אם רכיב האפליקציה מורכב מפריסות, לכל פריסה צריך להיות עותק אחד בלבד.
בהתחשב בשיקולים האלה, אפשר לבחור כמה קבוצות של אמצעי אחסון לגיבוי, אבל רק אמצעי אחסון אחד מכל קבוצה ייבחר.
בדוגמה הבאה, בהנחה שיש ארכיטקטורה של StatefulSet ראשי אחד ו-StatefulSet משני אחד, מוצג גיבוי של אמצעי אחסון של Pod אחד ב-StatefulSet המשני, ואז שחזור לכל אמצעי האחסון האחרים:
kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1
metadata:
name: mariadb
namespace: mariadb
spec:
resourceSelection:
type: Selector
selector:
matchLabels:
app: mariadb
components:
- name: mariadb
resourceKind: StatefulSet
resourceNames: ["mariadb-primary", "mariadb-secondary"]
strategy:
type: BackupOneRestoreAll
backupOneRestoreAll:
backupTargetName: mariadb-secondary
backupPreHooks:
- name: quiesce
container: mariadb
command: [...]
backupPostHooks:
- name: unquiesce
container: mariadb
command: [...]
אסטרטגיה: DumpAndLoad
בשיטה הזו נעשה שימוש באמצעי אחסון ייעודי לגיבוי ולשחזור, ונדרש PersistentVolumeClaim ייעודי שמצורף לרכיב שמאחסן נתוני dump.
השיטה הזו תומכת בפרמטרים הבאים:
dumpTarget– (חובה) מציין את ה-Deployment או ה-StatefulSet שרוצים להשתמש בהם כדי לגבות את הנתונים. המערכת בוחרת אוטומטית את ה-Pod שהכי מתאים לגיבוי. בהגדרה של זמינות גבוהה, מומלץ להגדיר את הערך הזה לאחת מהרפליקות של האפליקציה.
loadTarget– (חובה) מציין באיזה Deployment או StatefulSet צריך להשתמש כדי לטעון את הנתונים. המערכת בוחרת אוטומטית את ה-Pod שהכי מתאים לגיבוי. יעד הטעינה לא חייב להיות זהה ליעד ה-dump.
dumpHooks– (חובה) רשימה מסודרת של hooks שמופעלים כדי לאכלס את נפח הגיבוי הייעודי. הפקודות האלה מופעלות רק על קובץ ה-dump שנבחרPod.
backupPostHooks– (אופציונלי) רשימה מסודרת של hooks שמופעלים אחרי שגיבויי הנפח מגיעים לשלב ההעלאה. הפקודות האלה מופעלות רק על קובץ ה-dump שנבחרPod.loadHooks– (חובה) רשימה מסודרת של hooks שמופעלים כדי לטעון את הנתונים מהאחסון המשוחזר אחרי שהאפליקציה מופעלת. הפקודות האלה מופעלות רק על העומס שנבחרPod.
volumeSelector– (חובה) לוגיקה להתאמת נפח יחיד לגיבוי ולשחזור (הנפח של ה-dump). למרות שהיא צריכה להתאים רק לנפח אחסון אחד, אתם מגדירים אותה באותו אופן שבו אתם מגדירים את קבוצת המשנה של נפחי האחסון לגיבוי שמשמשת אסטרטגיות אחרות.
אם האפליקציה מורכבת מפריסות, לכל פריסה חייבת להיות העתק אחד בדיוק.
בדוגמה הזו, בהנחה שיש ארכיטקטורה של StatefulSet ראשי אחד ו-StatefulSet משני אחד עם PersistentVolumeClaims ייעודי גם ל-StatefulSet הראשי וגם ל-StatefulSet המשני, מוצגת אסטרטגיית DumpAndLoad:
kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1
metadata:
name: mariadb
namespace: mariadb
spec:
resourceSelection:
type: Selector
selector:
matchLabels:
app: mariadb
components:
- name: mariadb-dump
resourceKind: StatefulSet
resourceNames: ["mariadb-primary", "mariadb-secondary"]
strategy:
type: DumpAndLoad
dumpAndLoad:
loadTarget: mariadb-primary
dumpTarget: mariadb-secondary
dumpHooks:
- name: db_dump
container: mariadb
command:
- bash
- "-c"
- |
mysqldump -u root --all-databases > /backup/mysql_backup.dump
loadHooks:
- name: db_load
container: mariadb
command:
- bash
- "-c"
- |
mysql -u root < /backup/mysql_backup.sql
volumeSelector:
matchLabels:
gkebackup.gke.io/backup: dedicated-volume
בדיקה אם ProtectedApplication מוכן לגיבוי
כדי לבדוק אם ProtectedApplication מוכן לגיבוי, מריצים את הפקודה הבאה:
kubectl describe protectedapplication APPLICATION_NAME
מחליפים את APPLICATION_NAME בשם האפליקציה.
אם האפליקציה מוכנה, בתיאור שלה יופיע הסטטוס Ready to backup בתור true, כמו בדוגמה הזו:
% kubectl describe protectedapplication nginx
Name: nginx
Namespace: default
API Version: gkebackup.gke.io/v1
Kind: ProtectedApplication
Metadata:
UID: 90c04a86-9dcd-48f2-abbf-5d84f979b2c2
Spec:
Components:
Name: nginx
Resource Kind: Deployment
Resource Names:
nginx
Strategy:
Backup All Restore All:
Backup Pre Hooks:
Command:
/sbin/fsfreeze
-f
/var/log/nginx
Container: nginx
Name: freeze
Backup Post Hooks:
Command:
/sbin/fsfreeze
-u
/var/log/nginx
Container: nginx
Name: unfreeze
Type: BackupAllRestoreAll
Resource Selection:
Selector:
Match Labels:
app: nginx
Type: Selector
Status:
Ready To Backup: true
Events: <none>