הגדרת נפחים מתמשכים (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 תקוע
- הרץ
Pendingואתר את ה-PVC הבעייתי. - הרץ
kubectl describe pvc postgres-data-pvc. בדוק את סעיף האירועים (Events) לסיבה המדויקת. - אם הסיבה היא StorageClass חסר, צור אותו או תקן את
kubectl get pvc -n <namespace>ב-PVC. - אם ה-PV קשור, מחק PVCים מיותרים או התאם את accessModes.
- לאספקה דינמית, ודא של-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.







