פריסה של אפליקציה עם שמירת מצב

בדף הזה מוסבר איך לפרוס אפליקציה עם שמירת מצב (stateful) באמצעות Google Kubernetes Engine ‏(GKE).

סקירה כללית

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

אפשר להקצות באופן דינמי אחסון מתמיד, כך שהנפחים הבסיסיים נוצרים על פי דרישה. ב-Kubernetes, אתם מגדירים הקצאה דינמית על ידי יצירת StorageClass. ב-GKE, ברירת המחדל של StorageClass מאפשרת להקצות באופן דינמי דיסקים לאחסון מתמיד של Compute Engine.

‫Kubernetes משתמש בבקר StatefulSet כדי לפרוס אפליקציות עם שמירת מצב כאובייקטים של StatefulSet. פודים ב-StatefulSets לא ניתנים להחלפה: לכל פוד יש מזהה ייחודי שנשמר בכל מקום שבו הוא מתוזמן.

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

מידע נוסף על אחסון מתמיד באשכולות בכמה אזורים ובאשכולות אזוריים

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

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

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

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

בקשה לאחסון מתמיד ב-StatefulSet

אפליקציות יכולות לבקש אחסון מתמיד באמצעות PersistentVolumeClaim.

בדרך כלל צריך ליצור אובייקטים מסוג PersistentVolumeClaim בנוסף ליצירת ה-Pod. עם זאת, אובייקטים של StatefulSet כוללים מערך volumeClaimTemplates, שיוצר באופן אוטומטי את האובייקטים של PersistentVolumeClaim. כל רפליקה של StatefulSet מקבלת אובייקט PersistentVolumeClaim משלה.

אפשר גם להשתמש בדיסק קיים ב-StatefulSet.

קישור טופולוגיה דינמי

כשיוצרים StatefulSets שמשתמשים ב-PersistentVolumes אזוריים, מומלץ להגדיר את StorageClass עם צמד הערכים בשדה volumeBindingMode: WaitForFirstConsumer. ההגדרה הזו עוזרת לוודא שהקצאת הנפח מתעכבת עד ש-Pod מתוזמן לצומת תקין באזור עם מספיק קיבולת מחשוב. אם משתמשים בקישור המיידי שמוגדר כברירת מחדל, מסתכנים בנעילת אמצעי האחסון של Pod לאזור שבו אין מספיק קיבולת מחשוב לפני שה-Pod מתוזמן, מה שגורם ל-Pod להיתקע במצב Pending.

יצירת StatefulSet

כדי ליצור משאב StatefulSet, משתמשים בפקודה kubectl apply.

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

Linux

קובץ המניפסט הבא הוא דוגמה לשירות Headless ול-StatefulSet שהוא מנהל:

apiVersion: v1
kind: Service
metadata:
  name: SERVICE_NAME
  labels:
    app: APP_NAME
spec:
  ports:
  - port: 80
    name: PORT_NAME
  clusterIP: None
  selector:
    app: APP_NAME
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: STATEFULSET_NAME
spec:
  selector:
    matchLabels:
      # Selects Pods with this label.
      app: APP_NAME
  # Headless Service for network identity.
  serviceName: "SERVICE_NAME"
  replicas: 3
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: APP_NAME
    spec:
      containers:
      - name: CONTAINER_NAME
        image: IMAGE
        ports:
        - containerPort: 80
          name: PORT_NAME
        volumeMounts:
        - name: PVC_NAME
          mountPath: MOUNT_PATH
  volumeClaimTemplates:
  - metadata:
      name: PVC_NAME
      annotations:
        KEY: VALUE
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

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

  • ‫STATEFULSET_NAME: השם של ה-StatefulSet, לדוגמה web.
  • ‫SERVICE_NAME: שם השירות, לדוגמה nginx.
  • ‫APP_NAME: שם האפליקציה שפועלת ב-Pods, לדוגמה nginx.
  • ‫CONTAINER_NAME: שם הקונטיינרים ב-Pods, לדוגמה nginx.
  • ‫IMAGE: קובץ האימג' של הקונטיינר, לדוגמה nginx:stable.
  • ‫PORT_NAME: שם היציאה שנפתחה על ידי StatefulSet, לדוגמה web.
  • ‫PVC_NAME: השם של PersistentVolumeClaim, לדוגמה www.
  • ‫MOUNT_PATH: הנתיב בקונטיינר שבו האחסון מותקן, לדוגמה /usr/share/nginx/html.
  • ‫KEY ו-VALUE: צמד מפתח/ערך של הערה שצריך להחיל על המטא-נתונים של PersistentVolumeClaim. אתם יכולים להשתמש בהערות כדי לצרף לאובייקטים מטא-נתונים שרירותיים שלא מאפשרים זיהוי, שאפשר לאחזר באמצעות לקוחות כמו כלים וספריות. מידע נוסף על הערות

