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

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

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

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

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

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

  1. אפשר להריץ את חוברת ההוראות הזו במחשב נייד או בתחנת עבודה שמחוברים לרשת של מכשיר Google Distributed Cloud ‏ (GDC) עם בידוד פיזי. אפשר גם לחבר מחשב נייד או תחנת עבודה למתג באמצעות ההוראות שבקטע חיבור המכשיר.
  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>
    

    מכבים את הצמתים (מכונות ה-VM) של 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.

      הפלט יכול להיראות כמו בדוגמה הבאה של צומת ה-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 follower. לא מרוקנים את צומת ה-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 leader.

הסרת מפתחות 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
    

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

  11. אם אחד או יותר מהצמתים נמצאים במצב 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
    
    1. יוצרים חיבור SSH לצומת NotReady. כתובות ה-IP של היעד עבור SSH הן הערכים בעמודה INTERNAL-IP של הפלט מ-kubectl get nodes -A -o wide:

      ssh root@INTERNAL-IP
      
    2. מפעילים מחדש את השירותים containerd ו-kubelet בצומת NotReady. מריצים את הפקודות הבאות בצומת, לא במחשב הנייד או בתחנת העבודה שמחוברים למכשיר GDC עם air gap:

      systemctl stop containerd
      systemctl daemon-reload
      systemctl restart containerd
      systemctl stop kubelet
      systemctl start kubelet
      
    3. כדי לוודא את הסטטוס של השירותים 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 פועלים וכל הצמתים הם Ready, מחכים שעתיים כדי לאפשר למערך הבסיסי לסיים את ההתאמה לפני שמתחילים לפתור בעיות.