במאמר הזה מוסבר איך ליצור ולנהל עומסי עבודה עם שמירת מצב (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 משלה.
מידע נוסף זמין במאמר הגדרת אחסון בקונטיינר.