방구석 IT

[k8s] Dragonfly(D7y) - P2P 방식 대규모 컨테이너 이미지/파일 배포 가속 분산 전송 시스템 본문

Tech 학습 및 정리/CICD

[k8s] Dragonfly(D7y) - P2P 방식 대규모 컨테이너 이미지/파일 배포 가속 분산 전송 시스템

펭잉 2026. 6. 1. 09:25

공식 홈페이지

Dragonfly란

Dragonfly는 P2P(peer-to-peer) 기반 대규모 데이터 배포 및 가속 시스템

컨테이너 이미지, 파일, AI/ML 모델, 캐시, 로그, 의존성 등 클라우드 네이티브 환경에서 대규모 파일 전달을 효율적·안정적으로 처리할 수 있도록 설계됨

D7y는 Cloud Native Computing Foundation(CNCF)의 Graduated(정규) 프로젝트로 2025년 10월 승인 *주의! dragonfly와 dragonflydb는 다른 도구


핵심 기능

P2P 기반 분산 다운로드

  • 각 Peer가 다운로드/업로드를 동시에 수행하며, 유휴 대역폭을 활용해 전송 속도를 개선

비침투적(Non-intrusive) 통합

  • 다양한 컨테이너 런타임, 이미지 레지스트리, 다운로드 도구, AI 인프라와 무리 없이 통합

Load-Aware Scheduling

  • 중앙 스케줄러와 노드 수준’s 2단계 스케줄링을 통해 클러스터 로드에 맞춘 최적의 분산 다운로드 경로를 결정

데이터 일관성 보장

  • 다운로드된 파일이 사용자가 명시적으로 검증하지 않더라도 파일 일관성을 유지

예외 격리

  • 서비스, Peer, 태스크 수준에서 오류를 분리 처리해 안정성을 확보

생태계 통합

  • AI 모델/데이터셋, 컨테이너 이미지, 레지스트리 등 생태계 전반과 연계

아키텍처 구성

컴포넌트 역할
Manager 클러스터 전반의 동적 설정, 메타데이터 관리, 통계 수집 및 콘솔 UI 제공
Scheduler 다운로드 작업에 대해 최적 Peer/Seed Peer 선택 및 스케줄링 수행
Seed Peer P2P 계층의 루트 Peer 역할. 소스에서 직접 다운로드하고 다른 Peer에 전송
Peer 클라이언트 다운로드/업로드 역할 수행

동작 원리

첫 다운로드

  1. 클라이언트가 Peer로 파일 요청 (HTTP/HTTPS Proxy 또는 gRPC)
  2. Peer는 Scheduler에 태스크 등록
  3. Scheduler는 처음 요청인지 확인
    • 처음인 경우 Seed Peer에게 원본에서 다운로드하도록 지시
    • 파일을 작은 조각(piece)으로 분할
  4. Scheduler는 조각 다운로드를 Seed Peer → Peer 또는 Peer 간 P2P로 조정
  5. 각 조각이 성공적으로 다운로드되면 상태를 Scheduler로 리포트

후속 다운로드

  • 같은 파일을 요청할 때는 이미 조각을 보유한 Peer들끼리 서로 전송하여 빠르게 완성
  • 중앙 소스 다운로드 부담 감소 및 네트워크 효율 극대화

적용 사례 및 활용

Dragonfly는 대규모 데이터 배포 및 이미지 배포 가속을 위해 여러 환경에서 활용 예시) 이미지 캐시, 다중 리전/클러스터 컨테이너 배포, AI 모델/데이터세트 빠른 배포 등


참고 및 추가 링크


구축 과정

설치 전 확인 사항

조건

  • StorageClass가 반드시 필요함(Redis, Mysql 용)

  • PV의 스토리지 권한 때문에 Voluem Permissions 추가 설정 및 관련 bitnari 이미지 교체 필요 (values.yaml 수정)

  • “containerd registry mirror” 또는 “hosts.toml(certs.d) 기반 registry config_path”를 통해 dfdaemon을 mirror(프록시)로 둔다는 방식이기 때문에 노드별 /etc/containerd/config.toml에 아래 두 옵션 중 하나가 반드시 필요

    • [plugins."io.containerd.grpc.v1.cri".registry] config_path = "/etc/containerd/certs.d”

      → NKS에서 해당 부분 스크립트화 어려움


    • [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] endpoint = ["http://127.0.0.1:{로컬 Mirror 포트}"]

      → NKS에서 활용 가능


