به گزارش از وبسایت cncf

Dragonfly که توسط پروژه‌های Dragonfly Maintainer در CNCF برجسته شده است، با استفاده از معماری P2P توزیع فایل‌ها و تصاویر کانتینری را تسریع می‌کند. نصب پیش‌فرض این سیستم شامل چندین مؤلفه و وابستگی است؛ علاوه بر Scheduler، Seed Client و Client که وظیفه جابجایی داده‌ها را بر عهده دارند، معمولاً یک Manager برای پیکربندی پویا وجود دارد که از MySQL و Redis استفاده می‌کند. در حالی که این ساختار برای تیم‌هایی که Dragonfly را در ناوگان‌های چندخوشه‌ای بزرگ اجرا می‌کنند مناسب است، برای یک خوشه منفرد که تمرکزش بر حل مشکل بار زیاد رجیستری هنگام کشیدن تصویر است، ممکن است سنگین باشد. 🚀

برای چنین سناریوهایی، Dragonfly از یک مدل استقرار سبک پشتیبانی می‌کند که Manager، MySQL و Redis را حذف می‌کند. در این مدل، Scheduler به‌عنوان تنها مؤلفه هماهنگ‌کننده عمل می‌کند و با یک فرمان Helm کل مجموعه را می‌توان نصب کرد. در ادامه عملکرد معماری سبک‌وزن و نحوه راه‌اندازی آن در یک کلاستر محلی توضیح داده شده است.

نقش Manager در استقرار ناوگانی چیست؟ Manager به‌عنوان control plane عمل می‌کند: کنسول وب را میزبانی می‌کند، APIهای باز برای یکپارچگی‌ها (مثل preheat توسط registry) عرضه می‌کند، روابط چندخوشه‌ای P2P را مدیریت می‌نماید و پیکربندی‌های پویا را بین Schedulers و Clients توزیع می‌کند. داده‌های پیکربندی دینامیک معمولاً در MySQL نگهداری شده و Redis برای صف‌ها و پردازش ناهمزمان استفاده می‌شود که برای مقیاس ناوگان ضروری است.

اما برای یک خوشه منفرد و متمرکز بر توزیع P2P، نیاز اصلی پیکربندی پویاست. در عمل، پیکربندی پویا برای یک خوشه از یک فایل YAML محلی تشکیل می‌شود که محدودیت‌های زمان‌بندی، لیست‌های بلوک و endpointهای مربوطه را برای Clients تعریف می‌کند. جدا شدن Scheduler و Client از Manager به آن‌ها اجازه می‌دهد بدون وابستگی به یک پایگاه داده یا Manager آدرس‌دهی شده، به‌طور مستقل اجرا شوند.

چگونه مدل سبک‌وزن کار می‌کند؟ در استقرار سبک‌وزن، صفحه کنترل Manager با دو منبع ساده Kubernetes جایگزین می‌شود: یک ConfigMap و یک Service از نوع Headless. پیکربندی پویا از طریق ConfigMap فراهم می‌شود؛ وقتی manager.addr تنظیم نشده باشد، Scheduler و Client پیکربندی‌ها را از یک فایل محلی /etc/dragonfly/dynconfig.yaml بارگذاری می‌کنند که نمودار Helm آن را با یک ConfigMap نصب می‌کند. اگر فایل موجود نباشد، مقادیر پیش‌فرض هنگام راه‌اندازی ساخته می‌شوند. ⚙️

نمونه Dynconfig.yaml که پارامترهای سطح خوشه را تعریف می‌کند:

seedPeerClusterConfig:
  loadLimit: 2000

schedulerClusterConfig:
  candidateParentLimit: 3
  filterParentLimit: 15

schedulerClusterClientConfig:
  loadLimit: 200

Scheduler و Client این پیکربندی را به‌صورت دوره‌ای (توسط refreshInterval که پیش‌فرض آن یک دقیقه است) بارگذاری مجدد می‌کنند. به‌روزرسانی‌های ConfigMap بدون نیاز به راه‌اندازی مجدد پادها و در بازه‌های به‌روزرسانی به پادهای در حال اجرا منتقل می‌شوند. این تنظیمات همچنین به‌عنوان مقادیر Helm (مثلاً scheduler.dynconfig، seedClient.dynconfig، client.dynconfig) قابل نمایش هستند تا سازوکار GitOps حفظ شود.

