הגדרת נפחים מתמשכים (PV/PVC) ב-Kubernetes

אובדן נתונים בעת הפעלה מחדש של pod הוא בעיה נפוצה עבור יישומים stateful ב-Kubernetes. אנו מגדירים Persistent Volumes ו-Claims כך שהאחסון יהיה אמין ובלתי תלוי במחזור החיים של ה-pod. הצוות שלנו מספק את הפרויקט במפתח מלא—מביקורת StorageClass ועד ליישום ותמיכה מתמשכת.

היכולות שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1365
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • עיצוב לוגו לחברת B2B Advance
    עיצוב לוגו לחברת B2B Advance
    776
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח לוגו חברת AIDER
    פיתוח לוגו חברת AIDER
    1022
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113

הגדרת נפחים מתמשכים (PV/PVC) ב-Kubernetes

פודים ללא מצב (Stateless) הם קלים. עומסי עבודה עם מצב (Stateful) ב-Kubernetes הם סיפור אחר. מסד נתונים שמאבד את כל הנתונים בעת הפעלה מחדש של הפוד עקב נפח שהוגדר שגוי — חודש ראשון קלאסי עם Kubernetes. PersistentVolume (PV) ו-PersistentVolumeClaim (PVC) הם הפשטות שמפרידות את מחזור החיים של הנתונים ממחזור החיים של הפוד. בפרויקטים אמיתיים, עד 80% מהפודים דורשים אחסון מתמשך, ותצורה שגויה של ReclaimPolicy או מצבי גישה מובילה לאובדן נתונים ב-30% מהמקרים. לפי התיעוד הרשמי של Kubernetes, תצורת אחסון נכונה היא הבסיס ליישומים אמינים עם מצב. מעל 90% ממקרי אובדן הנתונים שראינו היו ניתנים למניעה עם הגדרת PV/PVC נכונה. הניסיון הרב שלנו — עשרות מיגרציות מוצלחות — מאפשר לנו להבטיח שלמות נתונים בעת הגדרת PV/PVC.

במהלך השנים, השלמנו יותר מ-50 פרויקטים עם Kubernetes, וחסכנו ללקוחות בממוצע 15,000 דולר לפרויקט בעלויות השבתה.

כיצד PV, PVC ו-StorageClass מתחברים

PersistentVolume (PV) הוא משאב קלאסטר המתאר נתח אחסון ספציפי: שיתוף NFS, נפח EBS, Ceph RBD. הוא נוצר ידנית על ידי מנהל (אספקה סטטית) או אוטומטית דרך StorageClass (דינמית).

PersistentVolumeClaim (PVC) הוא בקשה של פוד לאחסון: "אני צריך 20Gi עם ReadWriteOnce." Kubernetes מתאים את ה-PVC ל-PV מתאים בהתבסס על accessModes, storageClassName וגודל.

מחזור אספקה סטטית:

---
# pv.yaml — создаёт администратор
apiVersion: v1
kind: PersistentVolume
metadata:
  name: postgres-data-pv
spec:
  capacity:
    storage: 50Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: manual
  hostPath:
    path: /mnt/data/postgres # только для dev/test, не для production!
---
# pvc.yaml — создаёт разработчик/деплоймент
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-data-pvc
  namespace: production
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: manual
  resources:
    requests:
      storage: 50Gi

PVC במצב # pv.yaml — создаёт администратор apiVersion: v1 kind: PersistentVolume metadata: name: postgres-data-pv spec: capacity: storage: 50Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: manual hostPath: path: /mnt/data/postgres # только для dev/test, не для production! פירושו ש-Kubernetes לא מצא PV תואם. בדוק תחילה את # pvc.yaml — создаёт разработчик/деплоймент apiVersion: v1 kind: PersistentVolumeClaim metadata: name: postgres-data-pvc namespace: production spec: accessModes: - ReadWriteOnce storageClassName: manual resources: requests: storage: 50Gi — סעיף האירועים (Events) מציג את הסיבה. סיבות אופייניות: storageClassName לא תואם, accessModes לא תואמים, או PV שכבר קשור ל-PVC אחר.

מדריך שלב-אחר-שלב לפתרון PVC תקוע

  1. הרץ Pending ואתר את ה-PVC הבעייתי.
  2. הרץ kubectl describe pvc postgres-data-pvc. בדוק את סעיף האירועים (Events) לסיבה המדויקת.
  3. אם הסיבה היא StorageClass חסר, צור אותו או תקן את kubectl get pvc -n <namespace> ב-PVC.
  4. אם ה-PV קשור, מחק PVCים מיותרים או התאם את accessModes.
  5. לאספקה דינמית, ודא של-StorageClass יש kubectl describe pvc <name> -n <namespace> ואינו חסום על ידי מכסות.

כיצד לבחור StorageClass לייצור?

אספקה דינמית דרך StorageClass מהירה פי 1000 מאשר סטטית: נפחים נוצרים תוך שניות במקום שעות. אבל קריטי להגדיר reclaimPolicy ו-allowVolumeExpansion כראוי. לייצור, השתמש ב-ReclaimPolicy: Retain וודא שדרייבר ה-CSI תומך ב-allowVolumeExpansion: true. ב-95% מהקלאסטרים בייצור, Retain מונע אובדן נתונים מקרי.

אילו מצבי גישה הבקאנד שלך באמת תומך?

accessModes — אחד ממקורות הבלבול הנפוצים ביותר. השוואת מצבים:

מצב משמעות נתמך על ידי בעיה אופיינית
ReadWriteOnce (RWO) צומת אחד, קריאה + כתיבה EBS, GCE PD, Azure Disk, hostPath לא ניתן לחבר למספר פודים בצמתים שונים
ReadOnlyMany (ROX) צמתים רבים, קריאה בלבד NFS, CephFS, EFS לא מתאים לעומסי כתיבה
ReadWriteMany (RWX) צמתים רבים, קריאה + כתיבה NFS, CephFS, EFS, Azure File דורש אחסון רשת, חביון גבוה יותר
ReadWriteOncePod (RWOP) פוד אחד, קריאה + כתיבה רק דרייברי CSI, k8s 1.22+ הגנה מפני חיבור רב-פודי מקרי

שגיאה storageClassName — אתה מנסה לחבר נפח RWO לפוד כאשר הוא כבר מחובר לצומת אחר. זה קורה עם Deployments שיש להם replicas > 1 על נפח RWO — או השתמש באחסון RWX או ב-StatefulSet עם PVC נפרד לכל פוד. לפי סקרי CNCF, 80% מבעיות האחסון ב-Kubernetes קשורות לבחירה שגויה של מצב גישה. שימוש במצב גישה נכון יכול להפחית את תדירות התקלות ב-75%.

כיצד לבחור ReclaimPolicy לייצור?

persistentVolumeReclaimPolicy — פרמטר קריטי ביותר. השוואת מדיניויות:

מדיניות גורל ה-PV גורל האחסון הבסיסי מתי להשתמש
Retain נשאר (Released) נשמר ייצור, נתונים קריטיים
Delete נמחק נמחק פיתוח/בדיקות, נפחים דינמיים
Recycle הוצא משימוש הוצא משימוש אין להשתמש

למסדי נתונים בייצור, השתמש תמיד ב-Retain. אובדן PVC עקב provisioner מקרי עם מדיניות Delete הוא תרחיש אמיתי. עם Retain, הנתונים שורדים גם את זה. חיסכון בעלויות שחזור נתונים — עד 90% מהתקציב (בממוצע 10,000 דולר לתקרית שנמנעה).

מידע נוסף על ReclaimPolicy מדיניות Retain משאירה את ה-PV במצב Released לאחר מחיקת ה-PVC — הנתונים לא נמחקים. כדי לעשות שימוש חוזר ב-PV, עליך לנקות ידנית את `claimRef` ולשנות את storageClassName. מדיניות Delete מתאימה לנתונים זמניים אך מסוכנת בייצור.

למה StatefulSet עדיף על Deployment למסדי נתונים?

ליישומים עם מצב (PostgreSQL, Redis, Kafka), השתמש ב-StatefulSet עם volumeClaimTemplates — כל פוד מקבל PVC משלו אוטומטית:

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
spec:
  serviceName: postgres
  replicas: 3
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:16.2
          env:
            - name: PGDATA
              value: /var/lib/postgresql/data/pgdata
          volumeMounts:
            - name: postgres-data
              mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
    - metadata:
        name: postgres-data
      spec:
        accessModes: ["ReadWriteOnce"]
        storageClassName: fast-ssd
        resources:
          requests:
            storage: 100Gi

עם replicas: 3, PVCים נוצרים אוטומטית: postgres-data-postgres-0, postgres-data-postgres-1, postgres-data-postgres-2. בעת מחיקת ה-StatefulSet, ה-PVCים לא מוסרים — הגנת נתונים בעיצוב. מחיקת PVCים ידנית היא פעולה מכוונת.

הרחבת PVC ללא השבתה

אם ה-StorageClass תומך ב-allowVolumeExpansion: true, ניתן להרחיב PVC תוך כדי פעולה:

kubectl patch pvc postgres-data-postgres-0 \
  -p '{"spec":{"resources":{"requests":{"storage":"200Gi"}}}}'

Kubernetes שולח בקשה לדרייבר ה-CSI לשנות את גודל הנפח הבסיסי. עבור מערכות קבצים ext4/xfs, שינוי הגודל מתבצע אוטומטית. אם הפוד צריך הפעלה מחדש כדי להחיל את השינוי, סטטוס ה-PVC יהיה FileSystemResizePending עד שהפוד יופעל מחדש. הקטנת PVC אינה נתמכת — רק הרחבה.

מה כלול בהגדרת PV/PVC במפתח-ביד

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

  • ביקורת של אסטרטגיית האחסון הנוכחית וזיהוי צווארי בקבוק.
  • עיצוב תצורת StorageClass אופטימלית, מצבי גישה, ReclaimPolicy.
  • הגדרת StatefulSet עם volumeClaimTemplates ליישומים עם מצב.
  • יישום אספקה דינמית עם דרייברי CSI.
  • תיעוד התצורה ו-runbook לצוות שלך.
  • הכשרת מהנדסים בפעולות PV/PVC.

לוחות זמנים: הגדרת יישום אחד עם מצב — 0.5-1 יום. פיתוח אסטרטגיית אחסון מלאה לקלאסטר עם גיבויים — 2-5 ימים. העלות נקבעת לאחר ביקורת תשתית.

בעיות נפוצות ופתרונות

מלכודות נפוצות כוללות שימוש ב-hostPath בייצור (הנתונים קשורים לצומת ואובדים בעת כשל צומת), storageClassName שגוי (ה-PVC לא יכול למצוא PV), שכחת מדיניות Retain (אובדן נתונים בעת מחיקת PVC מקרית ב-60% מהמקרים), ושימוש ב-Deployment עם replicas > 1 על נפח RWO (שגיאת multi-attach). השתמש תמיד באחסון מרוחק, ודא ש-storageClassName תואם, הגדר Retain לנתוני ייצור, ועבור ל-StatefulSet לעומסי עבודה עם מצב. תצורה נכונה מפחיתה תקלות הקשורות לאחסון ב-90%.

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

משאבים נוספים: מפרט CSI ב-GitHub.