שימוש בדיסקים קיימים של אחסון מתמיד (persistent disks) כ-PersistentVolumes

בדף הזה מוסבר איך ליצור PersistentVolume באמצעות דיסקים לאחסון מתמיד קיימים שמלאים בנתונים, ואיך להשתמש ב-PersistentVolume ב-Pod.

סקירה כללית

יש שני תרחישים נפוצים שבהם נעשה שימוש בדיסק אחסון מתמיד קיים.

בדוגמאות שבדף הזה נעשה שימוש בדיסקים לאחסון מתמיד ב-Compute Engine.

ext4 היא סוג מערכת הקבצים שמוגדר כברירת מחדל, אבל אפשר להשתמש בדיסק אחסון מתמיד (persistent disk) קיים עם מערכת הקבצים xfs, בתנאי שתמונת הצומת תומכת בה. כדי להשתמש בדיסק xfs, משנים את spec.csi.fsType ל-xfs במניפסט של PersistentVolume.

‫Windows לא תומך בסוג מערכת הקבצים ext4. חובה להשתמש במערכת הקבצים NTFS עבור מאגרי צמתים של Windows Server. כדי להשתמש בדיסק NTFS, משנים את spec.csi.fsType ל-NTFS במניפסט של PersistentVolume.

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

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

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

שימוש ב-PersistentVolumeClaim שקשור ל-PersistentVolume

כדי שמכולה תוכל לגשת לדיסק אחסון מתמיד (persistent disk) קיים, צריך לבצע את הפעולות הבאות:

  1. הקצאת דיסק אחסון מתמיד (persistent disk) קיים כ-PersistentVolume.
  2. קישור של נפח האחסון המתמיד (PersistentVolume) לדרישת נפח אחסון מתמיד (PersistentVolumeClaim).
  3. נותנים לקונטיינרים ב-Pod גישה ל-PersistentVolume.

יצירת נפח אחסון מתמיד (PersistentVolume) ודרישה לנפח אחסון מתמיד (PersistentVolumeClaim)

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

כדי לקשר PersistentVolume ל-PersistentVolumeClaim, הערך של storageClassName בשני המשאבים חייב להיות זהה, וגם הערכים של capacity,‏ accessModes ו-volumeMode. אפשר להשמיט את storageClassName, אבל חובה לציין את "" כדי למנוע מ-Kubernetes להשתמש ב-StorageClass שמוגדר כברירת מחדל.

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

פרטים נוספים זמינים במאמרי העזרה של Kubernetes בנושא PersistentVolumes.

  1. שומרים את מניפסט ה-YAML הבא:

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: PV_NAME
    spec:
      storageClassName: "STORAGE_CLASS_NAME"
      capacity:
        storage: DISK_SIZE
      accessModes:
        - ReadWriteOnce
      claimRef:
        name: PV_CLAIM_NAME
        namespace: default
      csi:
        driver: pd.csi.storage.gke.io
        volumeHandle: DISK_ID
        fsType: FS_TYPE
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      namespace: default
      name: PV_CLAIM_NAME
    spec:
      storageClassName: "STORAGE_CLASS_NAME"
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: DISK_SIZE
    

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

    • PV_NAME: השם של PersistentVolume החדש.
    • STORAGE_CLASS_NAME: השם של ה-StorageClass החדש.
    • DISK_SIZE: הגודל של דיסק האחסון המתמיד הקיים. לדוגמה, 500G.
    • PV_CLAIM_NAME: השם של ה-PersistentVolumeClaim החדש.
    • DISK_ID: המזהה של דיסק קשיח קיים. הפורמט הוא projects/{project_id}/zones/{zone_name}/disks/{disk_name} עבור דיסקים לאחסון מתמיד של תחום, או projects/{project_id}/regions/{region_name}/disks/{disk_name} עבור דיסקים לאחסון מתמיד אזורי.
    • FS_TYPE: סוג מערכת הקבצים. אפשר להשאיר את ברירת המחדל (ext4) או להשתמש ב-xfs. אם באשכולות שלכם נעשה שימוש במאגר צמתים של Windows Server, אתם צריכים לשנות את זה ל-NTFS.
  2. כדי להחיל את ההגדרה וליצור את המשאבים PersistentVolume ו-PersistentVolumeClaim, מריצים את הפקודה הבאה:

    kubectl apply -f FILE_PATH
    

    מחליפים את הערך של FILE_PATH בנתיב לקובץ ה-YAML.

