חידוש ידני של אישורים לאשכולות שפג תוקפם

במאמר הזה מוסבר איך לחדש באופן ידני אישורים שתוקפם פג ב-Google Distributed Cloud. רכיבי מישור הבקרה של Google Distributed Cloud משתמשים באישור Transport Layer Security ‏ (TLS). כשאישורי האבטחה האלה פוקעים, אתם לא יכולים לנהל את עומסי העבודה ואת מחזורי החיים של האשכולות עד שאפשר לחדש את האישורים. מידע נוסף על ההשפעה של אישורים שפג תוקפם זמין במאמר בנושא תוקף האישורים.

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

כברירת מחדל, תוקף אישורי TLS, כולל אישורי etcd, הוא שנה אחת. ‫Google Distributed Cloud מחדשת את האישורים האלה במהלך שדרוגי אשכולות וכשמבצעים רוטציה של רשויות אישורים. האישורים האלה לא מתעדכנים מעצמם באופן תקופתי. מומלץ לשדרג את האשכולות באופן קבוע כדי לשמור על האבטחה שלהם, לקבל תמיכה ולמנוע את התפוגה של אישורי TLS.

שגיאות שנגרמות בגלל תפוגת האישור

אם תוקף אישורי ה-TLS באשכול פג, בקרי הליבה לא יכולים ליצור חיבורי TLS עם שרת ה-API של Kubernetes. היעדר הקישוריות גורם לשגיאות הבאות:

  • אי אפשר להתחבר לשרת: x509

    כשמשתמשים בפקודה kubectl כדי לקבל את הצמתים של האשכול, התגובה כוללת שגיאה שהאישורים פגו, כמו בדוגמה הבאה:

    Unable to connect to the server: x509: certificate has expired or is not yet valid
    
  • could not connect: x509 או rejected connection

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

    W | rafthttp: health check for peer 6221a1d241bb2d0a could not connect: x509: certificate
    has expired or is not yet valid
    I | embed: rejected connection from "10.200.0.4:46108" (error "remote error: tls: bad
    certificate", ServerName "")
    

בדיקת תאריכי התפוגה של האישורים

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

  1. נכנסים לאחת מהמכונות של צומת מישור הבקרה ומריצים את הפקודה הבאה:

    sudo kubeadm certs check-expiration
    

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

    CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
    admin.conf                 Nov 28, 2021 19:09 UTC   53m                                     no
    apiserver                  Nov 28, 2021 19:09 UTC   53m             ca                      no
    apiserver-etcd-client      Nov 28, 2021 19:09 UTC   53m             etcd-ca                 no
    apiserver-kubelet-client   Nov 28, 2021 19:09 UTC   53m             ca                      no
    controller-manager.conf    Nov 28, 2021 19:09 UTC   53m                                     no
    etcd-healthcheck-client    Nov 28, 2021 19:09 UTC   53m             etcd-ca                 no
    etcd-peer                  Nov 28, 2021 19:09 UTC   53m             etcd-ca                 no
    etcd-server                Nov 28, 2021 19:09 UTC   53m             etcd-ca                 no
    front-proxy-client         Nov 28, 2021 19:09 UTC   53m             front-proxy-ca          no
    scheduler.conf             Nov 28, 2021 19:09 UTC   53m                                     no
    
    CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
    ca                      Nov 26, 2031 18:06 UTC   9y              no
    etcd-ca                 Nov 26, 2031 18:06 UTC   9y              no
    front-proxy-ca          Nov 26, 2031 18:06 UTC   9y              no
    
  2. מריצים את הפקודה הבאה כדי לבדוק את תאריכי התפוגה של האישורים kubelet:

    sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -text | grep Validity -A2
    sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-server-current.pem -text | grep Validity -A2
    

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

    Validity
        Not Before: Sep 17 22:27:53 2021 GMT
        Not After : Sep 17 22:33:16 2022 GMT
    

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

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

    grep 'client-certificate-data' KUBECONFIG_PATH | \
        awk '{print $2}' | base64 -d | openssl x509 -text | grep Validity -A2
    

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

    Validity
        Not Before: Sep 17 22:27:53 2021 GMT
        Not After : Sep 17 22:33:16 2022 GMT
    
  4. מריצים את הפקודה הבאה כדי לחפש את תאריך התפוגה של האישור עבור קובץ ה-kubeconfig של האשכול באשכול הניהול:

    kubectl get secret/CLUSTER_NAME-kubeconfig \
        -n CLUSTER_NAMESPACE \
        --kubeconfig ADMIN_KUBECONFIG \
        -o jsonpath='{.data.value}' | base64 --decode | grep client-certificate-data | \
        awk '{print $2}' | base64 -d | openssl x509 -text | grep Validity -A2
    

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

    • ‫ADMIN_KUBECONFIG: הנתיב לקובץ kubeconfig של אשכול האדמין.

    • ‫CLUSTER_NAME: שם האשכול שעבורו מחדשים את האישורים.

    • ‫CLUSTER_NAMESPACE: מרחב השמות של האשכול שעבורו מחדשים את האישורים.

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

    Validity
        Not Before: Sep 17 22:27:53 2021 GMT
        Not After : Sep 17 22:33:16 2022 GMT
    

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

חידוש אישורים באופן ידני

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

חידוש האישורים בכל צומת של מישור הבקרה

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

  1. מגבים את התיקייה /etc/kubernetes.

  2. מריצים את הפקודה הבאה kubeadm כדי לחדש את כל האישורים. הפקודה מחדשת את האישורים באמצעות רשויות האישורים (CA) הקיימות במחשב:

    sudo kubeadm certs renew all
    

    פלט הפקודה דומה לדוגמה הבאה:

    certificate embedded in the kubeconfig file for the admin to use and for kubeadm itself renewed
    certificate for serving the Kubernetes API renewed
    certificate the apiserver uses to access etcd renewed
    certificate for the API server to connect to kubelet renewed
    certificate embedded in the kubeconfig file for the controller manager to use renewed
    certificate for liveness probes to healthcheck etcd renewed
    certificate for etcd nodes to communicate with each other renewed
    certificate for serving etcd renewed
    certificate for the front proxy client renewed
    certificate embedded in the kubeconfig file for the scheduler manager to use renewed
    
  3. מריצים את הפקודה הבאה כדי לוודא שלאישורים יש מועד תפוגה חדש:

    sudo kubeadm certs check-expiration
    
  4. לא כל הרכיבים של מישור הבקרה תומכים בטעינה מחדש דינמית של אישורים. כדי לאסוף את האישורים המחודשים, צריך להפעיל מחדש את המאגרי התגים הבאים: kube-apiserver,‏ kube-scheduler ו-kube-controller-manager.

    חוזרים על השלבים הבאים עבור כל אחד מארבעת המאגרי:

    1. מוצאים את מזהה המאגר של כל מאגר:

      sudo crictl ps | grep CONTAINER_NAME
      

      מחליפים את CONTAINER_NAME בשם של אחד מהמאגרים הבאים: kube-apiserver, kube-scheduler או kube-controller-manager.

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

      c331ade490cb6       28df10594cd92      26 hours ago       Running          kube-apiserver ...
      

      מזהה מאגר התגים הוא הערך בעמודה הראשונה.

    2. עוצרים כל קונטיינר:

      sudo crictl stop CONTAINER_ID
      

      מחליפים את CONTAINER_ID במזהה הקונטיינר מהשלב הקודם.

      כשמאגר התגים שהופסק יוצא, kubelet יוצר מאגר תגים חדש במקומו ומוחק את מאגר התגים שהופסק. אם מופיעה שגיאה, כמו context deadline exceeded (קוד השגיאה DeadlineExceeded), מריצים מחדש את הפקודה.

אימות החיבור

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

  • כדי לאמת את החיבור לשרת Kubernetes API, מריצים את הפקודה kubectl הבאה בכל צומת של מישור הבקרה:

    kubectl get nodes --kubeconfig /etc/kubernetes/admin.conf
    

התשובה צריכה להכיל את רשימת הצמתים של האשכול. אם חידשתם את האישורים בצורה תקינה, לא יוחזרו שגיאות TLS או שגיאות שקשורות לאישור.

עדכון הסוד של kubeconfig באשכול

בשלבים הבאים משתמשים באישור המחודש מקובץ admin.conf כדי לעדכן את הסוד של kubeconfig עבור האשכול. עם זאת, אי אפשר להשתמש בתוכן של הקובץ המעודכן admin.conf כמו שהוא. קודם צריך ליצור עותק של הקובץ admin.conf ולערוך אותו.

כדי לעדכן את קובץ ה-kubeconfig החדש בסוד, מבצעים את השלבים הבאים בצומת של מישור הבקרה:

  1. משתמשים בפקודה sed כדי להחליף את kubernetes בקובץ admin.conf בשם של האשכול, וכותבים את השינויים לקובץ חדש, kubeconfig_secret.conf:

    sed "s/kubernetes/CLUSTER_NAME/g" \
        /etc/kubernetes/admin.conf > /etc/kubernetes/kubeconfig_secret.conf
    
  2. כדי לוודא שהקובץ kubeconfig_secret.conf עודכן, משתמשים ב-diff:

    diff /etc/kubernetes/admin.conf /etc/kubernetes/kubeconfig_secret.conf
    

    בתגובה מוצגים כל המקומות שבהם הקובץ kubeconfig_secret.conf שונה מהקובץ admin.conf המעודכן. לדוגמה, אם ביצעתם את השלב הקודם עבור אשכול בשם demo-cluster, הפלט ייראה בערך כך:

    6c6
    <   name: kubernetes
    ---
    >   name: demo-cluster
    9,12c9,12
    <     cluster: kubernetes
    <     user: kubernetes-admin
    <   name: kubernetes-admin@kubernetes
    < current-context: kubernetes-admin@kubernetes
    ---
    >     cluster: demo-cluster
    >     user: demo-cluster-admin
    >   name: demo-cluster-admin@demo-cluster
    > current-context: demo-cluster-admin@demo-cluster
    16c16
    < - name: kubernetes-admin
    ---
    > - name: demo-cluster-admin
    
  3. מריצים את הפקודות הבאות כדי לעדכן את הסוד של kubeconfig באשכול:

    CLUSTER_KUBECONFIG_BASE64=$(base64 /etc/kubernetes/kubeconfig_secret.conf -w 0)
    
    kubectl get secret/CLUSTER_NAME-kubeconfig \
        -n CLUSTER_NAMESPACE \
        --kubeconfig /etc/kubernetes/admin.conf -o json | jq \
        --arg conf "${CLUSTER_KUBECONFIG_BASE64}" '.data."value" |= $conf' | kubectl apply \
        --kubeconfig /etc/kubernetes/admin.conf -f -
    

החלפת קובץ ה-kubeconfig של האשכול

כדי להחליף את קובץ ה-kubeconfig של האשכול בקובץ עם האישורים המחודשים, פועלים לפי השלבים הבאים:

  1. מעתיקים את הקובץ admin.conf מאחד מצמתי מישור הבקרה של האשכול אל תחנת העבודה של האדמין.

    כמו שצוין בקטעים הקודמים, הקובץ admin.conf נמצא בספרייה etc/kubernetes בצמתי מישור הבקרה של האשכול.

  2. כדי ליצור את קובץ ה-kubeconfig החדש, מריצים את הפקודה kubectl הבאה בתחנת העבודה של האדמין:

    kubectl --kubeconfig ADMIN_CONF_PATH get secret/CLUSTER_NAME-kubeconfig  \
        -n "CLUSTER_NAMESPACE" -o jsonpath='{.data.value}'  | \
        base64 --decode > new_kubeconfig.conf
    

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

    • ‫ADMIN_CONF_PATH: הנתיב של קובץ admin.conf שהועתק לתחנת העבודה של האדמין מצומת של מישור הבקרה.

    • ‫CLUSTER_NAME: שם האשכול שעבורו מחדשים את האישורים.

    • ‫CLUSTER_NAMESPACE: מרחב השמות של האשכול שעבורו מחדשים את האישורים.

    הקובץ new_kubeconfig.conf מכיל את נתוני האישור המעודכנים.

  3. מריצים פקודה כלשהי של kubectl באמצעות פרטי הכניסה החדשים כדי לוודא שקובץ ה-kubeconfig החדש פועל:

    kubectl get nodes --kubeconfig new_kubeconfig.conf
    
  4. מחליפים את התוכן של קובץ ה-kubeconfig הישן שנשמר בספריית האשכול בתחנת העבודה של האדמין בתוכן של קובץ ה-kubeconfig החדש new-kubeconfig.conf.

    כברירת מחדל, הנתיב לקובץ התצורה של האשכול הוא bmctl-workspace/CLUSTER_NAME/CLUSTER_NAME-kubeconfig.

אימות של אישורי kubelet והפעלה מחדש של etcd-defrag

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

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

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

    sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -text | grep Validity -A2
    sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-server-current.pem -text | grep Validity -A2
    

    הפלט של כל אחת מהפקודות אמור להיראות כך:

    Validity
        Not Before: Nov 28 18:04:57 2022 GMT
        Not After : Nov 28 19:04:57 2023 GMT
    
  2. כדי להפעיל מחדש את מאגר etcd-defrag, מריצים את הפקודה הבאה:

    קונטיינר etcd-defrag משתמש באישור לקוח apiserver-etcd כדי לתקשר עם etcd, וצריך להפעיל אותו מחדש כדי לאסוף את האישורים המעודכנים.

    kubectl rollout restart daemonset etcd-defrag -n kube-system --kubeconfig KUBECONFIG_PATH
    

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

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

לקבלת עזרה נוספת, אפשר לפנות אל Cloud Customer Care. אפשר גם לעיין במאמר קבלת תמיכה לקבלת מידע נוסף על מקורות מידע לתמיכה, כולל:

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