הגדרת cgroups עם הרשאת כתיבה למאגרי מידע

אתם יכולים לאפשר לעומסי עבודה ב-Google Kubernetes Engine‏ (GKE) לנהל משאבים, כמו CPU וזיכרון, עבור תהליכי צאצא באמצעות ה-API של cgroups ב-Linux. במאמר הזה מוסבר איך לתת לקונטיינרים גישת קריאה וכתיבה ל-cgroups API בלי להריץ את הקונטיינרים האלה במצב הרשאות.

מתי כדאי להשתמש ב-cgroups עם הרשאת כתיבה

כברירת מחדל, Kubernetes מספקת לכל קונטיינר Linux גישת קריאה בלבד ל-cgroups API על ידי הרכבת מערכת הקבצים /sys/fs/cgroup בכל קונטיינר. אפשר גם לאפשר ל-GKE לטעון את מערכת הקבצים הזו במצב קריאה-כתיבה בתרמילים ספציפיים, כדי לתת לתהליכי הבסיס לנהל ולהגביל משאבים לתהליכי צאצא.

קבוצות cgroups עם הרשאת כתיבה עוזרות לשפר את האמינות באפליקציות כמו Ray, שמריצות תהליכי מערכת וקוד משתמש באותו קונטיינר. על ידי כתיבה למערכת הקבצים /sys/fs/cgroup, Ray יכולה לשריין חלקים מהמשאבים של קונטיינר לתהליכים קריטיים. אתם יכולים להשתמש ב-cgroups שניתנים לכתיבה כדי לשפר את המהימנות באפליקציות האלה בלי הסיכון האבטחתי שקיים בשימוש במצב הרשאות מיוחדות עבור הקונטיינרים.

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

לפני שמתחילים, חשוב לוודא שביצעתם את המשימות הבאות:

  • מפעילים את ממשק ה-API של Google Kubernetes Engine.
  • הפעלת Google Kubernetes Engine API
  • כדי להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז לאתחל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה gcloud components update כדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
  • מוודאים שיש לכם אשכול במצב Autopilot או אשכול רגיל שפועלת בו גרסה 1.34.1-gke.2541000 ואילך. כדי ליצור אשכול חדש, אפשר לעיין במאמר בנושא יצירת אשכול Autopilot.
  • מוודאים שהאשכול משתמש ב-cgroup v2. מידע נוסף מופיע במאמר בנושא העברת צמתים ל-Linux cgroup v2.

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

אפשר להפעיל cgroups עם הרשאת כתיבה בצמתים על ידי התאמה אישית של ההגדרה של containerd.

בקובץ ההגדרות של containerd, מוסיפים קטע writableCgroups ומגדירים את השדה enabled לערך true. מידע נוסף זמין במאמר בנושא התאמה אישית של הגדרות containerd בצמתי GKE.

writableCgroups:
  enabled: true

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

  • כדי ליצור אשכול חדש: מציינים את קובץ התצורה באמצעות הדגל --containerd-config-from-file כשיוצרים אשכול חדש (משתמשים בפקודה gcloud container clusters create או gcloud container clusters create-auto).
  • עדכון של אשכול קיים: מציינים את קובץ התצורה באמצעות הדגל --containerd-config-from-file כשמעדכנים את ברירות המחדל של הצמתים ברמת האשכול (משתמשים בפקודה gcloud container clusters update). עדכון של ברירות המחדל של הצמתים ברמת האשכול לא משפיע על צמתים קיימים. בקטרי סטנדרט, צריך לשדרג את מאגרי הצמתים הקיימים (משתמשים בפקודה gcloud container clusters upgrade עם הדגל --node-pool) או ליצור אותם מחדש כדי להחיל את ההגדרה.
  • יצירת מאגר צמתים חדש: באשכולות רגילים, מציינים את קובץ ההגדרות באמצעות הדגל --containerd-config-from-file כשיוצרים מאגר צמתים חדש (משתמשים בפקודה gcloud container node-pools create).