준비(NKS 기준)


  1. 인스턴스 생성 사용자 스크립트 적용 - config.toml 수정용 NKS는 registry-config.json으로 config.toml을 관리하기 때문에 Dragonfly의 proxy 포트를 바라보도록 수정해야함.
#!/bin/bash
set -euo pipefail

# Dragonfly dfdaemon proxy port (values.yaml 기준 4001)
DF_PROXY_PORT="4001"

# dfdaemon proxy가 HTTP면 http, HTTPS면 https 로 변경
DF_PROXY_SCHEME="http"

mkdir -p /etc/containerd

# docker.io 를 dfdaemon(로컬)로 우선 보내고, 실패 시 원본으로 fallback
if [ "$DF_PROXY_SCHEME" = "https" ]; then
  cat > /etc/containerd/registry-config.json <<EOF
[
  {
    "registry": "docker.io",
    "endpoint_list": [
      "https://127.0.0.1:${DF_PROXY_PORT}",
      "https://registry-1.docker.io"
    ],
    "tls": {
      "insecure_skip_verify": true
    }
  }
]
EOF
else
  cat > /etc/containerd/registry-config.json <<EOF
[
  {
    "registry": "docker.io",
    "endpoint_list": [
      "http://127.0.0.1:${DF_PROXY_PORT}",
      "https://registry-1.docker.io"
    ]
  }
]
EOF
fi

# (선택) 디버깅을 위해 적용 파일 출력
echo "[INFO] Wrote /etc/containerd/registry-config.json"
cat /etc/containerd/registry-config.json

  1. StorageClass 생성
# 테스트용 NKS 기준 block storage 애드온 추가 후
vi storageClass.yaml

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: cinder-sc
provisioner: cinder.csi.openstack.org
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
---

kubectl apply -f storageClass.yaml

  1. dragonfly helm chart values.yaml 수정
# volume 설정을 위한 values.yaml 다운 후 수정
helm show values dragonfly/dragonfly > values.yaml
vi values.yaml
  • mysql 구간 (약 1810 줄 구간, volumePermissions 및 primary.persistence + fsGroup 설정 추가)
...
mysql:
  # -- Enable mysql with docker container.
  enable: true
  # -- Enable mysql volume permissions (fix PV permission for non-root container)
  volumePermissions:
    enabled: true
    image:
      repository: debian
      tag: "12-slim"
    containerSecurityContext:
      runAsUser: 0
...
  primary:
    service:
      # -- Mysql port.
      port: 3306
    persistence:
      enabled: true
      storageClass: cinder-sc
      accessModes:
        - ReadWriteOnce
    podSecurityContext:
      enabled: true
      fsGroup: 1001
      fsGroupChangePolicy: OnRootMismatch
    containerSecurityContext:
      enabled: true
      runAsUser: 1001
      runAsGroup: 1001
      runAsNonRoot: true
...
  • redis 구간 (약 1850 줄 구간, volumePermissions 및 master.persistence + fsGroup 설정 추가)
...
redis:
  # -- Enable redis cluster with docker container.
  enable: true
  # -- Enable redis volume permissions (fix PV permission for non-root container)
  volumePermissions:
    enabled: true
    image:
      repository: debian
      tag: "12-slim"
    containerSecurityContext:
      runAsUser: 0
...
  master:
    service:
      ports:
        # -- Redis master service port.
        redis: 6379
    persistence:
      enabled: true
      storageClass: cinder-sc
      accessModes:
        - ReadWriteOnce
    podSecurityContext:
      enabled: true
      fsGroup: 1001
      fsGroupChangePolicy: OnRootMismatch
    containerSecurityContext:
      enabled: true
      runAsUser: 1001
      runAsGroup: 1001
      runAsNonRoot: true
...

설치

helm repo add dragonfly https://dragonflyoss.github.io/helm-charts/
helm repo update

helm upgrade --install dragonfly dragonfly/dragonfly -n dragonfly-system --namespace dragonfly-system --create-namespace -f values.yaml

#삭제 방법
helm uninstall dragonfly -n dragonfly-system
kubectl delete ns dragonfly

모니터링