בקובץ הזה, השדה kind מציין שצריך ליצור אובייקט StatefulSet עם המפרטים שמוגדרים בקובץ. ה-StatefulSet לדוגמה הזה יוצר שלושה פודים משוכפלים, ופותח את יציאה 80 כדי לחשוף את ה-StatefulSet לאינטרנט.

Windows

כשמשתמשים באשכולות עם מאגרי צמתים של Windows Server, צריך ליצור StorageClass כי ברירת המחדל של StorageClass משתמשת ב-ext4 כסוג מערכת הקבצים, וזה עובד רק בקונטיינרים של Linux. אם אתם משתמשים בדיסק אחסון מתמיד (persistent disk) של Compute Engine, אתם צריכים להשתמש ב-NTFS כסוג האחסון של הקבצים, כמו בדוגמה הבאה:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  # Defines a name for this StorageClass.
  name: STORAGECLASS_NAME
parameters:
  # Specifies the type of Google Compute Engine persistent disk.
  type: pd-standard
  # Uses NTFS file system, which is crucial for Windows nodes
  fstype: NTFS
# The provisioner for Google Compute Engine persistent disks.
provisioner: kubernetes.io/gce-pd
# Specifies that the PersistentVolume will be deleted if the PersistentVolumeClaim is deleted.
reclaimPolicy: Delete
# Delays volume binding until a Pod using the PVC is scheduled.
volumeBindingMode: WaitForFirstConsumer

במניפסט הבא של StatefulSet נעשה שימוש ב-StorageClass שהוגדר למעלה. הוא יוצר ארבעה זוגות של PersistentVolume ו-PersistentVolumeClaim שמייצגים ארבעה דיסקים לאחסון מתמיד של Compute Engine. כל Pod ב-StatefulSet צורך דיסק אחסון מתמיד (persistent disk) אחד.

כדי לוודא שה-Pods מתוזמנים בצורה נכונה לצומתי Windows Server, צריך להוסיף בורר צמתים למפרט ה-Pod.

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: STATEFULSET_NAME
spec:
  replicas: 4
  selector:
    matchLabels:
      # Selects Pods with this label.
      app: APP_NAME
  template:
    metadata:
      labels:
        # Labels applied to the Pods created by the StatefulSet.
        app: APP_NAME
      name: CONTAINER_NAME
    spec:
      nodeSelector:
        # Ensures Pods are scheduled on Windows nodes.
        kubernetes.io/os: windows
      containers:
      - name: CONTAINER_NAME
        image: IMAGE
        ports:
        - containerPort: 80
          name: PORT_NAME
        volumeMounts:
        - name: PVC_NAME
          mountPath: MOUNT_PATH
  volumeClaimTemplates:
  - metadata:
      name: PVC_NAME
    spec:
      # Specifies the StorageClass to use, which is crucial for Windows nodes.
      storageClassName: STORAGECLASS_NAME
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

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

  • ‫STATEFULSET_NAME: השם של ה-StatefulSet, לדוגמה web-windows.
  • ‫APP_NAME: שם האפליקציה שפועלת ב-Pods, לדוגמה iis.
  • ‫CONTAINER_NAME: שם הקונטיינרים ב-Pods, לדוגמה iis.
  • ‫IMAGE: קובץ האימג' של הקונטיינר, לדוגמה mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019.
  • ‫PORT_NAME: שם היציאה שנפתחה על ידי StatefulSet, לדוגמה http.
  • ‫PVC_NAME: השם של PersistentVolumeClaim, לדוגמה iis-state.
  • ‫MOUNT_PATH: הנתיב בקונטיינר שבו האחסון מותקן, לדוגמה C:\mnt\state.
  • ‫STORAGECLASS_NAME: השם של StorageClass, לדוגמה my-storage-class.

כדי ליצור משאב StatefulSet, מריצים את הפקודה הבאה ומחליפים את STATEFULSET_FILE בשם של קובץ המניפסט:

kubectl apply -f STATEFULSET_FILE

אפשר גם להשתמש ב-kubectl apply -f DIRECTORY/ כדי ליצור את כל האובייקטים (חוץ מאלה שכבר קיימים) שמוגדרים בקובצי תצורה שמאוחסנים בספרייה.

בדיקת StatefulSet

kubectl

כדי לבדוק את ה-StatefulSet, מריצים את הפקודה הבאה:

kubectl get statefulset STATEFULSET_NAME -o yaml

הפקודה הזו מציגה את ההגדרות הפעילות של המשאב StatefulSet בפורמט YAML.

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

kubectl get pods -l app=APP_NAME

בפקודה הזו, הדגל -l מורה ל-kubectl לקבל את כל ה-Pods שמתויגים ל-APP_NAME.

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

NAME                                READY     STATUS    RESTARTS   AGE
pod-name                            1/1       Running   0          1m
pod-name                            1/1       Running   0          1m

כדי לקבל מידע מפורט על ה-StatefulSet, מריצים את הפקודה הבאה:

kubectl describe statefulset STATEFULSET_NAME

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