שימוש ב-PersistentVolume ב-Pod

אחרי שיוצרים את נפח האחסון המתמיד (PersistentVolume) ואת בקשת נפח האחסון המתמיד (PersistentVolumeClaim) ומקשרים ביניהם, אפשר לתת גישה למאגרי ה-Pod לנפח האחסון על ידי ציון ערכים בשדה volumeMounts.

הגדרת ה-YAML הבאה יוצרת Pod חדש וקונטיינר שמריץ תמונה של nginx, ואז מטמיעה את PersistentVolume ב-Pod:

kind: Pod
apiVersion: v1
metadata:
  name: POD_NAME
spec:
  volumes:
    - name: VOLUME_NAME
      persistentVolumeClaim:
        claimName: PV_CLAIM_NAME
  containers:
    - name: CONTAINER_NAME
      image: nginx
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: VOLUME_NAME

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

  • POD_NAME: השם של ה-Pod החדש.
  • VOLUME_NAME: שם אמצעי האחסון.
  • PV_CLAIM_NAME: השם של PersistentVolumeClaim שיצרתם בשלב הקודם.
  • CONTAINER_NAME: השם של מאגר התגים החדש.

מחילים את ההגדרה:

kubectl apply -f FILE_PATH

מחליפים את הערך של FILE_PATH בנתיב לקובץ ה-YAML.

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

kubectl describe pods POD_NAME

בפלט, בודקים שה-PersistentVolumeClaim הותקן:

...
Volumes:
  VOLUME_NAME:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  PV_CLAIM_NAME
    ReadOnly:   false
Events:
  Type    Reason                  Age   From                     Message
  ----    ------                  ----  ----                     -------
  Normal  Scheduled               29s   default-scheduler        Successfully assigned default/POD_NAME to gke-cluster-1-default-pool-d5cde866-o4g4
  Normal  SuccessfulAttachVolume  21s   attachdetach-controller  AttachVolume.Attach succeeded for volume "PV_NAME"
  Normal  Pulling                 19s   kubelet                  Pulling image "nginx"
  Normal  Pulled                  19s   kubelet                  Successfully pulled image "nginx"
  Normal  Created                 18s   kubelet                  Created container CONTAINER_NAME
  Normal  Started                 18s   kubelet                  Started container CONTAINER_NAME

שימוש בדיסק קיים ב-StatefulSet