שימוש ב-cgroups עם הרשאות כתיבה בעומסי עבודה

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

  • בוחרים צומת שבו מופעלות קבוצות cgroups עם הרשאת כתיבה.
  • הפעלת cgroups עם הרשאת כתיבה עבור קונטיינר אחד או יותר ב-Pod.
  • משתמשים בסיווג איכות השירות (QoS) המובטחת אם מתקיים אחד מהתנאים הבאים:

    • בעומסי עבודה שבהם מוגדרים משאבים ברמת ה-Pod, צריך להגדיר ערכים זהים ל-resources.requests ול-resources.limits במפרט ה-Pod.
    • עבור עומסי עבודה שבהם מצוינים משאבים לכל קונטיינר, צריך להגדיר ערכים שווים ל-resources.requests ול-resources.limits במפרט של כל קונטיינר ב-Pod, כולל קונטיינרים של init.

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

  1. כדי לבחור צמתים שמופעלים בהם cgroups עם הרשאת כתיבה, מוסיפים את התווית node.gke.io/enable-writable-cgroups: "true" לשדה spec.nodeSelector במפרט ה-Pod:

    node.gke.io/enable-writable-cgroups: "true"
    
  2. כדי להפעיל קבוצות cgroups עם הרשאת כתיבה עבור עומס העבודה, מוסיפים אחת מההערות הבאות לשדה metadata.annotations במפרט של ה-Pod:

    • הפעלה בכל הפודקאסט:

      node.gke.io/enable-writable-cgroups: "true"
      
    • הפעלה עבור קונטיינר ספציפי ב-Pod:

      node.gke.io/enable-writable-cgroups.CONTAINER_NAME: "true"
      

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

  3. כדי להגדיר את מחלקת ה-QoS המובטחת עבור ה-Pod, מציינים בקשות ומגבלות שוות של CPU וזיכרון לכל קונטיינר ב-Pod או לכל ה-Pod, כמו בדוגמה הבאה:

    resources:
      requests:
        cpu: "100m"
        memory: "100Mi"
      limits:
        cpu: "100m"
        memory: "100Mi"
    

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

מפרט ה-Pod הסופי צריך להיות דומה לדוגמאות הבאות.

  • בדוגמה הזו מופעלות קבוצות cgroups עם הרשאת כתיבה לכל הקונטיינרים ב-Pod:

    apiVersion: v1
    kind: Pod
    metadata:
      name: writable-cgroups-pod
      annotations:
        node.gke.io/enable-writable-cgroups: "true"
    spec:
      nodeSelector:
        node.gke.io/enable-writable-cgroups: "true"
      containers:
      - name: container
        image: busybox:stable
        command: ["/bin/sh", "-c"]
        args:
        -   |
          trap 'echo "Caught SIGTERM, exiting..."; exit 0' TERM
          echo "Waiting for termination signal..."
          while true; do sleep 1; done
        resources:
          requests:
            cpu: "100m"
            memory: "100Mi"
          limits:
            cpu: "100m"
            memory: "100Mi"
    
  • בדוגמה הזו מופעלות קבוצות cgroups עם הרשאת כתיבה עבור קונטיינר ספציפי ב-Pod עם כמה קונטיינרים:

    apiVersion: v1
    kind: Pod
    metadata:
      name: writable-cgroups-per-container
      annotations:
        node.gke.io/enable-writable-cgroups.busybox-container: "true"
    spec:
      nodeSelector:
        node.gke.io/enable-writable-cgroups: "true"
      containers:
      - name: busybox-container
        image: busybox:stable
        command: ["/bin/sh", "-c"]
        args:
        -   |
          trap 'echo "Caught SIGTERM, exiting..."; exit 0' TERM
          echo "Waiting for termination signal..."
          while true; do sleep 1; done
        resources:
          requests:
            cpu: "100m"
            memory: "100Mi"
          limits:
            cpu: "100m"
            memory: "100Mi"
      - name: container-disabled
        image: busybox:stable
        command: ["/bin/sh", "-c"]
        args:
        -   |
          trap 'echo "Caught SIGTERM, exiting..."; exit 0' TERM
          echo "Waiting for termination signal..."
          while true; do sleep 1; done
        resources:
          requests:
            cpu: "100m"
            memory: "100Mi"
          limits:
            cpu: "100m"
            memory: "100Mi"
    

מוודאים שמערכת הקבצים של cgroup ניתנת לכתיבה

כדי לאמת את ההרשאות במערכת הקבצים /sys/fs/cgroup של Pod או של קונטיינר, פועלים לפי השלבים הבאים:

  1. מזהים את ה-Pod שרוצים לבדוק. אפשר להשתמש באחד מפודי הדוגמה שמופיעים בקטע שימוש ב-cgroup עם הרשאות כתיבה בעומסי עבודה.
  2. יוצרים סשן של מעטפת ב-Pod:

    kubectl exec -it POD_NAME -- /bin/sh
    

    מחליפים את POD_NAME בשם של ה-Pod.

  3. מתארים את מערכת הקבצים של cgroup שנטענה:

    mount | grep cgroup
    

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

    cgroup on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime)
    

    בפלט הזה, rw מציין שמערכת הקבצים ניתנת לכתיבה. אם רואים את התוצאה ro, מערכת הקבצים היא לקריאה בלבד.

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