גיבוי ושחזור של אשכול משתמשים

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

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

מגבלות

  • התהליך הזה לא מגבה נתונים ספציפיים לאפליקציה.

  • התהליך הזה לא יוצר גיבוי של PersistentVolumes.

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

  • אי אפשר לשחזר אשכול אחרי שדרוג שנכשל.

  • ההליך הזה לא נועד לשחזר אשכול שנמחק.

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

מידע נוסף על מגבלות זמין במאמר בנושא אי-תאימות של התשתית.

גיבוי של אשכול משתמשים

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

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

מריצים את הפקודה הבאה כדי לבדוק אם Controlplane V2 מופעל באשכול:

kubectl get onpremuserclusters --kubeconfig USER_CLUSTER_KUBECONFIG \
  -n kube-system -o jsonpath='{.items[0].spec.enableControlplaneV2}' && echo

אם הפלט הוא true, פועלים לפי השלבים של Controlplane V2 כדי לגבות את האשכול. אם לא, פועלים לפי השלבים של Kubeception.

Kubeception

  1. מקבלים מעטפת לקונטיינר kube-etcd:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG exec -it \
     kube-etcd-0 -c kube-etcd -n USER_CLUSTER_NAME \
     -- /bin/sh
    

    where:

    • ADMIN_CLUSTER_KUBECONFIG הוא קובץ ה-kubeconfig של אשכול האדמין.
    • USER_CLUSTER_NAME הוא השם של אשכול המשתמשים.
  2. במעטפת, בספרייה /tmp, יוצרים גיבוי בשם snapshot.db:

    ETCDCTL_API=3 etcdctl \
      --endpoints=https://127.0.0.1:2379 \
      --cacert=/etcd.local.config/certificates/etcdCA.crt \
      --cert=/etcd.local.config/certificates/etcd.crt \
      --key=/etcd.local.config/certificates/etcd.key \
      snapshot save /tmp/snapshot.db
    
  3. במעטפת, מזינים exit כדי לצאת מהמעטפת.

  4. כדי להעתיק את /tmp/snapshot.db מהמאגר kube-etcd לספרייה הנוכחית:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG cp \
      USER_CLUSTER_NAME/kube-etcd-0:/tmp/snapshot.db \
      --container kube-etcd snapshot.db
    