אפשר להשתמש ב-Persistent Disks קיימים של Compute Engine ב-StatefulSet באמצעות PersistentVolumes. ה-StatefulSet יוצר באופן אוטומטי PersistentVolumeClaim לכל רפליקה. אפשר לחזות את השמות של ה-PersistentVolumeClaims שנוצרו ולקשר אותם ל-PersistentVolumes באמצעות claimRef.

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

  1. בוחרים שם ל-StatefulSet החדש, שם לתבנית PersistentVolumeClaim ומספר העותקים המשוכפלים ב-StatefulSet.
  2. מגלים את השמות של ה-PersistentVolumeClaims שנוצרו באופן אוטומטי. ‫StatefulSet משתמש בפורמט הבא לשמות של PersistentVolumeClaim:

    PVC_TEMPLATE_NAME-STATEFULSET_NAME-REPLICA_INDEX
    

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

    • PVC_TEMPLATE_NAME: השם של תבנית PersistentVolumeClaim החדשה.
    • STATEFULSET_NAME: השם של ה-StatefulSet החדש.
    • REPLICA_INDEX: האינדקס של הרפליקה של StatefulSet. בדוגמה הזו, נשתמש ב-0 וב-1.
  3. יוצרים את נפחי האחסון המתמיד (PersistentVolumes). צריך ליצור PersistentVolume לכל רפליקה ב-StatefulSet.

    1. שומרים את מניפסט ה-YAML הבא:

      apiVersion: v1
      kind: PersistentVolume
      metadata:
        name: pv-ss-demo-0
      spec:
        storageClassName: "STORAGE_CLASS_NAME"
        capacity:
          storage: DISK1_SIZE
        accessModes:
          - ReadWriteOnce
        claimRef:
          namespace: default
          name: PVC_TEMPLATE_NAME-STATEFULSET_NAME-0
        csi:
          driver: pd.csi.storage.gke.io
          volumeHandle: DISK1_ID
          fsType: FS_TYPE
       ---
      apiVersion: v1
      kind: PersistentVolume
      metadata:
        name: pv-ss-demo-1
      spec:
        storageClassName: "STORAGE_CLASS_NAME"
        capacity:
          storage: DISK2_SIZE
        accessModes:
          - ReadWriteOnce
        claimRef:
          namespace: default
          name: PVC_TEMPLATE_NAME-STATEFULSET_NAME-1
        csi:
          driver: pd.csi.storage.gke.io
          volumeHandle: DISK2_ID
          fsType: FS_TYPE
      

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

      • DISK1_SIZE and DISK2_SIZE: הגדלים של דיסקי האחסון המתמיד הקיימים.
      • DISK1_ID and DISK2_ID: המזהים של דיסקי אחסון מתמיד קיימים.
      • PVC_TEMPLATE_NAME-STATEFULSET_NAME-0 and PVC_TEMPLATE_NAME-STATEFULSET_NAME-1: השמות של ה-PersistentVolumeClaims שנוצרו באופן אוטומטי בפורמט שהוגדר בשלב הקודם.
      • STORAGE_CLASS_NAME: השם של StorageClass.
    2. מחילים את ההגדרה:

      kubectl apply -f FILE_PATH
      

      מחליפים את הערך של FILE_PATH בנתיב לקובץ ה-YAML.

  4. יוצרים StatefulSet באמצעות הערכים שבחרתם בשלב 1. חשוב לוודא שנפח האחסון שצוין ב-volumeClaimTemplates קטן או שווה לקיבולת הכוללת של PersistentVolumes.

    1. שומרים את מניפסט ה-YAML הבא:

      apiVersion: apps/v1
      kind: StatefulSet
      metadata:
        name: STATEFULSET_NAME
      spec:
        selector:
          matchLabels:
            app: nginx
        serviceName: "nginx"
        replicas: 2
        template:
          metadata:
            labels:
              app: nginx
          spec:
            terminationGracePeriodSeconds: 10
            containers:
            - name: nginx
              image: registry.k8s.io/nginx-slim:0.8
              ports:
              - containerPort: 80
                name: web
              volumeMounts:
              - name: PVC_TEMPLATE_NAME
                mountPath: /usr/share/nginx/html
        volumeClaimTemplates:
        - metadata:
            name: PVC_TEMPLATE_NAME
          spec:
            accessModes: [ "ReadWriteOnce" ]
            storageClassName: "STORAGE_CLASS_NAME"
            resources:
              requests:
                storage: 100Gi
      

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

      • STATEFULSET_NAME: השם של ה-StatefulSet החדש.
      • PVC_TEMPLATE_NAME: השם של תבנית ה-PersistentVolumeClaim החדשה.
      • STORAGE_CLASS_NAME: השם של StorageClass.
    2. מחילים את ההגדרה:

      kubectl apply -f FILE_PATH
      

      מחליפים את הערך של FILE_PATH בנתיב לקובץ ה-YAML.

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