يوفر Dragonfly نموذج نشر خفيفاً لتوزيع الملفات وصور الحاويات عبر تقنية الند للند (P2P)، من دون الحاجة إلى مكونات Manager وMySQL وRedis الموجودة عادةً في التثبيت التقليدي. ويستبدل هذا النموذج طبقة التحكم المركزية بـ Scheduler واحد للتنسيق، إلى جانب ConfigMap وخدمة Kubernetes من نوع Headless لاكتشاف العُقد.
يناسب هذا الأسلوب العناقيد الفردية التي تركز على تخفيف ضغط السجل أثناء سحب صور الحاويات، إضافة إلى مواقع الحافة وخطوط CI/CD التي تحتاج إلى توزيع P2P ومهام التسخين المسبق. أما البيئات التي تدير Dragonfly عبر عناقيد متعددة وتحتاج إلى واجهة ويب أو تكاملات OpenAPI، فتبقى بنية Manager الكاملة أكثر ملاءمة.
ما الذي يتغير في النموذج الخفيف؟
يعمل Manager في النشر التقليدي بوصفه مستوى التحكم في Dragonfly؛ فهو يستضيف وحدة التحكم على الويب، ويوفر واجهات OpenAPI للتكاملات مثل التسخين المسبق الذي تطلقه السجلات، ويدير العلاقات بين عناقيد P2P المتعددة، كما يوزع الإعدادات الديناميكية على Schedulers وClients. ويعتمد في حفظ الحالة على MySQL، بينما يستخدم Redis للتخزين المؤقت وتوزيع المهام غير المتزامنة.
لكن العنقود الواحد الذي يركز على توزيع المحتوى يحتاج غالباً إلى جزء محدود من هذه الوظائف، وتحديداً إعدادات الجدولة وقوائم الحظر وعناوين نقاط الوصول اللازمة لاكتشاف Schedulers. وعند عدم ضبط manager.addr، يستطيع Scheduler وClient العمل بصورة مستقلة من دون قاعدة بيانات، وقراءة الإعدادات من الملف المحلي /etc/dragonfly/dynconfig.yaml الذي يثبته مخطط Helm عبر ConfigMap. وإذا لم يوجد الملف، تُنشأ قيم افتراضية عند بدء التشغيل.
يعاد تحميل الإعدادات دورياً وفق قيمة refreshInterval، التي يكون افتراضها دقيقة واحدة. وبذلك تصل تحديثات ConfigMap إلى Pods العاملة من دون إعادة تشغيلها. كما تظهر الإعدادات ضمن قيم Helm، ومنها scheduler.dynconfig وseedClient.dynconfig وclient.dynconfig، بما يحافظ على أسلوب إعداد تصريحي ملائم لممارسات GitOps.
اكتشاف Schedulers وإدارة البصمة التشغيلية
بدلاً من سؤال Manager عن عناوين Schedulers، يشير ملف إعداد Client إلى خدمة Headless مثل dragonfly-scheduler.dragonfly-system.svc.cluster.local:8002. ويحلل dfdaemon اسم المضيف عبر DNS لاكتشاف عناوين Pods، ثم يفحص صحة كل نقطة وصول ويستبعد النسخ غير السليمة. وعند زيادة عدد نسخ StatefulSet الخاصة بـScheduler أو خفضه، يكتشف Clients نقاط النهاية الجديدة تلقائياً عبر DNS.
إذا كانت Schedulers تعمل بعناوين IP ثابتة، بما في ذلك العناوين الموجودة خارج عنقود Kubernetes، يمكن استخدام scheduler.addrs لتعريف قائمة صريحة. وتكون هذه القائمة، عندما لا تكون فارغة، ذات أولوية على العنوان المعتمد على DNS.
يتكون النشر الخفيف من ثلاثة أعباء أساسية:
- Scheduler: يعمل كـ StatefulSet لتنسيق الجدولة وتوزيع أجزاء المحتوى بين الأقران.
- Seed Client: يعمل كجذر لشبكة P2P وينزل المحتوى مباشرة من المستودع الأصلي.
- Client: يعمل كـ DaemonSet على كل عقدة، حيث يضبط dfinit نظام containerd لتوجيه عمليات سحب الصور عبر Client المحلي.
لا يحتاج هذا النموذج إلى نسخ احتياطية لقواعد البيانات أو نصوص ترحيل أثناء الترقية؛ إذ تُحفظ الحالة في مخازن مؤقتة على الأقراص المحلية، ويمكن إعادة بنائها عند الطلب من المصدر الأصلي.
التثبيت على عنقود kind
يقترح المصدر اختبار النموذج على عنقود kind متعدد العقد. تبدأ العملية بإنشاء عقدة control-plane وعقدة worker باستخدام ملف إعداد kind-config.yaml، ثم تنفيذ الأمر kind create cluster --config kind-config.yaml.
بعد ذلك تُسحب صور dragonflyoss/scheduler:latest وdragonflyoss/client:latest وdragonflyoss/dfinit:latest، وتُحمّل إلى عقد kind عبر kind load docker-image. وفي ملف قيم Helm، تُفعّل المقاييس، ويُحدد مستودع Scheduler، ويُضبط dfinit لاستخدام ملف إعداد containerd الموجود في /etc/containerd/config.toml مع تفعيل proxyAllRegistries.
يُثبت المخطط بالأمر helm install --wait --create-namespace --namespace dragonfly-system dragonfly dragonfly/dragonfly -f charts-config.yaml. وفي المثال الوارد، يفترض أن تبدأ أربعة Pods بنجاح: Client لكل عقدة worker، وScheduler واحد، وSeed Client واحد. ويمكن التحقق من ذلك باستخدام kubectl get po -n dragonfly-system.
لاختبار التوجيه عبر P2P، تُسحب صورة alpine:3.19 داخل عقدة worker باستخدام crictl، ثم تُراجع سجلات Client المحلي للعثور على معرّف المهمة والتأكد من ظهور رسالة نجاح تنزيلها.
التسخين المسبق وحقن أدوات Dragonfly
يعمل التسخين المسبق للصور والملفات من دون Manager. إذ يتصل dfctl مباشرةً بنقطة gRPC الخاصة بـScheduler لإطلاق تنزيلات على Seed Clients أو Clients العقد. ويدعم الأمر صور OCI مع مصادقة السجل، إضافة إلى تنزيلات HTTP وHTTPS، بينما يحدد الخيار --scope ما إذا كانت المهمة تستهدف Seed Client واحداً أو جميع Seed Clients أو كل Clients في العنقود.
وللتعامل مع الأصول الثانوية التي قد تنزلها التطبيقات، مثل نماذج التعلم الآلي وملفات البيانات ومخرجات البناء، يوفر Dragonfly أداة dragonfly-injector، وهي Webhook لتعديل Pods. تضيف الأداة أدوات Dragonfly، ومنها dfget وdfcache وdfstore وdfdaemon، كما تثبت مقبس Unix المحلي الخاص بـdfdaemon داخل Pod من دون تعديل الصور الأساسية للتطبيق. ويستخدم Injector أداة cert-manager لإصدار شهادات TLS لخادم Webhook، ثم يُفعّل عبر وسم Pod بالتعليق dragonfly.io/inject: 'true'.
متى تكون بنية Manager أفضل؟
تظل بنية Manager الخيار الأنسب عند تشغيل Dragonfly كخدمة منصة مركزية عبر عناقيد متعددة، أو عند الحاجة إلى واجهة ويب، أو إلى التسخين المسبق الآلي عبر تكاملات OpenAPI. ويمكن تفعيلها في إعدادات Helm عبر ضبط manager.enable وmysql.enable وredis.enable على true.
وبذلك يمكن للفرق البدء بالنشر الخفيف، ثم إضافة Manager والمكونات المرتبطة به عندما تتوسع المتطلبات التشغيلية من توزيع P2P داخل عنقود واحد إلى إدارة منصة متعددة العناقيد.