Controlplane V2

  1. מקבלים את השם של ה-Pod של etcd:

    kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get pods \
     -n kube-system -l component=etcd,tier=control-plane -ojsonpath='{$.items[*].metadata.name}{"\n"}'
    

    where:

    • USER_CLUSTER_KUBECONFIG הוא קובץ ה-kubeconfig של אשכול המשתמשים.

    דוגמה:

    NAME          READY   STATUS    RESTARTS   AGE
    etcd-uc1-cp1  1/1     Running   0          38m
    etcd-uc1-cp2  1/1     Running   0          37m
    etcd-uc1-cp3  1/1     Running   0          38m
    

    הערה: יכולים להיות כמה פודים של etcd, למשל 3 עבור אשכולות HA. לגיבוי, כל etcd pod אמור לעבוד.

  2. מקבלים מעטפת לקונטיינר etcd:

    kubectl --kubeconfig USER_CLUSTER_KUBECONFIG exec -it \
     POD_NAME -c etcd -n kube-system -- /bin/sh
    
    

    where:

    • POD_NAME הוא השם של ה-pod של etcd שנלקח מהשלב הקודם.
  3. במעטפת, יוצרים קובץ גיבוי בשם snapshot.db:

    ETCDCTL_API=3 etcdctl \
      --endpoints=https://127.0.0.1:2379 \
      --cacert=/etc/kubernetes/pki/etcd/ca.crt \
      --cert=/etc/kubernetes/pki/etcd/server.crt \
      --key=/etc/kubernetes/pki/etcd/server.key \
      snapshot save /tmp/snapshot.db
    
  4. במעטפת, מזינים exit כדי לצאת מהמעטפת.

  5. מעתיקים את snapshot.db מהמאגר etcd לספריית הבית של תחנת העבודה:

    kubectl --kubeconfig USER_CLUSTER_KUBECONFIG \
     cp POD_NAME:/tmp/snapshot.db ~/snapshot.db \
     -c etcd -n kube-system
    
  6. מעתיקים את הסודות מהספרייה של PKI:

    ssh -i NODE_NAME.key ubuntu@NODE_EXTERNAL_IP
    sudo chmod -R 0644 /etc/kubernetes/pki/*
    sudo chmod 0755 /etc/kubernetes/pki/etcd
    exit
    scp -ri NODE_NAME.key ubuntu@NODE_EXTERNAL_IP:/etc/kubernetes/pki ~/pki_NODE_NAME
    

    where:

    • NODE_NAME הוא הקובץ שמכיל את מפתח ה-SSH לצומת של מישור הבקרה
    • NODE_EXTERNAL_IP היא כתובת ה-IP של צומת מישור הבקרה של המשתמש שממנו רוצים להעתיק את הסודות.

שחזור אשכול משתמשים מגיבוי (לא HA)

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

בהוראות הבאות מוסבר איך להשתמש בקובץ גיבוי כדי לשחזר אשכול משתמשים במקרים שבהם נתוני ה-etcd של האשכול ניזוקו, ו-Pod ה-etcd של אשכול המשתמשים נמצא במצב של לולאת קריסה.

Kubeception

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

  1. מוצאים את השם של ה-Secret שמשמש את etcd באשכול המשתמשים:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG -n USER_CLUSTER_NAME \
       get secrets | grep kube-etcd-certs
    
  2. מעתיקים את מניפסט ה-Pod הבא לקובץ בשם etcd-utility.yaml. מחליפים את מה שכתוב בשדות הבאים:

    • NODE_NAME: הצומת שבו פועל ה-Pod‏ kube-etcd-0.

    • ADMIN_CLUSTER_KUBECONFIG: קובץ ה-kubeconfig של אשכול האדמין.

    • USER_CLUSTER_NAME: השם של אשכול המשתמשים.

    • GKE_ON_PREM_VERSION: הגרסה של האשכול שבו רוצים לבצע את השחזור של etcd (לדוגמה, 1.5.0-gke.0).

    • KUBE_ETCD_SECRET_NAME: השם של הסוד שמשמש את etcd באשכול המשתמשים, שמתחיל ב-kube-etcd-certs.

    apiVersion: v1
    kind: Pod
    metadata:
     name: etcd-utility-0
     namespace: USER_CLUSTER_NAME
    spec:
     containers:
     - command: ["/bin/sh"]
       args: ["-ec", "while :; do echo '.'; sleep 5 ; done"]
       image: gcr.io/gke-on-prem-release/etcd-util:GKE_ON_PREM_VERSION
       name: etcd-utility
       volumeMounts:
       - mountPath: /var/lib/etcd
         name: data
       - mountPath: /etcd.local.config/certificates
         name: etcd-certs
     nodeSelector:
       kubernetes.googleapis.com/cluster-name: USER_CLUSTER_NAME
       kubernetes.io/hostname: NODE_NAME
     tolerations:
     - effect: NoExecute
       key: node.kubernetes.io/not-ready
       operator: Exists
       tolerationSeconds: 300
     - effect: NoExecute
       key: node.kubernetes.io/unreachable
       operator: Exists
       tolerationSeconds: 300
     - effect: NoSchedule
       key: node.kubernetes.io/unschedulable
       operator: Exists
     volumes:
     - name: data
       persistentVolumeClaim:
         claimName: data-kube-etcd-0
     - name: etcd-certs
       secret:
         defaultMode: 420
         secretName: KUBE_ETCD_SECRET_NAME
    
  3. פורסים את ה-Pod של כלי השירות:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG \
      create -f etcd-utility.yaml --namespace USER_CLUSTER_NAME
    
  4. מעתיקים את snapshot.db מהספרייה הנוכחית לספריית הבסיס (root) של ה-Pod של כלי השירות:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG cp snapshot.db \
      USER_CLUSTER_NAME/etcd-utility-0:snapshot.db --container etcd-utility
    
  5. מקבלים מעטפת לקונטיינר etcd-utility:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG exec it \
      etcd-utility-0 --container etcd-utility --namespace USER_CLUSTER_NAME \
      -- bin/sh
    
  6. במעטפת, בספריית השורש, מריצים את הפקודה הבאה כדי ליצור תיקייה חדשה שמכילה את הגיבוי:

    ETCDCTL_API=3 etcdctl \
      --endpoints=https://127.0.0.1:2379 \
      --cacert=/etcd.local.config/certificates/etcdCA.crt \
      --cert=/etcd.local.config/certificates/etcd.crt \
      --key=/etcd.local.config/certificates/etcd.key \
      snapshot restore snapshot.db
    
  7. במעטפת, מוחקים את נתוני etcd הישנים:

    rm -r var/lib/etcd/*
    
  8. במעטפת, מעתיקים את נתוני ה-etcd ששוחזרו למיקום הקבוע שלהם:

    cp -r default.etcd/* var/lib/etcd/
    
  9. במעטפת, מזינים exit כדי לצאת מהמעטפת.

  10. מוחקים את ה-Pod של etcd שקורס:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG \
      delete pod kube-etcd-0 --namespace USER_CLUSTER_NAME
    
  11. מוודאים ש-Pod של etcd לא קורס יותר.

  12. מוחקים את ה-Pod של חברת התשתיות:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG \
      delete pod etcd-utility-0 --namespace USER_CLUSTER_NAME
  13. הסרת etcd-utility.yaml מהספרייה הנוכחית:

    rm etcd-utility.yaml
    

Controlplane V2

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

  1. מקבלים מעטפת (shell) לצומת של מישור הבקרה של המשתמש:

    ssh -i NODE_NAME.key ubuntu@NODE_EXTERNAL_IP
    
  2. במעטפת, מפסיקים את שרת Kubernetes API ואת שרת etcd:

    sudo mv /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/etcd.yaml ~
    
  3. במעטפת, מזינים exit כדי לצאת מהמעטפת.

  4. מריצים את הפקודה scp כדי להעתיק את קובץ הגיבוי snapshot.db ואת הסודות לצומת של מישור הבקרה של המשתמש:

    scp -i NODE_NAME.key ~/snapshot.db ubuntu@NODE_EXTERNAL_IP:/tmp/
    
    chmod a+rw pki/
    scp -ri NODE_NAME.key ~/pki_NODE_NAME ubuntu@NODE_EXTERNAL_IP:/etc/kubernetes/pki
    
  5. במעטפת, משתמשים בפקודה snapshot.db כדי לשחזר את נתוני etcd:

    ETCDCTL_API=3 sudo etcdctl \
     --cacert=/etc/kubernetes/pki/etcd/ca.crt \
     --cert=/etc/kubernetes/pki/etcd/server.crt \
     --key=/etc/kubernetes/pki/etcd/server.key \
     --data-dir=/opt/data/var/lib/etcd \
     --name=NODE_NAME \
     --initial-advertise-peer-urls=https://NODE_IP_ADDRESS:2380 \
     --initial-cluster=NODE_NAME=https://NODE_IP_ADDRESS:2380 \
     snapshot restore /tmp/snapshot.db
    

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

    • NODE_NAME: שם הצומת שבו מתבצעת השחזור
    • NODE_IP_ADDRESS: כתובת ה-IP של הצומת.
  6. מוסיפים את הדגל - --initial-cluster-state=new לקובץ המניפסט של etcd בקטע container command.

    דוגמה:

    containers:
          - command:
            - etcd
            ...
            - --initial-cluster-state=new
            ...

  7. במעטפת, מפעילים את השרתים kube-apiserver ו-etcd:

    sudo mv ~/etcd.yaml ~/kube-apiserver.yaml /etc/kubernetes/manifests/
    
  8. במעטפת, מזינים exit כדי לצאת מהמעטפת.

שחזור אשכול משתמש מגיבוי (זמינות גבוהה)

Kubeception

בקטע הזה מוסבר איך לשחזר את נתוני etcd עבור אשכול משתמשים עם זמינות גבוהה (HA).

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

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

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

כדי לבצע את השלבים בקטע הזה, צריך ליצור קובץ snapshot.db כמו שמתואר במאמר גיבוי של אשכול משתמשים.

הצגת רשימה של ה-Pods והצמתים של etcd

  1. מפרטים את פודי ה-etcd שמנהלים את מאגר ה-etcd עבור אשכול המשתמשים. ה-Pods האלה פועלים באשכול הניהול:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG get pods --namespace USER_CLUSTER_NAME \
    --output wide | grep kube-etcd
    

    בפלט מוצגים ה-Pods של etcd והצמתים שבהם ה-Pods פועלים. הצמתים שמוצגים בפלט הם צמתים באשכול האדמין שמשמשים כמישורי בקרה לאשכול המשתמש:

    NAME              ...   NODE
    kube-etcd-0       ...   xxx
    kube-etcd-1       ...   yyy
    kube-etcd-2       ...   zzz
    
  2. חשוב לרשום את שמות ה-Pod ואת שמות הצמתים של מישור הבקרה כדי להשתמש בהם בהמשך.

    שימו לב שכל פוד של etcd נקרא kube-etcd בתוספת מספר. המספר הזה נקרא מספר החבר בקבוצה. הוא מזהה את ה-Pod כחבר מסוים באשכול etcd שמכיל את נתוני האובייקט של אשכול המשתמשים. במדריך הזה, מחזיק המקום MEMBER_NUMBER מייצג את מספר החבר ב-Pod של etcd.

    שימו לב גם שכל Pod באשכול etcd פועל על צומת משלו.

הכנה לפריסת קבוצות ה-Pod של כלי השירות

  1. שומרים מניפסט עבור PodDisruptionBudget ‏ (PDB) עבור שרת Kubernetes API של אשכול המשתמש. לאחר מכן מוחקים את קובץ ה-PDB.

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG get pdb --namespace USER_CLUSTER_NAME \
    kube-apiserver-pdb --output yaml > kube-apiserver-pdb.yaml
    
    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG delete pdb --namespace USER_CLUSTER_NAME \
    kube-apiserver-pdb
    
  2. עוצרים את שרת ה-API של Kubernetes ואת פריסת התחזוקה של etcd. כך מוודאים שאף רכיב לא ישתמש ב-etcd במהלך השחזור:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG --namespace USER_CLUSTER_NAME \
    scale --replicas 0 statefulset kube-apiserver
    
    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG --namespace USER_CLUSTER_NAME \
    scale --replicas 0 deployment gke-master-etcd-maintenance
    
  3. זוכרים את השם של קובץ האימג' בקונטיינר של ה-Pods של etcd.

פריסת ה-Pods של כלי השירות

  1. נזכרים בשם ה-Pod של etcd ובשם הצומת שבו ה-Pod פועל.

  2. שומרים את מניפסט ה-Pod הבא בספרייה הנוכחית בקובץ בשם etcd-utility-MEMBER_NUMBER.yaml:

 apiVersion: v1
 kind: Pod
 metadata:
   name: etcd-utility-MEMBER_NUMBER
   namespace: USER_CLUSTER_NAME
 spec:
   containers:
   - command: ["/bin/sh"]
     args: ["-ec", "while :; do echo '.'; sleep 5 ; done"]
     image: gcr.io/gke-on-prem-release/etcd-util:GKE_ON_PREM_VERSION
     name: etcd-utility
     volumeMounts:
     - mountPath: /var/lib/etcd
       name: data
     - mountPath: /etcd.local.config/certificates
       name: etcd-certs
   nodeSelector:
     kubernetes.googleapis.com/cluster-name: USER_CLUSTER_NAME
     kubernetes.io/hostname: NODE_NAME
   tolerations:
   - effect: NoExecute
     key: node.kubernetes.io/not-ready
     operator: Exists
     tolerationSeconds: 300
   - effect: NoExecute
     key: node.kubernetes.io/unreachable
     operator: Exists
     tolerationSeconds: 300
   - effect: NoSchedule
     key: node.kubernetes.io/unschedulable
     operator: Exists
   volumes:
   - name: data
     persistentVolumeClaim:
       claimName: data-kube-etcd-MEMBER_NUMBER
   - name: etcd-certs
     secret:
       defaultMode: 420
       secretName: KUBE_ETCD_SECRET_NAME

קובץ המניפסט שלמעלה מתאר Pod של כלי שמופעל באופן זמני כדי לשחזר נתוני etcd.

  1. יוצרים את ה-Pod של כלי השירות באשכול האדמין:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG apply -f etcd-utility-MEMBER_NUMBER.yaml
    
  2. מעתיקים את קובץ הגיבוי, snapshot.db, לספריית הבסיס של ה-Pod של כלי השירות:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG cp snapshot.db \
    USER_CLUSTER_NAME/etcd-utility-MEMBER_NUMBER:snapshot.db
    
  3. מקבלים מעטפת אל קונטיינר etcd-utility ב-Pod של כלי השירות:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG exec -it --namespace USER_CLUSTER_NAME \
    etcd-utility-MEMBER_NUMBER --container etcd-utility -- bin/sh
    
  4. במעטפת, בספריית השורש, משתמשים בפקודה snapshot.db כדי לשחזר את נתוני etcd:

    ETCDCTL_API=3 etcdctl \
    --endpoints=https://127.0.0.1:2379 \
    --cacert=/etcd.local.config/certificates/etcdCA.crt \
    --cert=/etcd.local.config/certificates/etcd.crt \
    --key=/etcd.local.config/certificates/etcd.key \
    --name=kube-etcd-MEMBER_NUMBER \
    --initial-cluster=kube-etcd-0=https://kube-etcd-0.kube-etcd:2380,kube-etcd-1=https://kube-etcd-1.kube-etcd:2380,kube-etcd-2=https://kube-etcd-2.kube-etcd:2380 \
    --initial-cluster-token=etcd-cluster-1 \
    --initial-advertise-peer-urls=https://kube-etcd-MEMBER_NUMBER.kube-etcd:2380 \
    snapshot restore snapshot.db
    

    הפקודה הקודמת אחסנה את נתוני etcd בספרייה /kube-etcd-MEMBER_NUMBER.etcd.

  5. במעטפת, מוחקים את נתוני etcd הישנים:

    rm -r var/lib/etcd/*
    
  6. במעטפת, מעתיקים את נתוני ה-etcd ששוחזרו למיקום הקבוע שלהם:

    cp -r kube-etcd-MEMBER_NUMBER.etcd/* var/lib/etcd/
    
  7. במעטפת, מסירים את ספריית etcd הזמנית ואת קובץ הגיבוי:

    rm -R kube-etcd-MEMBER_NUMBER.etcd/
    rm snapshot.db
    
  8. במעטפת, מזינים exit כדי לצאת מהמעטפת.

  9. מוחקים את ה-Pod של חברת התשתיות:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG delete pod \
    --namespace USER_CLUSTER_NAME etcd-utility-MEMBER_NUMBER
    

הפעלה מחדש של רכיבים

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

  1. מפעילים מחדש את ה-Pods ב-StatefulSet‏ kube-etcd:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG rollout restart statefulset \
    --namespace USER_CLUSTER_NAME kube-etcd
    
  2. מפעילים את שרתי Kubernetes API עבור אשכול המשתמשים:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG scale statefulset --replicas 3 \
    --namespace USER_CLUSTER_NAME kube-apiserver
    
  3. מפעילים את פריסת התחזוקה של etcd עבור אשכול המשתמשים:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG scale deployment --replicas 1 \
    --namespace=USER_CLUSTER_NAME  gke-master-etcd-maintenance
    
  4. משחזרים את ה-PDB עבור שרת ה-API של Kubernetes:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG apply -f kube-apiserver-pdb.yaml
    

Controlplane V2

בקטע הזה מוסבר איך לשחזר את נתוני etcd עבור אשכול משתמשים עם זמינות גבוהה (HA).

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

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

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

כדי לבצע את השלבים בקטע הזה, צריך ליצור קובץ snapshot.db כמו שמתואר במאמר גיבוי של אשכול משתמשים.

הצגת רשימה של ה-Pods והצמתים של etcd

  1. מציגים את רשימת ה-Pods של etcd ואת הצומת המתאים:

    kubectl get pod --kubeconfig USER_CLUSTER_KUBECONFIG \
     -n kube-system -l component=etcd,tier=control-plane -o wide
    

    בפלט מוצגים ה-Pods של etcd והצמתים שבהם ה-Pods פועלים. הצמתים שמוצגים בפלט הם צמתים באשכול האדמין שמשמשים כמישורי בקרה לאשכול המשתמש:

    NAME           ...   NODE
    etcd-xxx       ...   xxx
    etcd-yyy       ...   yyy
    etcd-zzz       ...   zzz
    
  2. חשוב לרשום את שמות ה-Pod ואת שמות הצמתים של מישור הבקרה כדי להשתמש בהם בהמשך.

    שימו לב שכל Pod של etcd נקרא etcd-xxx בתוספת שם הצומת. הסיבה לכך היא שבתכונה Controlplane V2, הפודים של etcd פועלים כפוד סטטי.

בהכנה לשחזור

  1. מריצים את הפקודה scp כדי להעתיק את קובץ הגיבוי snapshot.db לכל הצמתים של מישור הבקרה של המשתמש:

    scp -i NODE_NAME.key ~/snapshot.db ubuntu@NODE_EXTERNAL_IP:/tmp/
    
  2. מעתיקים את הסודות לצומת של מישור הבקרה של המשתמש הרלוונטי:

    chmod a+rw ~/pki_*
    scp -ri NODE_NAME.key ~/pki_NODE_NAME/* ubuntu@NODE_EXTERNAL_IP:/opt/data/etc/kubernetes/pki/
    
  3. מקבלים מעטפת (shell) לצומת של מישור הבקרה של המשתמש:

    ssh -i NODE_NAME.key ubuntu@NODE_EXTERNAL_IP
    

ביצוע השחזור

  1. נזכרים בשם ה-Pod של etcd ובשם הצומת שבו ה-Pod פועל.

  2. במעטפת, מפסיקים את שרת Kubernetes API ואת שרת etcd בכל הצמתים של מישור הבקרה של המשתמש:

    sudo mv /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/etcd.yaml ~
    
  3. במעטפת, משתמשים בפקודה snapshot.db כדי לשחזר את נתוני etcd בכל הצמתים של מישור הבקרה של המשתמש:

    ETCDCTL_API=3 sudo etcdctl \
     --cacert=/etc/kubernetes/pki/etcd/ca.crt \
     --cert=/etc/kubernetes/pki/etcd/server.crt \
     --key=/etc/kubernetes/pki/etcd/server.key \
     --data-dir=/opt/data/var/lib/etcd \
     --name=NODE_NAME \
     --initial-advertise-peer-urls=https://NODE_IP_ADDRESS:2380 \
     --initial-cluster=NODE1=https://NODE1_IP:2380,NODE2=https://NODE2_IP:2380,NODE3=https://NODE3_IP:2380 \
     snapshot restore /tmp/snapshot.db
    

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

    • NODE_NAME: שם הצומת שבו מתבצעת השחזור.
    • NODE_IP_ADDRESS: כתובת ה-IP של הצומת.
    • ממלאים את NODE1, NODE2, NODE3 ואת NODE1_IP, NODE2_IP, NODE3_IP של הצומת המתאים לדגל --initial-cluster. אפשר גם לקבל את זה ממניפסט ה-etcd.
  4. מוסיפים את הדגל - --initial-cluster-state=existing לקובץ המניפסט של etcd בקטע container command.

    דוגמה:

    containers:
          - command:
            - etcd
            ...
            - --initial-cluster-state=existing
            ...

הפעלה מחדש של רכיבים

  1. במעטפת, מפעילים את השרתים kube-apiserver ו-etcd בכל הצמתים של מישור הבקרה של המשתמש:

    sudo mv ~/etcd.yaml ~/kube-apiserver.yaml /etc/kubernetes/manifests/
    
  2. במעטפת, מזינים exit כדי לצאת מהמעטפת.

  3. מוודאים ש-kube-apiserver ו-etcd פועלים בכל הצמתים של מישור הבקרה של המשתמש:

    kubectl get pod --kubeconfig USER_CLUSTER_KUBECONFIG \
    -n kube-system -l tier=control-plane
    

גיבוי אוטומטי של אשכול

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

Kubeception

  • מגדירים את BACKUP_DIR לנתיב שבו רוצים לאחסן את הגיבויים של האדמין ושל אשכול המשתמשים. הנתיב הזה לא אמור להתקיים.
  • מגדירים את ADMIN_CLUSTER_KUBECONFIG לנתיב של קובץ ה-kubeconfig של אשכול האדמין
  • מגדירים את USER_CLUSTER_NAMESPACE לשם של אשכול המשתמשים. השם של אשכול המשתמשים הוא מרחב שמות באשכול האדמין.
  • מגדירים את EXTERNAL_IP לכתובת ה-VIP שהזמנתם עבור שירות אמצעי הבקרה לאדמינים.
  • מגדירים את SSH_PRIVATE_KEY לנתיב של מפתח ה-SSH.
  • אם אתם משתמשים ברשת פרטית, צריך להגדיר את JUMP_IP לכתובת ה-IP של שרת הניתוב של הרשת.
#!/usr/bin/env bash

# Automates manual steps for taking backups of user and admin clusters.
# Fill in the variables below before running the script.

BACKUP_DIR=""                       # path to store user and admin cluster backups
ADMIN_CLUSTER_KUBECONFIG=""         # path to admin cluster kubeconfig
USER_CLUSTER_NAMESPACE=""           # user cluster namespace
EXTERNAL_IP=""                      # admin control plane node external ip - follow steps in documentation
SSH_PRIVATE_KEY=""                  # path to vsphere_tmp ssh private key - follow steps in documentation
JUMP_IP=""                          # network jump server IP - leave empty string if not using private network.

mkdir -p $BACKUP_DIR
mkdir $BACKUP_DIR/pki

# USER CLUSTER BACKUP

# Snapshot user cluster etcd
kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} exec -it -n ${USER_CLUSTER_NAMESPACE} kube-etcd-0 -c kube-etcd -- /bin/sh -ec "export ETCDCTL_API=3; etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etcd.local.config/certificates/etcdCA.crt --cert=/etcd.local.config/certificates/etcd.crt --key=/etcd.local.config/certificates/etcd.key snapshot save ${USER_CLUSTER_NAMESPACE}_snapshot.db"
kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} cp ${USER_CLUSTER_NAMESPACE}/kube-etcd-0:${USER_CLUSTER_NAMESPACE}_snapshot.db $BACKUP_DIR/user-cluster_${USER_CLUSTER_NAMESPACE}_snapshot.db 

# ADMIN CLUSTER BACKUP

# Set up ssh options
SSH_OPTS=(-oStrictHostKeyChecking=no -i ${SSH_PRIVATE_KEY})
if [ "${JUMP_IP}" != "" ]; then
  SSH_OPTS+=(-oProxyCommand="ssh -oStrictHostKeyChecking=no -i ${SSH_PRIVATE_KEY} -W %h:%p ubuntu@${JUMP_IP}")
fi

# Copy admin certs
ssh "${SSH_OPTS[@]}" ubuntu@${EXTERNAL_IP} 'sudo chmod -R +rw /etc/kubernetes/pki/*'
scp -r "${SSH_OPTS[@]}" ubuntu@${EXTERNAL_IP}:/etc/kubernetes/pki/* ${BACKUP_DIR}/pki/

# Snapshot admin cluster etcd
admin_etcd=$(kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} get pods -n kube-system -l component=etcd,tier=control-plane -ojsonpath='{$.items[*].metadata.name}{"\n"}')
kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} exec -it -n kube-system ${admin_etcd} -- /bin/sh -ec "export ETCDCTL_API=3; etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key snapshot save admin_snapshot.db"
kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} cp -n kube-system ${admin_etcd}:admin_snapshot.db $BACKUP_DIR/admin-cluster_snapshot.db

Controlplane V2

  • מגדירים את BACKUP_DIR לנתיב שבו רוצים לאחסן את הגיבויים של האדמין ושל אשכול המשתמשים. הנתיב הזה לא אמור להתקיים.
  • מגדירים את ADMIN_CLUSTER_KUBECONFIG לנתיב של קובץ ה-kubeconfig של אשכול האדמין
  • מגדירים את USER_CLUSTER_KUBECONFIG לנתיב של קובץ ה-kubeconfig של אשכול המשתמשים.
  • מגדירים את EXTERNAL_IP לכתובת ה-VIP שהזמנתם עבור שירות אמצעי הבקרה לאדמינים.
  • מגדירים את SSH_PRIVATE_KEY לנתיב של מפתח ה-SSH.
  • אם אתם משתמשים ברשת פרטית, צריך להגדיר את JUMP_IP לכתובת ה-IP של שרת הניתוב של הרשת.
#!/usr/bin/env bash

# Automates manual steps for taking backups of user and admin clusters.
# Fill in the variables below before running the script.

BACKUP_DIR=""                       # path to store user and admin cluster backups
ADMIN_CLUSTER_KUBECONFIG=""         # path to admin cluster kubeconfig
USER_CLUSTER_KUBECONFIG=""          # path to user cluster kubeconfig
EXTERNAL_IP=""                      # admin control plane node external ip - follow steps in documentation
SSH_PRIVATE_KEY=""                  # path to ssh private key - follow steps in documentation
JUMP_IP=""                          # network jump server IP - leave empty string if not using private network

mkdir -p $BACKUP_DIR
mkdir $BACKUP_DIR/pki

# USER CLUSTER BACKUP
user_etcd=$(kubectl --kubeconfig=${USER_CLUSTER_KUBECONFIG} get pods -n kube-system -l component=etcd,tier=control-plane -ojsonpath='{$.items[0].metadata.name}{"\n"}')
kubectl --kubeconfig=${USER_CLUSTER_KUBECONFIG} exec -it -n kube-system ${user_etcd} -c etcd -- /bin/sh -ec "export ETCDCTL_API=3; etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key snapshot save /tmp/${user_etcd}_snapshot.db"
kubectl --kubeconfig=${USER_CLUSTER_KUBECONFIG} cp kube-system/${user_etcd}:/tmp/${user_etcd}_snapshot.db $BACKUP_DIR/${user_etcd}_snapshot.db

# ADMIN CLUSTER BACKUP

# Set up ssh options
SSH_OPTS=(-oStrictHostKeyChecking=no -i ${SSH_PRIVATE_KEY})
if [ "${JUMP_IP}" != "" ]; then
  SSH_OPTS+=(-oProxyCommand="ssh -oStrictHostKeyChecking=no -i ${SSH_PRIVATE_KEY} -W %h:%p ubuntu@${JUMP_IP}")
fi

# Copy admin certs
ssh "${SSH_OPTS[@]}" ubuntu@${EXTERNAL_IP} 'sudo chmod -R +rw /etc/kubernetes/pki/*'
scp -r "${SSH_OPTS[@]}" ubuntu@${EXTERNAL_IP}:/etc/kubernetes/pki/* ${BACKUP_DIR}/pki/

# Snapshot admin cluster etcd
admin_etcd=$(kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} get pods -n kube-system -l component=etcd,tier=control-plane -ojsonpath='{$.items[*].metadata.name}{"\n"}')
kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} exec -it -n kube-system ${admin_etcd} -- /bin/sh -ec "export ETCDCTL_API=3; etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key snapshot save /tmp/${admin_etcd}_snapshot.db"
kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} cp -n kube-system ${admin_etcd}:/tmp/${admin_etcd}_snapshot.db $BACKUP_DIR/${admin_etcd}_snapshot.db

אימות השחזור

כדי לוודא שהאשכול שוחזר בהצלחה, מריצים את הפקודה gkectl diagnose cluster.

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