יצירת עומסי עבודה עם שמירת מצב

במאמר הזה מוסבר איך ליצור ולנהל עומסי עבודה עם שמירת מצב (stateful) באשכול Kubernetes של Google Distributed Cloud (GDC) עם air gap. עומסי עבודה עם שמירת מצב מאפשרים להרחיב את פריסת האפליקציה באמצעות אחסון מתמיד. אחסון מתמיד מספק לאפליקציה זהויות עקביות ושמות מארחים יציבים, בלי קשר למקום שבו מתוזמנים עומסי העבודה שלה.

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

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

כדי להשלים את המשימות שבמסמך הזה, צריך לבקש את ההרשאות הנדרשות ולהכין את הסביבה.

בקשת תפקידים ב-IAM

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

תפקידים משותפים באשכול

כדי ליצור, למחוק, לערוך או להציג עומסי עבודה עם שמירת מצב באשכול משותף, בקשו מהאדמין של הפרויקט ב-IAM להקצות לכם את התפקיד אדמין של מרחב שמות (namespace-admin). התפקיד הזה קשור למרחב השמות של הפרויקט.

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

כדי ליצור, למחוק, לערוך או להציג עומסי עבודה עם שמירת מצב באשכול רגיל, בקשו מהאדמין של הפרויקט ב-IAM להקצות לכם את התפקיד מפתח אשכולות (cluster-developer). התפקיד הזה קשור למרחב השמות של הפרויקט.

הכנת הסביבה

כדי להריץ פקודות באשכול Kubernetes באמצעות ה-API, צריך לוודא שיש לכם את המשאבים הבאים:

  • מאתרים את שם האשכול של Kubernetes, או שואלים חבר בקבוצת האדמינים של הפלטפורמה מה שם האשכול.

  • נכנסים לחשבון ויוצרים את קובץ kubeconfig לאשכול Kubernetes.

  • בהוראות הבאות, מחליפים את KUBERNETES_CLUSTER_KUBECONFIG בנתיב kubeconfig של אשכול Kubernetes.

יצירת משאב StatefulSet

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

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

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

kubectl --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG -n NAMESPACE \
    apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
  name: SERVICE_NAME
  labels:
    app: APP_NAME
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: APP_NAME
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: STATEFULSET_NAME
spec:
  selector:
    matchLabels:
      app: APP_LABEL_NAME
  serviceName: "SERVICE_NAME"
  replicas: NUMBER_OF_REPLICAS
  template:
    metadata:
      labels:
        app: APP_LABEL_NAME
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: CONTAINER_NAME
        image: CONTAINER_IMAGE
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: CONTAINER_STORAGE_VOLUME_PATH
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi
EOF

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

  • ‫KUBERNETES_CLUSTER_KUBECONFIG: קובץ ה-kubeconfig של האשכול שאליו פורסים את עומסי העבודה של הקונטיינר.

  • ‫NAMESPACE: מרחב השמות שבו פורסים את עומסי העבודה של הקונטיינר. באשכולות משותפים, צריך להשתמש במרחב שמות של פרויקט. באשכולות רגילים, זה יכול להיות כל מרחב שמות.

  • ‫SERVICE_NAME: השם של האובייקט Service. חשוב לוודא שהאובייקט StatefulSet מגדיר את האובייקט Service גם ב-serviceName שלו.

  • ‫APP_NAME: שם האפליקציה שרוצים להריץ בפריסה.

  • ‫APP_LABEL_NAME: בורר התוויות שקובע אילו pod שייכים לאובייקט StatefulSet.

  • ‫STATEFULSET_NAME: השם של האובייקט StatefulSet.

  • ‫NUMBER_OF_REPLICAS: מספר האובייקטים המשוכפלים של Pod שהפריסה מנהלת.

  • ‫CONTAINER_NAME: שם הקונטיינר.

  • ‫CONTAINER_IMAGE: השם של קובץ האימג' של הקונטיינר. צריך לכלול את הנתיב של Container Registry ואת גרסת האימג', למשל REGISTRY_PATH/nginx:1.23. מידע נוסף על הגדרת הנתיב של Container Registry זמין בסקירה הכללית על Managed Harbor Service.

  • ‫CONTAINER_STORAGE_VOLUME_PATH: הנתיב בתוך הקונטיינר שבו מותקן נפח האחסון.

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

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "nginx"
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: REGISTRY_PATH/nginx:1.23
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

בדוגמה הזו:

  • נוצר אובייקט Service בשם nginx, שמצוין בשדה metadata: name. האובייקט Service מטרגט אפליקציה בשם nginx, שמצוינת על ידי labels.app: nginx ו-selector.app: nginx. האובייקט Service חושף את יציאה 80 ונותן לה את השם web. האובייקט Service הזה שולט בדומיין הרשת ומנתב את תעבורת הנתונים לאפליקציה בקונטיינר שנפרסה על ידי האובייקט StatefulSet.
  • נוצר StatefulSet בשם web עם שלושה אובייקטים משוכפלים של Pod, כפי שהוגדר בשדה replicas: 3.
  • התבנית Pod, שמוגדרת בקטע .spec.template, מציינת שהאובייקטים מסוג Pod מתויגים בתווית app: nginx.
  • המפרט Pod, שמוגדר בקטע .template.spec, מציין שה-pods של StatefulSet מריצים קונטיינר אחד, nginx, שמריץ את קובץ האימג' nginx בגרסה 1.23.
  • המפרט של Pod משתמש ביציאת האינטרנט שנפתחה על ידי האובייקט Service.
  • בקטע .template.spec.volumeMounts מצוין שדה mountPath בשם www. ‫mountPath הוא הנתיב בקונטיינר שבו נטען נפח האחסון.
  • ה-StatefulSet מקצה שלושה אובייקטים של PersistentVolumeClaim, בשמות web-www-0,‏ web-www-1 ו-web-www-2, עם נפח אחסון של 1GB לכל אחד.

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

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

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

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

מידע נוסף זמין במאמר הגדרת אחסון בקונטיינר.

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