قواعد البيانات على Kubernetes
قواعد البيانات على Kubernetes
تشغيل قواعد البيانات على Kubernetes من أكثر المواضيع جدلًا في هندسة المنصات. لسنوات كان الرأي السائد: "الأعباء عديمة الحالة فقط — احتفظ بقواعد بياناتك خارج الكتلة." كان هذا المنطق مقبولًا عام 2016 حين كانت بدائيات التخزين في Kubernetes غير ناضجة. في عام 2025، مع وجود عوامل ناضجة ومشغّلات CSI وتجارب إنتاجية موثّقة في شركات كـ Zalando وCloudflare وGitLab، تغيّرت المعادلة. لكن "يمكنك" لا تعني "يجب عليك"، والظروف التي يصحّ فيها كل جواب تختلف اختلافًا جوهريًّا.
لماذا تشغيل قواعد البيانات في Kubernetes أمر صعب
صُمّم Kubernetes حول مبدأ "الماشية" — حاويات عديمة الحالة يمكن قتلها وإعادة جدولتها وتوسيعها أفقيًّا كيفما شئت. قواعد البيانات "حيوانات أليفة": لها هوية وحالة قرصية وتوبولوجيا نسخ متماثل وعضوية في الكتلة يجب أن تنجو من عمليات إعادة التشغيل وأعطال العقد دون فقدان بيانات. عدة بدائيات تردم هذه الفجوة:
- StatefulSet — يُعيّن هويات منتظمة وثابتة للحاويات (
pg-0،pg-1،pg-2) تبقى حتى بعد إعادة تشغيل الحاوية. تحصل كل حاوية على PersistentVolumeClaim خاص بها. - PersistentVolumeClaim (PVC) — التخزين الدائم للحاوية، مدعوم بمشغّل CSI (EBS أو GCE PD أو Ceph أو Longhorn وغيرها). يبقى الـ PVC بعد زوال الحاوية.
- Headless Service — خدمة بـ
clusterIP: Noneتكشف اسم DNS لكل حاوية مباشرةً (pg-0.postgres-headless.default.svc.cluster.local)، مما يتيح للمشغّل توجيه الكتابات إلى الأساسية والقراءات إلى النسخ. - PodDisruptionBudget (PDB) — يمنع Kubernetes من إخلاء عدد كبير من حاويات قواعد البيانات في آنٍ واحد أثناء صيانة العقد.
حتى مع هذه البدائيات، لن تكتب مشغّل قاعدة بيانات جاهزًا للإنتاج من الصفر. منطق التنسيق — انتخاب القائد، وترقية النسخة، والتبديل دون فقدان بيانات، وإعادة تحميل الإعدادات عند تغيير المواصفات — معقّد بما يكفي لجعل المجتمع يتقارب حول المشغّلات (operators) كآلية تسليم قياسية.
المشغّلات: التجريد الصحيح
يُشفّر مشغّل Kubernetes كتاب تشغيل المشغّل البشري في صورة حلقة تحكم. يراقب موارد مخصصة (CRs) تُعرّفها — كائن Cluster لـ PostgreSQL مثلًا — ويُوفّق حالة الكتلة الفعلية نحو الحالة المطلوبة. المشغّلات الجيدة تتولى:
- الإقلاع: تهيئة الأساسية، وبثّ النسخ منها، وتسجيلها في التوبولوجيا
- الفشل التلقائي: رصد فشل الأساسية، وانتخاب قائد جديد، وتحديث نقاط نهاية الخدمة المخفية، كل ذلك دون فقدان بيانات
- التبديل: تسليم الأساسية بأمان وبدون توقف للصيانة
- النسخ الاحتياطي: نسخ قاعدية مجدوَلة إلى مخزن الكائنات (S3، GCS) وأرشفة WAL المستمرة
- إدارة الإعدادات: ترجمة تغيير في المواصفة إلى إعادة تحميل أو تشغيل منسّقة ومتدرجة
- ترقيات الإصدار الثانوية والرئيسية: ترقيات منسّقة على مستوى الكتلة بأكملها مع دعم التراجع
CloudNativePG — المعيار الذهبي لمشغّل PostgreSQL
CloudNativePG (CNPG) مشروع حضانة CNCF وأنضج مشغّل PostgreSQL إنتاجيًّا متاح. يشغّل PostgreSQL مباشرةً في الحاويات (بدون sidecar)، ويستخدم نسخ التدفق الأصلية لـ PostgreSQL، ويدمج أرشفة WAL مع مخزن الكائنات جاهزًا للاستخدام. إليك مانيفست كتلة بسيط لكن متوافق مع متطلبات الإنتاج:
طبّق الملف وسيُقلّع CNPG الكتلة، ويُهيّئ نسخ التدفق، ويبدأ أرشفة WAL، وينشئ PodMonitor لكي تستخلص Prometheus مقاييس postgres_exporter المدمجة تلقائيًّا. تحقق من حالة الكتلة بـ:
التخزين: القرار الفاصل
المشغّل بلا قيمة إذا كانت طبقة التخزين تحته غير موثوقة. اختيار التخزين له أثر أكبر على أداء قاعدة البيانات وسلامة البيانات من أي قرار آخر في Kubernetes.
مبادئ التخزين الرئيسية لقواعد البيانات الإنتاجية على Kubernetes:
- استخدم التخزين الكتلي، لا أنظمة الملفات المشتركة. NFS ومعظم تكوينات CephFS غير آمنة لأدلة بيانات PostgreSQL أو MySQL لأنها لا توفّر ضمانات
fsyncالتي تعتمد عليها قواعد البيانات. استخدم وحدات التخزين الكتلية (EBS أو GCE PD أو Ceph RBD في وضع الكتلة). - فعّل تشفير الوحدات على مستوى StorageClass، لا على مستوى التطبيق. تضمن الإضافة التوضيحية
encrypted: "true"أو مرجع مفتاح KMS في StorageClass تشفير كل PVC تلقائيًّا. - اطلب ضمان QoS للتخزين. على العقد التي تضمّ أعباء متعددة، يُعدّ ضجيج جهة I/O القرص من المصادر الرئيسية لارتفاع زمن الاستجابة. استخدم
topologySpreadConstraintsأو مجموعات عقد مخصصة (عبر node selectors و taints) لعزل حاويات قواعد البيانات. - لا تستخدم
emptyDirلبيانات قاعدة البيانات أبدًا.emptyDirزائل — يُدمَّر حين تُخلَى الحاوية. هذا أكثر الأخطاء شيوعًا التي تؤدي إلى فقدان البيانات عند تشغيل قواعد البيانات في Kubernetes لأول مرة. - اضبط StorageClass بـ
reclaimPolicy: Retainلجميع PVCs الخاصة بقواعد البيانات. سياسةDeleteالافتراضية ستُدمّر وحدة تخزين البيانات بشكل دائم فور حذف أي PVC — سواء بقصد أم بخطأ بشري.
kubectl delete pvc pg-prod-1 على StorageClass بـ reclaimPolicy: Delete، فإن وحدة تخزين EBS الأساسية ستُدمَّر بشكل دائم في غضون ثوانٍ. استخدم دائمًا reclaimPolicy: Retain لوحدات التخزين الخاصة بقواعد البيانات. بعد التفكيك المقصود، احذف الـ PV ووحدة التخزين الأساسية يدويًّا فقط بعد التأكد من أن البيانات لم تعد مطلوبة أو أن نسخة احتياطية مُتحقَّقة منها موجودة.
متى لا تُشغّل قواعد البيانات على Kubernetes
حتى مع المشغّلات الناضجة، هناك حالات تُضيف فيها قاعدة البيانات داخل Kubernetes تعقيدًا دون فائدة متناسبة:
- أنت تستخدم خدمة مُدارة ولا تعاني من مشكلة تشغيلية. RDS وCloud SQL وAurora تحلّ مشاكل حقيقية بتكلفة معقولة. الانتقال إلى كتلة CNPG لاكتساب تحكم لا تحتاجه هو تعقيد خالص.
- فريقك لا يمتلك خبرة Kubernetes. تشغيل كتلة CNPG يتطلب فهم StatefulSets وPVCs وStorageClasses وسياسات الشبكة وCRDs الخاصة بالمشغّل. لا يجب أن تتخذ Kubernetes منصةً لقواعد البيانات كأول خطوة إذا لم يكن فريقك ملمًّا بها.
- طبقة التخزين لديك غير جاهزة للإنتاج. إذا كانت الكتلة تستخدم أقراصًا محلية زائلة، أو تثبيت Longhorn سيء الضبط، أو NFS، فإن تشغيل قاعدة بيانات إنتاجية عليها سينتهي بكارثة. أصلح البنية التحتية قبل تشغيل الأعباء ذات الحالة.
- متطلبات الامتثال أو إقامة البيانات تفرض العزل. بعض الأطر التنظيمية تشترط تشغيل قواعد البيانات على أجهزة مخصصة لمستأجر واحد. كتلة Kubernetes مشتركة تنتهك هذه الاشتراطات بغض النظر عن نضج المشغّل.
- أعباء I/O مرتفعة للغاية. لن تبلغ كتلة تعمل على تخزين شبكي للأغراض العامة مستوى الإنتاجية التي يوفرها مضيف NVMe مادي. لـ OLTP مكثوف الكتابة على نطاق واسع، لا يزال المضيف المخصص أو خادم قواعد البيانات المادي هو الإجابة الصحيحة.
ممارسات تشغيلية رئيسية
إذا قرّرت تشغيل قواعد البيانات على Kubernetes، فهذه الممارسات هي ما يُميّز النشر الإنتاجي عن التجريب:
- هيّئ PDB دائمًا. بدون PodDisruptionBudget، يمكن لـ
kubectl drainأثناء صيانة العقد إخلاء الأساسية وإحدى النسخ في آنٍ واحد، مما يتسبب في توقف مؤقت أو سلسلة من عمليات الفشل التلقائي. - استخدم قواعد anti-affinity لتوزيع حاويات قواعد البيانات عبر العقد المادية ومناطق التوافر. الأساسية وكلا النسختين على نفس العقدة يعني أن فشل عقدة واحدة يُسقط الكتلة بأكملها.
- اختبر الفشل التلقائي بانتظام باستخدام أمر الترقية الخاص بالمشغّل. اعرف RTO من فشل الأساسية قبل أن تواجهه في الإنتاج.
- تحقق من أرشفة WAL والاسترداد. تشغيل
kubectl cnpg backup pg-prodلا يكفي — استرجع تلك النسخة الاحتياطية بانتظام في namespace منفصل أو كتلة تجريبية للتأكد من صحتها. - افصل namespace قواعد البيانات باستخدام NetworkPolicies تسمح فقط لـ namespaces التطبيقات بالوصول إلى منافذ قواعد البيانات. يجب ألّا تكون قواعد البيانات متاحة من الإنترنت المفتوح أو من أعباء غير ذات صلة في الكتلة ذاتها.