<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Dragonfly V2 分發(fā)集群的鏡像

          共 22393字,需瀏覽 45分鐘

           ·

          2024-03-24 18:00

          1. Dragonfly 簡(jiǎn)介

          Dragonfly 的相關(guān)文檔在社區(qū) https://d7y.io/zh/docs/ 已經(jīng)有詳細(xì)說(shuō)明。這里只是簡(jiǎn)單介紹一下,V2 版本的主要組件:

          • Manager,提供 UI 界面、用戶(hù)管理、集群監(jiān)控、任務(wù)管理等功能
          • Scheduler,調(diào)度 Peer 之間的流量、提供預(yù)熱等功能
          • Seed Peer,回源節(jié)點(diǎn),用于從源站(Harbor、Docker.io 等)下載數(shù)據(jù),也可以作為 Peer 節(jié)點(diǎn)
          • Peer,提供下載數(shù)據(jù)的終端節(jié)點(diǎn)

          其中 Manager、Scheduler 是單獨(dú)的容器鏡像,Seed Peer 和 Peer 是同一個(gè)容器鏡像。

          Dragonfly 支持的鏡像預(yù)熱功能,可以和 Harbor 進(jìn)行集成,但本文不會(huì)涉及。本文主要是介紹我們?cè)谥?AI 業(yè)務(wù)時(shí),生產(chǎn)環(huán)境下的一些實(shí)踐。值得注意的是 Dragonfly V2 實(shí)際上構(gòu)建了一個(gè) P2P 分發(fā)的網(wǎng)絡(luò),不僅可以分發(fā)鏡像,還可以分發(fā)文件,這就打開(kāi)了想象空間。

          2. IDC 機(jī)房中的 Dragonfly 集群

          我們 AI 模型的推理和訓(xùn)練都是基于 Kubernetes 集群,后端存儲(chǔ)采用的是企業(yè)版 JuiceFS,在每個(gè) Node 節(jié)點(diǎn)都掛載了幾個(gè) T 的 SSD 磁盤(pán),用來(lái)掛載 JuiceFS 的緩存目錄。

          因此,Kubernetes 集群中的每個(gè) Node 節(jié)點(diǎn)都具備作為 Dragonfly Peer 節(jié)點(diǎn)的條件。但 Peer 組網(wǎng)時(shí),我們不希望有額外的負(fù)擔(dān),包括:

          • 跨 VPC 的 NAT 流量
          • 公網(wǎng)傳輸數(shù)據(jù)

          下面是 Dragonflyv2 機(jī)房多 VPC 部署拓?fù)鋱D:

          3a9782d638e406554e5cf82c570c2d64.webp

          • LB 需要公網(wǎng) IP,作為 Peer 的接入點(diǎn)
          • 一個(gè) VPC 對(duì)應(yīng)一個(gè) Dragonfly 的 Cluster 抽象
          • 雖然 IDC 打通了 VPC 之間的網(wǎng)絡(luò),但一個(gè) VPC 內(nèi)的 Peer 才允許組網(wǎng)
          • 集群內(nèi)每個(gè) Node 節(jié)點(diǎn)部署一個(gè) Peer

          VPC 內(nèi),下面這張圖給出了詳細(xì)的高可用方案。

          ead6456e236346b9e0f92fc3e368aaa9.webp

          • LB 只需要內(nèi)網(wǎng) IP 即可
          • 使用云廠(chǎng)的 MySQL 8.0、Redis 6 服務(wù)
          • 兩臺(tái) VM 部署 Manager、Scheduler、Seed Peer
          • 每個(gè) VM 部署的是一套完整的 Dragonfly 集群,包括 Manager、Scheduler、Seed Peer,不用經(jīng)過(guò) LB 也能用
          • 每個(gè) Node 節(jié)點(diǎn)部署 Peer

          Dragonfly 構(gòu)建的 P2P 分發(fā)網(wǎng)絡(luò),不應(yīng)該和 PaaS 層耦合太緊密,避免循環(huán)依賴(lài)。因此,這里采用雙 VM 的方案,共享數(shù)據(jù)存儲(chǔ),保障可用性。在 Kubernetes 集群的 Master 節(jié)點(diǎn)上,我們也不會(huì)進(jìn)行加速優(yōu)化,保障 PaaS 層控制面的簡(jiǎn)潔和獨(dú)立。

          3. VM 上部署 Dragonfly 控制平面

          需要提前安裝好 Docker,分別在兩臺(tái) VM 上進(jìn)行獨(dú)立部署。

          3.1 安裝 docker-compose

          • 下載 docker-compose
                
                curl -L https://mirror.ghproxy.com/https://github.com/docker/compose/releases/download/v2.23.3/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
          • 添加執(zhí)行權(quán)限
                
                chmod +x /usr/local/bin/docker-compose
          • 查看版本
                
                docker-compose -v

          3.2 安裝 dragonfly

          參考 https://d7y.io/zh/docs/getting-started/quick-start/docker-compose/

          • 下載 docker-compose 部署文件
                
                cd /data
          wget https://mirror.ghproxy.com/https://github.com/dragonflyoss/Dragonfly2/archive/refs/tags/v2.1.28.tar.gz
          tar -zxvf v2.1.28.tar.gz
          cp -r Dragonfly2-2.1.28/deploy/docker-compose ./
          • 清理不需要的文件
                
                rm -rf *2.1.28*
          • 生成默認(rèn)的配置文件
                
                cd docker-compose

          由于默認(rèn)的發(fā)布包中,沒(méi)有配置文件,這里先生成一份配置文件,然后再修改。

                
                export IP=VM_IP
          ./run.sh

          立即終止執(zhí)行,然后繼續(xù)修改配置文件。

          • 固定鏡像版本
                
                sed -i 's/latest/v2.1.28/g' docker-compose.yaml
          • 修改存儲(chǔ)賬號(hào)及其他配置

          修改 Redis、MySQL 地址和密碼

                
                vim template/manager.template.yaml

          修改 Redis 密碼

                
                vim template/scheduler.template.yaml

          在這兩個(gè)配置文件中,還有一些其他的配置項(xiàng),可以根據(jù)實(shí)際情況進(jìn)行修改。比如,manager 的 addr 指向當(dāng)前主機(jī)的服務(wù)、將日志輸出到控制臺(tái)、開(kāi)啟 Metrics 等。

          • 修改 seed-peer 的緩存目錄
                
                vim docker-compose.yaml
                
                volumes:
            - ./cache:/var/cache/dragonfly
            - ./data:/var/lib/dragonfly

          如果關(guān)閉了 seed-peer 作為 peer 節(jié)點(diǎn)的功能,可以跳過(guò)這一步,同時(shí),VM 的磁盤(pán)空間也可以不用太大。

          • 啟動(dòng)服務(wù)
                
                docker-compose up -d
          • 查看服務(wù)
                
                docker-compose ps

          NAME        IMAGE                            COMMAND                  SERVICE     CREATED        STATUS                  PORTS
          manager     dragonflyoss/manager:v2.1.28     "/opt/dragonfly/bin/…"   manager     14 hours ago   Up 14 hours (healthy)   0.0.0.0:8080->8080/tcp, 0.0.0.0:65003->65003/tcp
          scheduler   dragonflyoss/scheduler:v2.1.28   "/opt/dragonfly/bin/…"   scheduler   14 hours ago   Up 14 hours (healthy)   0.0.0.0:8002->8002/tcp
          seed-peer   dragonflyoss/dfdaemon:v2.1.28    "/opt/dragonfly/bin/…"   seed-peer   14 hours ago   Up 14 hours (healthy)   65001/tcp, 0.0.0.0:65006-65008->65006-65008/tcp
          • 打開(kāi)管理頁(yè)面看看

          訪(fǎng)問(wèn) http://${VM_IP}:8080 端口可以看到 Dragonfly 的管理界面,如果機(jī)器沒(méi)有公網(wǎng) IP,可以使用 socat 進(jìn)行端口轉(zhuǎn)發(fā)。找一臺(tái)有公網(wǎng) IP 的機(jī)器,執(zhí)行以下命令,將 30000 端口轉(zhuǎn)發(fā)到 8080 端口:

                
                export IP=VM_IP
          socat TCP-LISTEN:30000,fork TCP:$IP:8080

          兩臺(tái) VM 部署完成,在 Dashboard 中可以看到這樣一個(gè)集群,兩個(gè) Scheduler、兩個(gè) Seed Peer。如下圖:

          a0dfe461174ea0580b0f84dc53db77a7.webp

          4. 在集群部署 Peer 節(jié)點(diǎn)

          • 創(chuàng)建命名空間
                
                kubectl create ns dragonfly-system
          • 創(chuàng)建配置文件

          這里需要將 LB 的 IP 地址填入配置文件中,Peer 才能接入到 Dragonfly 集群中。

                
                export MANAGER_IP=LB_IP

          有很多參數(shù),可以根據(jù)實(shí)際情況進(jìn)行修改,這里提供了一份默認(rèn)的配置文件。

                
                kubectl apply -f - <<EOF
          apiVersion: v1
          data:
            dfget.yaml: |
              aliveTime: 0s
              gcInterval: 1m0s
              keepStorage: false
              workHome: /usr/local/dragonfly
              logDir: /var/log/dragonfly
              cacheDir: /var/cache/dragonfly
              pluginDir: /usr/local/dragonfly/plugins
              dataDir: /var/lib/dragonfly
              console: true
              health:
                path: /server/ping
                tcpListen:
                  port: 40901
              verbose: true
              pprof-port: 18066
              metrics: ":8000"
              jaeger: ""
              scheduler:
                manager:
                  enabletrue
                  netAddrs:
                    - type: tcp
                      addr: $MANAGER_IP:65003
                  refreshInterval: 10m
                netAddrs:
                scheduleTimeout: 30s
                disableAutoBackSource: false
                seedPeer:
                  clusterID: 1
                  enablefalse
                  type: super
              host:
                idc: ""
                location: ""
              download:
                calculateDigest: true
                downloadGRPC:
                  security:
                    insecure: true
                    tlsVerify: true
                  unixListen:
                    socket: ""
                peerGRPC:
                  security:
                    insecure: true
                  tcpListen:
                    port: 65000
                perPeerRateLimit: 512Mi
                prefetch: false
                totalRateLimit: 1024Mi
              upload:
                rateLimit: 1024Mi
                security:
                  insecure: true
                  tlsVerify: false
                tcpListen:
                  port: 65002
              objectStorage:
                enablefalse
                filter: Expires&Signature&ns
                maxReplicas: 3
                security:
                  insecure: true
                  tlsVerify: true
                tcpListen:
                  port: 65004
              storage:
                diskGCThreshold: 1000Gi
                multiplex: true
                strategy: io.d7y.storage.v2.simple
                taskExpireTime: 72h
              proxy:
                defaultFilter: Expires&Signature&ns
                defaultTag:
                tcpListen:
                  port: 65001
                security:
                  insecure: true
                  tlsVerify: false
                registryMirror:
                  dynamic: true
                  insecure: false
                  url: https://index.docker.io
                proxies:
                  - regx: blobs/sha256.*
              security:
                autoIssueCert: false
                caCert: ""
                certSpec:
                  dnsNames: null
                  ipAddresses: null
                  validityPeriod: 4320h
                tlsPolicy: prefer
                tlsVerify: false
              network:
                enableIPv6: false
              announcer:
                schedulerInterval: 30s
          kind: ConfigMap
          metadata:
            labels:
              app: dragonfly
            name: dragonfly-dfdaemon
            namespace: dragonfly-system
          EOF
          • 創(chuàng)建 DaemonSet

          我們從官方的 Helm Chart 中提取出來(lái)的 DaemonSet 文件。需要注意的是,Peer 使用的緩存目錄是主機(jī)上的 /data/dfget 目錄。最好提前清理主機(jī)上的 /data/dfget 目錄,避免出現(xiàn)權(quán)限問(wèn)題,也不用提前創(chuàng)建,DaemonSet 會(huì)自動(dòng)創(chuàng)建。

                
                kubectl apply -f - <<EOF
          apiVersion: apps/v1
          kind: DaemonSet
          metadata:
            labels:
              app: dragonfly
            name: dragonfly-dfdaemon
            namespace: dragonfly-system
          spec:
            selector:
              matchLabels:
                app: dragonfly
            template:
              metadata:
                labels:
                  app: dragonfly
              spec:
                containers:
                - image: dragonflyoss/dfdaemon:v2.1.28
                  livenessProbe:
                    exec:
                      command:
                      - /bin/grpc_health_probe
                      - -addr=:65000
                  name: dfdaemon
                  ports:
                  - containerPort: 65001
                    protocol: TCP
                  - containerPort: 40901
                    hostIP: 127.0.0.1
                    hostPort: 40901
                    protocol: TCP
                  - containerPort: 8000
                    protocol: TCP
                  readinessProbe:
                    exec:
                      command:
                      - /bin/grpc_health_probe
                      - -addr=:65000
                    failureThreshold: 3
                    initialDelaySeconds: 5
                    periodSeconds: 10
                    successThreshold: 1
                    timeoutSeconds: 1
                  resources:
                    limits:
                      cpu: "2"
                      memory: 2Gi
                  securityContext:
                    capabilities:
                      add:
                      - SYS_ADMIN
                  volumeMounts:
                  - mountPath: /etc/dragonfly
                    name: config
                  - mountPath: /var/cache/dragonfly
                    name: dfgetcache
                  - mountPath: /var/lib/dragonfly
                    name: dfgetdata
                hostNetwork: true
                hostPID: true
                volumes:
                - configMap:
                    defaultMode: 420
                    name: dragonfly-dfdaemon
                  name: config
                - hostPath:
                    path: /data/dfget/cache
                    type: DirectoryOrCreate
                  name: dfgetcache
                - hostPath:
                    path: /data/dfget/data
                    type: DirectoryOrCreate
                  name: dfgetdata
          EOF
          • 查看負(fù)載
                
                kubectl -n dragonfly-system get pod

          NAME                       READY   STATUS    RESTARTS   AGE
          dragonfly-dfdaemon-79qkw   1/1     Running   0          14h
          dragonfly-dfdaemon-8hhzb   1/1     Running   3          14h
          dragonfly-dfdaemon-nnfc5   1/1     Running   0          14h
          dragonfly-dfdaemon-w7lff   1/1     Running   0          14h
          dragonfly-dfdaemon-wrmzw   1/1     Running   0          14h

          5. 在 VM 上部署 Peer 節(jié)點(diǎn)

          • 創(chuàng)建目錄
                
                mkdir -p /data/dfget && cd /data/dfget
          • 設(shè)置 IP
                
                wget https://mirror.ghproxy.com/https://raw.githubusercontent.com/shaowenchen/hubimage/main/nydus/dfget.template.yaml -O dfget.yaml
                
                export MANAGER_IP=LB_IP
          sed -i "s/__MANAGER_IP__/$MANAGER_IP/g" dfget.yaml
          • 啟動(dòng) Peer
                
                nerdctl run -d --name=peer --restart=always \
                      -p 65000:65000 -p 65001:65001 -p 65002:65002 \
                      -v $(pwd)/data:/var/lib/dragonfly \
                      -v $(pwd)/cache:/var/cache/dragonfly \
                      -v $(pwd)/dfget.yaml:/etc/dragonfly/dfget.yaml:ro \
                      dragonflyoss/dfdaemon:v2.1.28

          6. 使用節(jié)點(diǎn)配置

          6.1 Docker

          Docker 的 Mirror 方式只能加速 Docker.io 的鏡像,這里采用 Proxy 的方式,代理全部 Dockerd 的流量。Proxy 與 Mirror 的區(qū)別在于,Mirror 掛了,Dockerd 會(huì)拉取源站,而 Proxy 掛了,Dockerd 直接拉取失敗。

          • 添加代理
                
                mkdir -p /etc/systemd/system/docker.service.d
                
                cat > /etc/systemd/system/docker.service.d/http-proxy.conf <<EOF
          [Service]
          Environment="HTTP_PROXY=http://127.0.0.1:65001"
          Environment="HTTPS_PROXY=http://127.0.0.1:65001"
          EOF
          • 重啟 Docker
                
                systemctl daemon-reload
          systemctl restart docker

          注意,這里如果 /etc/docker/daemon.json 中沒(méi)有配置 "live-restore": true ,會(huì)導(dǎo)致容器全部重啟。

          • 查看環(huán)境變量
                
                systemctl show --property=Environment docker

          Environment=HTTP_PROXY=http://127.0.0.1:65001 HTTPS_PROXY=http://127.0.0.1:65001
          • 鏡像拉取測(cè)試
                
                docker pull nginx

          此時(shí),Dockerd 的流量會(huì)經(jīng)過(guò) Dragonfly Peer 節(jié)點(diǎn)。

          6.2 Containerd

          參考 https://github.com/containerd/containerd/blob/main/docs/cri/config.md#registry-configuration

          /etc/containerd/config.toml[plugins."io.containerd.grpc.v1.cri".registry] 項(xiàng)的 config_path = "/etc/containerd/certs.d" 提供了類(lèi)似于 mirror 的配置方式。

          • 配置 Docker.io
                
                mkdir -p /etc/containerd/certs.d/docker.io
                
                cat > /etc/containerd/certs.d/docker.io/hosts.toml <<EOF
          server = "https://docker.io"

          [host."http://127.0.0.1:65001"]
            capabilities = ["pull""resolve"]
            [host."http://127.0.0.1:65001".header]
              X-Dragonfly-Registry = ["https://registry-1.docker.io"]
            [host."https://registry-1.docker.io"]
              capabilities = ["pull""resolve"]
          EOF
          • 配置其他、私有鏡像倉(cāng)庫(kù)

          其他鏡像倉(cāng)庫(kù)的配置可以通過(guò)腳本生成,比如:

                
                wget https://mirror.ghproxy.com/https://raw.githubusercontent.com/dragonflyoss/Dragonfly2/main/hack/gen-containerd-hosts.sh
          bash gen-containerd-hosts.sh ghcr.io

          這里沒(méi)有用腳本生成 docker.io 的配置是因?yàn)椋傻呐渲梦募校?code style="color:rgb(235,97,97);font-size:14px;font-family:'Operator Mono', Consolas, Monaco, Menlo, monospace;">X-Dragonfly-Registry 是 https://docker.io,而不是 https://registry-1.docker.io。

          使用 X-Dragonfly-Registry = ["https://docker.io"] 會(huì)出現(xiàn)如下錯(cuò)誤:

                
                unknow type: text/html

          以上添加的 mirror,不用重啟 Containerd,直接能生效。

          • 鏡像拉取測(cè)試
                
                nerdctl pull nginx

          此時(shí),在本地 /data/dfget/data 目錄下可以看到 Peer 節(jié)點(diǎn)緩存的鏡像數(shù)據(jù)。

          7. 集成 Nydus

          如果 Nydus 已經(jīng)配置好,這里其實(shí)已經(jīng)能輕松配置好。

          • 給 Nydusd 添加 mirror
                
                vim /etc/nydus/nydusd-config.fusedev.json
                
                {
            "device": {
              "backend": {
                "type""registry",
                "config": {
                  "mirrors": [
                    {
                      "host""http://127.0.0.1:65001",
                      "auth_through"false,
                      "headers": {
                        "X-Dragonfly-Registry""https://index.docker.io"
                      },
                      "ping_url""http://127.0.0.1:40901/server/ping"
                    }
                  ]
                }
              }
            }
          }
          • 重啟 Nydusd
                
                systemctl restart nydus-snapshotter
          • 鏡像拉取測(cè)試
                
                nerdctl pull shaowenchen/demo-ubuntu:latest-nydus

          8. 總結(jié)

          本篇記錄了這周在生產(chǎn)環(huán)境中,測(cè)試并部署 Dragonfly V2 的部分過(guò)程,主要內(nèi)容包括:

          • 機(jī)房中 Dragonfly 集群的部署拓?fù)?/li>
          • 集群和 VM 上 Peer 節(jié)點(diǎn)的部署
          • Docker、Containerd、Nydus 的集成

          說(shuō)下不足,沒(méi)有指標(biāo)監(jiān)控,在做 Benchmark 時(shí),我們發(fā)現(xiàn) AZ 內(nèi)和跨 AZ 的 Peer 之間的數(shù)據(jù)傳輸都受限,如果想構(gòu)建高性能的 P2P 分發(fā)網(wǎng)絡(luò),Peer 與 Peer、Peer 與 Seed Peer 之間的網(wǎng)絡(luò)是一個(gè)重要的考量因素。

          bc8d4ff952a98acf524367176df89b7a.webp

          瀏覽 203
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  北条麻纪无码成人 | 黄色片亚洲 | 日本一区二区三区在线观看 | 国产一级在线电影 | 亚洲无码视频在线观看 |