کشف Scheduler در مدل سبک‌وزن از طریق یک Service headless انجام می‌شود. در یک استقرار مبتنی بر Manager، Clients از Manager درخواست لیست Schedulerها می‌کنند؛ اما در استقرار سبک، Dynconfig.yaml Client مستقیماً به Service headless زمان‌بندی اشاره می‌کند:

scheduler:
  addr: dragonfly-scheduler.dragonfly-system.svc.cluster.local:8002

فرآیند Client (dfdaemon) نام میزبان را از DNS حل می‌کند تا تمام IPهای Podهای Scheduler را کشف کند، هر endpoint را بررسی کرده و نمونه‌های ناسالم را فیلتر می‌کند. در صورتی که Schedulerها به‌صورت StatefulSet بالا یا پایین بروند، Clients به‌طور خودکار endpoints به‌روز شده را از طریق DNS دریافت می‌کنند. در صورتی که Schedulerها در آدرس‌های IP ثابت (مثلاً خارج از خوشه) اجرا شوند، می‌توان آن‌ها را صریح با استفاده از scheduler.addrs تعریف کرد. یک لیست غیرخالی از addrs کشف DNS را لغو می‌کند:

scheduler:
  addrs:
    - 192.168.1.10:8002
    - 192.168.1.11:8002

ردپای درون‌خوشه‌ای معمولاً سه جزء را شامل می‌شود:

– Scheduler (StatefulSet): هماهنگی زمان‌بندی کار و توزیع قطعات در بین peers.
– Seed Client (StatefulSet): به‌عنوان peer ریشه عمل می‌کند و محتوا را مستقیماً از رجیستری اصلی دانلود می‌کند.
– Client (DaemonSet): روی هر نود اجرا می‌شود و dfinit کانتینر را برای مسیریابی تصویر از طریق peer محلی پیکربندی می‌کند.

این ردپا نیازی به پشتیبان‌گیری از پایگاه داده یا اسکریپت‌های مهاجرت هنگام ارتقا ندارد. حالت سیستم در cache دیسک محلی نگهداری می‌شود که در صورت نیاز قابل بازسازی از منبع مبدا است.

مقایسه مدل‌های استقرار: Dragonfly سه گزینه را بسته به نیاز عملیاتی ارائه می‌دهد. از آنجا که نمودار Helm پیش‌فرض Manager، MySQL و Redis را غیرفعال می‌کند، استقرار Lightweight به‌عنوان خط پایه عمل می‌کند:

– Lightweight Deployment: تنها Scheduler، Seed Client و Client را مستقر می‌کند؛ مناسب برای خوشه‌های منفرد، edge و خطوط CI/CD متمرکز بر P2P و preheat با dfctl.
– Lightweight + Redis: Redis را به معماری سبک اضافه می‌کند (scheduler.database.redis.addrs) تا وظایف مداوم و نگهداری متادیتا و cache ماندگار فعال شود.
– Deployment with Manager: Manager به‌همراه MySQL و Redis مستقر می‌شود و امکاناتی مثل کنسول وب، OpenAPI، مدیریت چندخوشه‌ای و preheat از طریق API را فراهم می‌کند.

یک جدول مقایسه ویژگی‌ها به‌طور خلاصه نشان می‌دهد که کدام قابلیت‌ها در هر نوع استقرار فعال هستند؛ اما در اینجا به‌صورت خلاصه گفته شد که قابلیت‌هایی مانند Blocklist و توزیع وظیفه در همه پیکربندی‌ها پشتیبانی می‌شوند، در حالی که persistent tasks و OpenAPI/Console فقط در حالت With Manager کامل هستند.

راهنمای گام‌به‌گام راه‌اندازی در یک خوشه محلی (نمونه): 🧭

1) ایجاد یک خوشه kind نقش: worker

kind create cluster --config kind-config.yaml

2) از پیش بارگذاری تصاویر مورد نیاز در نودها:

docker pull dragonflyoss/scheduler:latest
docker pull dragonflyoss/client:latest
docker pull dragonflyoss/dfinit:latest

3) پیکربندی مقادیر Helm — فایل charts-config.yaml (نمونه‌ی ساده‌ای که Manager، mysql و redis به‌صورت پیش‌فرض غیرفعال هستند):

scheduler:
  image:
    repository: dragonflyoss/scheduler
    tag: latest
  enabled: true

seedClient:
  image:
    repository: dragonflyoss/seed-client
    tag: latest
  enabled: true

