وحدات التخزين والبيانات الدائمة
وحدات التخزين والبيانات الدائمة
طبقة الكتابة في الحاوية مؤقتة بطبيعتها. في اللحظة التي تُنفّذ فيها docker rm، يختفي كل بايت كُتب داخل تلك الطبقة نهائياً. بالنسبة لخوادم الويب عديمة الحالة، هذا ميزة — حاويات متطابقة بلا انجراف في الحالة. أما لأي شيء يُنتج بيانات دائمة — قواعد بيانات، ملفات مرفوعة، نقاط حفظ نماذج التعلم الآلي، سجلات التدقيق — فهو فخٌّ إنتاجي خطير. هذا الدرس يرسم الخط الفاصل بين وصلات الربط والأحجام المُسمّاة في Docker، ويشرح دورة حياة البيانات خلف كل منهما، ويستعرض الأنماط التي تستخدمها شركات من أمثال Google وNetflix للحفاظ على استقرار الحاويات ذات الحالة على نطاق واسع.
مشكلة طبقة الكتابة
تتألف صور Docker من طبقات للقراءة فقط مُكدَّسة عبر نظام ملفات موحّد (overlay2 على Linux الحديثة). عند بدء تشغيل حاوية، يُضيف Docker طبقة كتابة رفيعة واحدة في الأعلى. تذهب الكتابات إليها وحدها. يترتب على ذلك ثلاث نتائج:
- فقدان البيانات عند الحذف. يحذف
docker rmطبقة الكتابة بلا شرط. - لا مشاركة. حاويتان من الصورة ذاتها لكل منهما طبقة كتابة معزولة خاصة — لا يمكنهما رؤية كتابات بعضهما.
- تأخر في الإدخال/الإخراج. آلية النسخ عند الكتابة في نظام الملفات الموحّد أبطأ من القرص الأصلي؛ تعاني عمليات الإدخال/الإخراج العشوائية المكثّفة كقواعد البيانات بشكل ملحوظ.
الحل هو تركيب تخزين من خارج الحاوية إلى مسار داخلها. يوفر Docker آليتين رئيسيتين: وصلات الربط (bind mounts) والأحجام المُسمّاة (named volumes). آلية ثالثة هي وصلات tmpfs التي تحتفظ بالبيانات في ذاكرة الوصول العشوائي وتُغطّى في نهاية الدرس.
الأحجام المُسمّاة — الخيار الافتراضي في الإنتاج
الحجم المُسمّى هو جزء من تخزين المضيف يُنشئه Docker ويديره بنفسه، عادةً تحت /var/lib/docker/volumes/<name>/_data على Linux. تُشير إليه بالاسم لا بالمسار، ويتولى Docker إنشاءه وملكيته ودورة حياته بشكل مستقل عن أي حاوية بعينها.
docker stop وdocker rm وحتى ترقيات الصورة. إنها الخيار الصحيح الافتراضي لأي قاعدة بيانات، أو مخزن مؤقت، أو مجلد رفع ملفات في الإنتاج.
تُوسّع برامج تشغيل الأحجام (Volume Drivers) هذا النموذج. يكتب المُشغّل الافتراضي local على قرص المضيف. في بيئات السحابة يمكن استبداله بمُشغّل يُركّب NFS أو AWS EFS أو Azure Files، مما يمنح الحاويات واجهة الحجم المُسمّى ذاتها فيما يكون الخلفية تخزيناً شبكياً مشتركاً:
وصلات الربط — للتطوير وحقن الإعدادات
تربط وصلة الربط مساراً مطلقاً على المضيف مباشرةً داخل الحاوية. لا يتولى Docker أي إدارة — يجب أن يوجد المجلد مسبقاً، وتحصل الحاوية على وصول كامل للقراءة والكتابة لما فيه.
حالات الاستخدام الإنتاجية المقبولة لوصلات الربط هي: حقن شهادات TLS من مدير الأسرار الذي يكتب في مسار مضيف، وتركيب /var/run/docker.sock داخل حاويات عوامل CI (بحذر شديد)، ومشاركة نتائج البناء بين حاويات في خط أنابيب متعدد المراحل يعمل على المضيف ذاته.
دورة حياة البيانات: الحجم مقابل الحاوية
فهم ما الذي يتحكم في دورة حياة البيانات هو النموذج الذهني الأساسي. دورة حياة الحجم المُسمّى مفصولة تماماً عن أي حاوية:
- حذف الحاوية ← يبقى الحجم.
- ترقية الحاوية (صورة جديدة) ← تركيب الحجم ذاته ← تنتقل البيانات تلقائياً.
- يمكن لحاويتين تركيب الحجم ذاته في آنٍ واحد — مفيد للنسخ المتماثلة للقراءة أو ملحقات شحن السجلات، لكنه خطير إن كتبتا الملفات ذاتها.
- حذف الحجم صراحةً بـ
docker volume rm← البيانات تختفي نهائياً.
docker volume prune بشكل دوري على خوادم البناء لاستعادة مساحة القرص من الأحجام غير المرتبطة بأي حاوية. على خوادم الإنتاج، لا تُنظّف أبداً بدون نسخة احتياطية مؤكدة — الأحجام المجهولة من الحاويات القديمة تُحذف أيضاً.
الأحجام المجهولة ونمط --volumes-from
عند تصريح Dockerfile بتعليمة VOLUME أو استخدام -v /some/path بدون اسم، يُنشئ Docker حجماً مجهولاً — حجم مُسمّى بـ UUID كاسم له. يعمل مثل الحجم المُسمّى تماماً لكنه أصعب في الإدارة لأن الاسم غير واضح. تجنّب الأحجام المجهولة في أي شيء تُدير عليه عمليات؛ أعطِ الأحجام دائماً أسماء صريحة.
تُركّب العلامة القديمة --volumes-from كل أحجام حاوية واحدة في أخرى. كانت شائعة في نمط حاوية البيانات (قبل عصر Compose) وتظهر أحياناً في ملحقات النسخ الاحتياطي:
وصلات tmpfs — تخزين مؤقت في الذاكرة
وصلة tmpfs موجودة فقط في ذاكرة وصول عشوائي نواة المضيف ولا تُكتب أبداً على القرص. تختفي عند إيقاف الحاوية. استخدمها للبيانات الحساسة المؤقتة (رموز الجلسات، الأسرار المفككة تشفيرها) التي يجب ألا تظهر في السجلات أو على القرص:
أنماط الإنتاج على نطاق واسع
في مجموعة Kubernetes أو Docker Swarm، لا تعمل الأحجام المُسمّاة المدعومة بالمُشغّل المحلي في حالات النشر متعدد العقد — لكل عقدة قرصها الخاص ولا توجد مزامنة. الحلول المستخدمة عملياً:
- تخزين الكتل السحابي (AWS EBS، GCP PD). وصل وحيد؛ يتبع الحجم الـ pod/الحاوية إلى أي عقدة جُدولت عليها عبر مُشغّل CSI (Kubernetes) أو مكوّن الحجم (Swarm). أدنى زمن استجابة؛ الأفضل لقواعد البيانات.
- أنظمة الملفات الشبكية المشتركة (EFS، Azure Files، NFS). وصل متعدد؛ أي عقدة يمكنها تركيب نظام الملفات ذاته في وقتٍ واحد. مناسب للأصول المشتركة كالملفات المرفوعة أو أوزان نماذج التعلم الآلي.
- تخزين الكائنات (S3، GCS) عبر وصلات FUSE أو SDK. الأفضل للبيانات الضخمة نادرة الوصول. ليس جهاز كتلة — الخيار الخاطئ لقاعدة بيانات ذات معاملات.