kubectl describe pod POD_NAME

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

kubectl get pvc

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

NAME                            STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS    AGE
STATEFULSET_NAME-PVC_NAME-0     Bound     pvc-bdff4e1e-183e-11e8-bf6d-42010a800002   1G         RWO            standard        9s
STATEFULSET_NAME-PVC_NAME-1     Bound     pvc-bdff4e1e-183e-11e8-bf6d-42010a800003   1G         RWO            standard        9s
STATEFULSET_NAME-PVC_NAME-2     Bound     pvc-bdff4e1e-183e-11e8-bf6d-42010a800004   1G         RWO            standard        9s

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

kubectl describe pvc STATEFULSET_NAME-PVC_NAME-0

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

kubectl describe pv PV_NAME

המסוף

כדי לבדוק StatefulSet:

  1. נכנסים לדף Workloads במסוף Google Cloud .

    כניסה לדף Workloads

  2. ברשימת עומסי העבודה, לוחצים על השם של ה-StatefulSet שרוצים לבדוק.

  3. בדף Stateful Set details, מבצעים את הפעולות הבאות:

    • לוחצים על הכרטיסייה Revision History כדי לראות את היסטוריית הגרסאות של ה-StatefulSet.
    • לוחצים על הכרטיסייה Events כדי לראות את כל האירועים שקשורים ל-StatefulSet.
    • לוחצים על הכרטיסייה Logs כדי לראות את יומני הקונטיינרים של ה-StatefulSet.
    • לוחצים על הכרטיסייה YAML כדי לראות, להעתיק או להוריד את קובץ ה-YAML של הגדרת ה-StatefulSet.

עדכון של StatefulSet

יש כמה דרכים לעדכן StatefulSets. השיטה הנפוצה וההצהרתית היא kubectl apply. כדי לעדכן את ה-StatefulSet ישירות מהמעטפת או בעורך המועדף, אפשר להשתמש ב-kubectl edit. אפשר גם להשתמש בעורך YAML מתפריט GKE Workloads במסוף Google Cloud .

אפשר להשיק עדכונים למפרט Pods של משאב StatefulSet, כמו התמונה, השימוש במשאבים או הבקשות למשאבים, או ההגדרות שלו.

kubectl apply

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

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

kubectl apply -f STATEFULSET_FILE

מחליפים את STATEFULSET_FILE בקובץ מניפסט העדכונים.

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

מידע נוסף על kubectl apply זמין במאמרי העזרה של kubectl.

המסוף

כדי לערוך את ההגדרות של StatefulSet פעיל:

  1. נכנסים לדף Workloads במסוף Google Cloud .

    כניסה לדף Workloads

  2. ברשימת עומסי העבודה, לוחצים על השם של ה-StatefulSet שרוצים לשנות.

  3. לוחצים על עריכה.

  4. משנים את קובץ ה-YAML של ההגדרות לפי הצורך.

  5. לוחצים על Save.

בדיקת ההשקה של העדכון

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

kubectl rollout status statefulset STATEFULSET_NAME

כדי לראות את היסטוריית ההשקה של StatefulSet, מריצים את הפקודה הבאה:

kubectl rollout history statefulset STATEFULSET_NAME

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

kubectl rollout undo statefulset STATEFULSET_NAME

שיטות עדכון

השדה updateStrategy של StatefulSet מאפשר להגדיר ולהשבית עדכונים אוטומטיים בהדרגה (rolling) של קונטיינרים, תוויות, בקשות למשאבים, מגבלות והערות ל-Pods ב-StatefulSet.

מידע נוסף על שיטות עדכון של StatefulSets זמין במסמכי התיעוד של Kubernetes.

התאמה לעומס (scaling) של StatefulSet

kubectl

אפשר להשתמש בפקודה kubectl scale בכל שלב כדי לשנות את קנה המידה של StatefulSet.

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

kubectl scale statefulset STATEFULSET_NAME --replicas NUMBER_OF_REPLICAS

מחליפים את NUMBER_OF_REPLICAS במספר הרצוי של Pods משוכפלים.

המסוף

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

  1. נכנסים לדף Workloads במסוף Google Cloud .

    כניסה לדף Workloads

  2. ברשימת עומסי העבודה, לוחצים על השם של ה-StatefulSet שרוצים לשנות.

  3. לוחצים על Actions > Scale > Edit replicas.

  4. מזינים את המספר החדש של Replicas ל-StatefulSet.

  5. לוחצים על קנה מידה.

מחיקת StatefulSet

kubectl

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

kubectl delete statefulset STATEFULSET_NAME

המסוף

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

  1. נכנסים לדף Workloads במסוף Google Cloud .

    כניסה לדף Workloads

  2. ברשימת עומסי העבודה, בוחרים StatefulSet אחד או יותר שרוצים למחוק.

  3. לוחצים על מחיקה.

  4. כשמופיעה בקשה לאישור, לוחצים על מחיקה.

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