כיבוי והפעלה של המכשיר

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

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

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

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

דרישות מוקדמות

  1. אפשר להריץ את קובץ runbook הזה במחשב נייד או בתחנת עבודה שמחוברים לרשת של מכשיר Google Distributed Cloud (GDC) עם air gap. אפשר גם לחבר מחשב נייד או תחנת עבודה למתג באמצעות ההוראות שבקטע חיבור המכשיר.
  2. מוודאים שיש לכם גישה לקובץ kubeconfig של אשכול האדמין הראשי.
  3. מגדירים את משתנה הסביבה הנכון של KUBECONFIG על ידי הפעלת הפקודה export KUBECONFIG=PATH_TO_KUBECONFIG.
  4. מוודאים שיש לכם את מפתח ה-SSH והאישור.

כיבוי המאווררים

  1. כדי לקבל מידע על הצמתים, מריצים את הפקודה kubectl get nodes -A -o wide.

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

    kubectl annotate bmhost -n gpc-system NODE_NAME "baremetalhost.metal3.io/paused=true" --overwrite
    

    הפלט יכול להיראות כמו בדוגמה הבאה:

    baremetalhost.metal3.io/**-**-bm01 annotated
    baremetalhost.metal3.io/**-**-bm02 annotated
    baremetalhost.metal3.io/**-**-bm03 annotated
    
  3. מקבלים פרטי כניסה ל-ONTAP Select ‏ (OTS). פרטי הכניסה האלה נחוצים כדי לכבות את צומתי OTS בהמשך.

    מריצים את הפקודה הבאה כדי לזהות את כתובת ה-IP לניהול של OTS שמופיעה בעמודה MGMTIP (כתובת IP לניהול):

     export KUBECONFIG=/root/release/root-admin/kube-admin-remote-kubeconfig
    
     kubectl get storagecluster -n gpc-system
    

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

     export KUBECONFIG=/root/release/root-admin/root-admin-kubeconfig
    
     # Find the secret name
     SECRET_NAME=$(kubectl get secrets -n gpc-system -o name | grep 'ontap-.*-stge01-credential')
    
     # Decode the password from that secret
     OTS_PASSWORD=$(kubectl get $SECRET_NAME -n gpc-system -o jsonpath='{.data.netapp_password}' | base64 --decode)
    
     echo $OTS_PASSWORD
    

    שומרים את כתובת ה-IP והסיסמה של ניהול ה-OTS.

  4. מבודדים את כל הצמתים אחד אחרי השני:

    kubectl cordon NODE_NAME
    

    הפלט יכול להיראות כמו בדוגמה הבאה:

    node/**-**-bm01 cordoned
    node/**-**-bm02 cordoned
    node/**-**-bm03 cordoned
    
  5. כיבוי של צמתי ONTAP Select ‏ (OTS)

    יוצרים חיבור SSH לאשכול OTS באמצעות כתובת ה-IP לניהול וסיסמת האדמין שאחזרתם:

     ssh admin@<ots-management-ip>
    

    משביתים את הצמתים (מכונות וירטואליות) של OTS. לדוגמה:

     bn-aa-stge01::> cluster show
     Node                  Health  Eligibility
     --------------------- ------- ------------
     bn-aa-stge01-01       true    true
     bn-aa-stge01-02       true    true
    
     bn-aa-stge01::> set diag
    
     Warning: These diagnostic commands are for use by NetApp personnel only.
     Do you want to continue? {y|n}: y
    
     bn-aa-stge01::> system node halt -node *
    
  6. כדי למנוע מ-webhook של Gatekeeper לחסום את ניקוזי הצמתים כשהתאים שלו עוברים למצב אופליין, צריך להגדיר באופן זמני את מדיניות הכשל שלו ל-Ignore:

    kubectl patch validatingwebhookconfiguration gatekeeper-validating-webhook-configuration -p '{"webhooks":[{"name":"validation.gatekeeper.sh","failurePolicy":"Ignore"}]}'
    
  7. כדי לקבוע את צומת המנהל ואת צומתי העוקבים של etcd, מריצים את השלב הזה אחד אחרי השני לכל הצמתים:

    1. כדי למצוא כתובות IP של יעד ל-SSH, רושמים את הערכים בעמודה INTERNAL-IP של הפלט מ-kubectl get nodes -A -o wide. יוצרים חיבור SSH:

      ssh root@INTERNAL-IP
      
    2. כדי לקבוע אם הצומת הנוכחי הוא etcd leader או follower, מריצים את הפקודה הבאה בטרמינל של SSH:

      ETCDCTL_API=3 etcdctl \
          --cacert /etc/kubernetes/pki/etcd/ca.crt \
          --cert /etc/kubernetes/pki/etcd/server.crt \
          --key /etc/kubernetes/pki/etcd/server.key \
          --write-out=table endpoint status
      

      שימו לב לשדה IS LEADER.

      הפלט יכול להיראות כמו בדוגמה הבאה של צומת המוביל של etcd:

      [root@**-**-bm0* ~]# ETCDCTL_API=3 etcdctl \
      >      --cacert /etc/kubernetes/pki/etcd/ca.crt \
      >      --cert /etc/kubernetes/pki/etcd/server.crt \
      >      --key /etc/kubernetes/pki/etcd/server.key \
      >      --write-out=table endpoint status
      +----------------+------------------+--------------+---------+-----------+------------+-----------+------------+--------------------+--------+
      |    ENDPOINT    |        ID        |   VERSION    | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
      +----------------+------------------+--------------+---------+-----------+------------+-----------+------------+--------------------+--------+
      | ************** | **************** | 3.4.30-gke.1 |  162 MB |      true |      false |      3641 |   12957958 |           12957958 |        |
      +----------------+------------------+--------------+---------+-----------+------------+-----------+------------+--------------------+--------+
      

      הפלט יכול להיראות כמו בדוגמה הבאה עבור שני צמתי המעקב של etcd:

      [root@**-**-bm0* ~]# ETCDCTL_API=3 etcdctl \
      >      --cacert /etc/kubernetes/pki/etcd/ca.crt \
      >      --cert /etc/kubernetes/pki/etcd/server.crt \
      >      --key /etc/kubernetes/pki/etcd/server.key \
      >      --write-out=table endpoint status
      +----------------+------------------+--------------+---------+-----------+------------+-----------+------------+--------------------+--------+
      |    ENDPOINT    |        ID        |   VERSION    | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
      +----------------+------------------+--------------+---------+-----------+------------+-----------+------------+--------------------+--------+
      | ************** | **************** | 3.4.30-gke.1 |  163 MB |     false |      false |      3641 |   12957404 |           12957404 |        |
      +----------------+------------------+--------------+---------+-----------+------------+-----------+------------+--------------------+--------+
      

      רושמים את הסטטוסים etcd-leader ו-etcd-follower של הצמתים.

  8. מרוקנים את הצמתים.

    מרוקנים את שני צמתי העוקבים של etcd. לא מנקזים את צומת ה-etcd הראשי

    kubectl drain NODE_NAME --delete-emptydir-data --grace-period 900 --ignore-daemonsets --disable-eviction
    

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

    node/**-**-bm01 already cordoned
    WARNING: ignoring DaemonSet-managed Pods: kube-system/anetd-krj2z, kube-system/etcd-defrag-xh469, kube-system/ipam-controller-manager-2f4dz, kube-system/istio-cni-node-cgqv4, kube-system/kube-proxy-5mwf2, kube-system/localpv-mn2jh, kube-system/metallb-speaker-6l7sv, mon-system/mon-node-exporter-backend-nd8mp, netapp-trident/netapp-trident-node-linux-rrlmd, obs-system/anthos-audit-logs-forwarder-tpfqv, obs-system/anthos-log-forwarder-npjh4, obs-system/kube-control-plane-metrics-proxy-wp8nh, obs-system/log-failure-detector-crbnv, obs-system/oplogs-forwarder-sqwvj, vm-system/macvtap-v9pgp, vm-system/virt-handler-86khx
    pod/grafana-0 deleted
    pod/capi-kubeadm-bootstrap-controller-manager-1.30.400-gke.136lvgtf deleted
    pod/grafana-0 deleted
    pod/grafana-proxy-server-86d8fc4758-mkc4f deleted
    .
    .
    .
    
    node/**-**-bm02 already cordoned
    WARNING: ignoring DaemonSet-managed Pods: kube-system/anetd-v75jz, kube-system/etcd-defrag-t5jnc, kube-system/ipam-controller-manager-5958m, kube-system/istio-cni-node-ggv4c, kube-system/kube-proxy-r6x46, kube-system/localpv-g56xc, kube-system/metallb-speaker-tmw72, mon-system/mon-node-exporter-backend-9rs7k, netapp-trident/netapp-trident-node-linux-9jmfp, obs-system/anthos-audit-logs-forwarder-bwns9, obs-system/anthos-log-forwarder-lbskj, obs-system/kube-control-plane-metrics-proxy-grthl, obs-system/log-failure-detector-dzh4v, obs-system/oplogs-forwarder-vdn7z, vm-system/macvtap-mjwtc, vm-system/virt-handler-dlqvv
    pod/vai-web-plugin-backend-5dfd6d6597-nxxgn
    pod/vai-web-plugin-frontend-6b5468968b-mrr7g
    pod/grafana-proxy-server-64b759fbf6-b8pl8
    pod/iam-bundledidp-backend-0
    .
    .
    .
    
  9. מבצעים כיבוי תקין של שני צמתי העוקבים של etcd. פועלים לפי השלב הבא אחד אחרי השני בשני הצמתים.

  10. השבתה של NODE_NAME באמצעות iLO:

    1. אחזור שם המשתמש של iLO:

      kubectl get secret bmc-credentials-NODE_NAME -n gpc-system -o jsonpath="{.data.username}" | base64 --decode
      
    2. שליפת הסיסמה של iLO:

      kubectl get secret bmc-credentials-NODE_NAME -n gpc-system -o jsonpath="{.data.password}" | base64 --decode
      
    3. אחזור כתובת BMC-IP של NODE_NAME מהערכים בעמודה BMC-IP:

      kubectl get servers -A
      
    4. עוברים לכתובת BMC-IP שהתקבלה בשלב הקודם ונכנסים לחשבון באמצעות שם המשתמש והסיסמה שהתקבלו.

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

  11. אחרי ששני הצמתים של etcd-follower נסגרים, חוזרים על השלב של הוצאת הצומת עבור הצומת המוביל של etcd.

הסרת מפתחות YubiKey לצורך העברה

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

הפעלה וחיבור

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

תוכנית פעולה

  1. מכניסים את מפתחות YubiKey לכל צומת.

  2. מחברים את מכונת ה-appliance של GDC עם air gap לחשמל, ולוחצים על כפתור ההפעלה בצומת **-**-bm03 כדי להפעיל את שרת הגישור של OTS.

  3. אחרי שהצומת **-**-bm03 הופך לזמין, בודקים את הסטטוס של שירותי מערכת היעד של SCSI ‏ (SCST) כדי לוודא ששרת הגישור של OTS פעיל. השירות הזה אמור להציג את האפשרויות הבאות: Active: active (running)

    sudo systemctl status scst.service
    
  4. לוחצים על לחצן ההפעלה בשני הצמתים הנותרים בכל סדר.

  5. אחרי שמפעילים את הצמתים, מחכים כמה דקות עד שמישור הבקרה מתחבר. ‫kubectl יכול להתחבר למישור הבקרה תוך פחות מ-30 דקות.

  6. כדי לקבל את שמות הצמתים, מריצים את הפקודה kubectl get nodes -A.

  7. כדי להפעיל את התזמון, צריך לבטל את ההגנה על כל צומת:

    kubectl uncordon `NODE_NAME`
    
  8. מחדשים את הסנכרון של המארחים מסוג Bare Metal לכל צומת:

    kubectl annotate bmhost -n gpc-system NODE_NAME "baremetalhost.metal3.io/paused=false" --overwrite
    
  9. כדי לשחזר את מדיניות האבטחה של האשכול, מחזירים את ההגדרה של ה-webhook לאימות של Gatekeeper ל-Fail:

    kubectl patch validatingwebhookconfiguration gatekeeper-validating-webhook-configuration -p '{"webhooks":[{"name":"validation.gatekeeper.sh","failurePolicy":"Fail"}]}'
    
  10. בודקים את סטטוס הצמתים באמצעות kubectl get nodes -A.

    • אם כל הצמתים במצב Ready, צריך להמתין שעתיים עד שתהליך ההתאמה יסתיים. הפלט יכול להיראות כך:

      NAME         STATUS     ROLES           AGE     VERSION
      **-**-bm01   Ready      control-plane   4d13h   v1.30.6-gke.300
      **-**-bm02   Ready      control-plane   4d13h   v1.30.6-gke.300
      **-**-bm03   Ready      control-plane   4d13h   v1.30.6-gke.300
      

      במקרה הזה, לא צריך לבצע פעולה נוספת.

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

      NAME         STATUS     ROLES           AGE     VERSION
      **-**-bm01   Ready      control-plane   4d13h   v1.30.6-gke.300
      **-**-bm02   Ready      control-plane   4d13h   v1.30.6-gke.300
      **-**-bm03   NotReady   control-plane   4d13h   v1.30.6-gke.300
      

      במקרה כזה, רושמים את שם הצומת שלא מוכן וממשיכים לשלבים הבאים.

  11. יוצרים חיבור SSH לצומת NotReady. כתובות ה-IP של יעד SSH הן ערכים בעמודה INTERNAL-IP של הפלט מ-kubectl get nodes -A -o wide:

    ssh root@INTERNAL-IP
    
  12. מפעילים מחדש את השירותים containerd ו-kubelet בצומת NotReady. צריך להריץ את הפקודות הבאות בצמתים, לא במחשב הנייד או בתחנת העבודה של הלקוח שמחוברים למכשיר Google Distributed Cloud (GDC) עם בידוד פיזי:

    systemctl stop containerd
    systemctl daemon-reload
    systemctl restart containerd
    systemctl stop kubelet
    systemctl start kubelet
    
  13. כדי לבדוק את הסטטוס של השירותים containerd ו-kubelet, מריצים את הפקודות הבאות בצומת NotReady:

    systemctl status kubelet
    systemctl status containerd
    

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

    # systemctl status kubelet kubelet.service - kubelet: The Kubernetes Node Agent
    Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled)
    Drop-In: /etc/systemd/system/kubelet.service.d
            └─00-standalone_containerd.conf, 10-kubeadm.conf
    Active: active (running) since Thu 2025-03-27 07:58:27 UTC; 34s ago
    .
    .
    .
    
    # systemctl status containerd containerd.service - containerd container runtime
    Loaded: loaded (/etc/systemd/system/containerd.service; disabled; vendor preset: disabled)
    Active: active (running) since Thu 2025-03-27 07:58:17 UTC; 52s ago
    .
    .
    .
    

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