Grafana Dashboard JSON 참고자료

D7y-prometheus-metrics

D7y-monitoring

Grafana-Lab-D7y

  1. 모니터링을 위해서 values.yaml에서 각 metrics를 enable하고 prometheus Lable을 지정 metrics 활성화 요소

    • manager
    • scheduler
    • seedClient
    • client

  1. 대시보드는 D7y의 공식 문서와 Grafana Lab에서 제공본을 활용 가능
Name ID Link Description
Dragonfly Manager 15945 https://grafana.com/grafana/dashboards/15945 Granafa dashboard for dragonfly manager.
Dragonfly Scheduler 15944 https://grafana.com/grafana/dashboards/15944 Granafa dashboard for dragonfly scheduler.
Dragonfly Client 21053 https://grafana.com/grafana/dashboards/21053-client/ Granafa dashboard for dragonfly Seed Client.
Dragonfly Seed Client 21054 https://grafana.com/grafana/dashboards/21054-seed-client/ Granafa dashboard for dragonfly Seed Client.

*client, manager, scheduler 사용 가능

  1. 또는 D7y 공식 문서의 Operations > Best Practices > Observability > Promethues Metrics를 참고해 Prometheus 대시보드 직접 구현 가능 (버전 확인 필수)






테스트

이미지 용량별 Scale-Out 테스트

# 이미지 용량 34.5 MB 테스트, 최초 배포 후 10분 이후 스케일 아웃
kubectl create deployment nginx --image=nginx:latest --replicas=1
kubectl scale deployment nginx --replicas=30

# 이미지 용량 1.1 GB 테스트, 최초 배포 후 10분 이후 스케일 아웃
kubectl create deployment tensorflowmagenta --image=tensorflow/magenta:0.3.11 --replicas=1
kubectl scale deployment nginx --replicas=30

# 이미지 용량 743.3 MB 테스트, 최초 배포 후 10분 이후 스케일 아웃
kubectl create deployment tensorflowjupyter --image=tensorflow/tensorflow:nightly-jupyter --replicas=1
kubectl scale deployment nginx --replicas=30

*기본 제공 대시보드에서 확인 가능한 화면(예시)


확인용 커스텀 대시보드로 테스트 결과 확인

  • replicas = 1 배포
  • replicas = 30 적용

결과 해석

  • replicas=1의 최초 배포의 경우 외부에서 Download와 내부 P2P에 저장이 동시에 발생하여 P2P Offload는 50%, Traffic과 Event 또한 동일하게 발생함
  • 이후 replicas=30으로 scale-out 한 뒤에는 각 클라이언트간에만 Peer Traffic 및 Event 발생, P2P Offload 통계 또함 100%이며 External Registry Traffic은 발생하지 않음
  • 즉, 최초에는 클러스터 외부에서 이미지를 받아오지만 이후부터는 P2P로 클러스터 내부의 노드별 D7y Client 끼리 이미지를 공유받아 Pod를 생성함


[대시보스 항목 설명] - 대시보드 json은 첨부파일 확인


① P2P Offload Ratio (Gauge)

확인 내용: 전체 이미지 트래픽 중 내부 P2P 비율 해석

수치 의미
70%↑ 매우 성공
40~70% 보통
<40% 효과 미미

의미: 높을수록 Registry 병목 제거 성공


② External Registry Traffic (Stat) 확인 내용: 외부 Registry로 나간 실제 트래픽 의미: 비용 절감 지표, 장애 영향도 지표


③ P2P vs External Traffic (Line) 확인 내용: 내부/외부 트래픽 비교 의미:

P2P가 위 → 성공 External이 위 → 실패


④ Download Completion Ratio (Gauge) 확인 내용: 다운로드 성공률 기준: 95% 이상 유지 필요 의미: 낮으면 네트워크/피어 장애


⑤ Client Download Latency p95 확인 내용: 실제 배포 체감 시간 의미: Before/After 비교 핵심


⑥ Concurrent Scheduler Load 확인 내용: 동시 배포 처리량 의미: 지속 고수치 → 병목


⑦ Seed vs P2P Start Events 확인 내용: 외부 Seed vs 내부 확산 비율

정상 패턴:

Seed ↑ → 곧 감소 P2P ↑ → 유지            → 정상 확산 구조

첨부파일