client:
  image:
    repository: dragonflyoss/client
    tag: latest
  enabled: true

dfinit:
  enabled: true
  image:
    repository: dragonflyoss/dfinit
    tag: latest

config:
  containerRuntime:
    containerd:
      configPath: /etc/containerd/config.toml
  proxyAllRegistries: true

4) نصب Dragonfly با استفاده از Helm:

helm repo add dragonfly https://dragonflyoss.github.io/helm-charts/
helm repo update
helm install --wait --create-namespace --namespace dragonfly-system dragonfly dragonfly/dragonfly -f charts-config.yaml

5) بررسی شروع پادها (نمونه خروجی):

kubectl -n dragonfly-system get pods
# نمونه خروجی:
# dragonfly-client-xxxxx   1/1 Running   0  3m
# dragonfly-scheduler-0    1/1 Running   0  3m
# dragonfly-seed-client-xx 1/1 Running   0  3m

6) آزمون مسیر‌یابی با crictl / docker و گرفتن لاگ‌های Client جهت تأیید مسیریابی از طریق Dragonfly:

docker exec -i kind-worker /usr/local/bin/crictl pull alpine:3.19

export POD_NAME=$(kubectl -n dragonfly-system get pod -l "app=dragonfly,release=dragonfly,component=client" -o=jsonpath='{.items[?(@.spec.nodeName=="kind-worker")].metadata.name}' | head -n 1)

# بررسی لاگ‌ها برای task_id مربوط به alpine
kubectl -n dragonfly-system exec -it ${POD_NAME} -- sh -c "grep -hoP 'library/alpine.*task_id="K[^"]+' /var/log/dragonfly/dfdaemon/* | head -n 1"

# نمایش محتوای لاگ‌های dfdaemon
kubectl -n dragonfly-system exec -it ${POD_NAME} -- sh -c "tail -n 200 /var/log/dragonfly/dfdaemon/*"

این فرآیند نشان می‌دهد که عملکرد دانلود می‌تواند بدون وجود Manager کار کند. CLI ابزار dfctl مستقیماً با gRPC endpoint مربوط به Scheduler تعامل می‌کند تا دانلودها را در Seed Clients یا Node Clients آغاز کند، به‌عنوان مثال:

dfctl task preheat oci://docker.io/library/alpine:3.19 
  --scheduler-endpoint http://dragonfly-scheduler.dragonfly-system.svc.cluster.local:8002 
  --scope all_seed_peers

dfctl از هر دو شیوه OCI image (oci://) با احراز هویت رجیستری و دانلود استاندارد HTTP/HTTPS (https://) پشتیبانی می‌کند. پرچم –scope مشخص می‌کند پیش‌گرم‌سازی برای کدام دسته اعمال می‌شود (یک Seed Client، همه Seed Clients، یا همه Clients در خوشه).

تزریق آثار به Podهای اپلیکیشن: معمولاً برنامه‌ها علاوه بر تصویر کانتینر، دارایی‌های ثانویه‌ای مانند مدل‌های ML یا داده‌ها را دانلود می‌کنند. Dragonfly یک Injector ارائه می‌دهد که به‌عنوان یک admission webhook در Kubernetes عمل می‌کند و ابزارهای Dragonfly (dfget، dfcache، dfstore، dfdaemon) و mount سوکت یونیکس dfdaemon را در برنامه Pods تزریق می‌نماید تا دانلودهای P2P بدون نیاز به تغییر تصاویر پایه انجام شود. Injector با cert-manager گواهی‌های TLS برای وب‌‌هوک تولید می‌کند. 🔌

برای فعال‌سازی Injector مقادیر مربوطه را در فایل مقادیر Helm فعال کنید (نمونه):

injector:
  enable: true
  replicas: 2
  image:
    repository: dragonflyoss/injector
    tag: latest
  initContainerImage:
    repository: dragonflyoss/client
    tag: latest

جمع‌بندی: استقرار سبک‌وزن Dragonfly اجرای سریع و سربار کمتر برای خوشه‌های منفرد و سناریوهای edge یا CI/CD فراهم می‌آورد، در حالی که در صورت نیاز به ویژگی‌های پیشرفته‌تر (مانند کنسول وب، OpenAPI، مدیریت چندخوشه‌ای یا وظایف ماندگار) می‌توان Redis و Manager را به آرتیفکت نصب افزود.

موفق باشید! 😊