1. 程式人生 > >使用DragonFly進行智慧映象分發

使用DragonFly進行智慧映象分發

![](https://img2020.cnblogs.com/blog/2022564/202006/2022564-20200621120041723-1951570686.png) Dragonfly 是一款基於 P2P 的智慧映象和檔案分發工具。它旨在提高檔案傳輸的效率和速率,最大限度地利用網路頻寬,尤其是在分發大量資料時,例如應用分發、快取分發、日誌分發和映象分發。

在阿里巴巴,Dragonfly 每個月會被呼叫 20 億次,分發的資料量高達 3.4PB。Dragonfly 已成為阿里巴巴基礎設施中的重要一環。

儘管容器技術大部分時候簡化了運維工作,但是它也帶來了一些挑戰:例如映象分發的效率問題,尤其是必須在多個主機上覆制映象分發時。

Dragonfly 在這種場景下能夠完美支援 Docker 和 [PouchContainer](https://github.com/alibaba/pouch)。它也相容其他格式的容器。相比原生方式,它能將容器分發速度提高 57 倍,並讓 Registry 網路出口流量降低 99.5%。
Dragonfly 能讓所有型別的檔案、映象或資料分發變得簡單而經濟。

更多請通過[官方文件](https://d7y.io/zh-cn/docs/overview/what_is_dragonfly.html)瞭解。
## 純Docker部署 這裡採用多機部署,方案如下:
![](https://cdn.nlark.com/yuque/0/2020/png/255717/1592705247556-89c1a9a0-61d7-4013-b7c5-d3d8cf9ec02e.png#align=left&display=inline&height=904&margin=%5Bobject%20Object%5D&originHeight=904&originWidth=1544&size=0&status=done&style=none&width=1544) | 應用 | IP | | --- | --- | | 服務端 | 172.17.100.120 | | 客戶端 | 172.17.100.121 | | 客戶端 | 172.17.100.122 |
### 部署服務端 以docker方式部署,命令如下: ```bash docker run -d --name supernode --restart=always -p 8001:8001 -p 8002:8002 \ dragonflyoss/supernode:0.3.0 -Dsupernode.advertiseIp=172.17.100.120 ``` ### 部署客戶端 **準備配置檔案**
Dragonfly 的配置檔案預設位於 `/etc/dragonfly` 目錄下,使用容器部署客戶端時,需要將配置檔案掛載到容器內。
為客戶端配置 Dragonfly Supernode 地址: ``` cat < /etc/dragonfly/dfget.yml nodes: - 172.17.100.120 EOD ``` ##### 啟動客戶端 ``` docker run -d --name dfclient --restart=always -p 65001:65001 \ -v /etc/dragonfly:/etc/dragonfly \ dragonflyoss/dfclient:v0.3.0 --registry https://index.docker.io ``` > registry是倉庫地址,這裡使用的官方倉庫 ### 修改Docker Daemon配置 我們需要修改 Dragonfly 客戶端機器(`dfclient0`, `dfclient1`)上 Docker Daemon 配置,通過 mirror 方式來使用 Dragonfly 進行映象的拉取。
在配置檔案 `/etc/docker/daemon.json` 中新增或更新如下配置項: ``` { "registry-mirrors": ["http://127.0.0.1:65001"] } ``` 然後重啟Docker ``` systemctl restart docker ``` ### 拉取映象測試 在任意一臺客戶端上進行測試,比如: ``` docker pull tomcat ``` ### 驗證 檢視client端的日誌,如果輸出如下,則表示是通過DragonFly來傳輸的。 ``` docker exec dfclient grep 'downloading piece' /root/.small-dragonfly/logs/dfclient.log ``` ``` 2020-06-20 15:56:49.813 INFO sign:146-1592668602.159 : downloading piece:{"taskID":"4d977359836129ce2eec4b8418a7042c47db547a239e2a577ddc787ee177289c","superNode":"172.17.100.120","dstCid":"cdnnode:172.17.100.120~4d977359836129ce2eec4b8418a7042c47db547a239e2a577ddc787ee177289c","range":"0-4194303","result":503,"status":701,"pieceSize":4194304,"pieceNum":0} ``` 如果需要檢視映象是否通過其他 peer 節點來完成傳輸,可以執行以下命令: ``` docker exec dfclient grep 'downloading piece' /root/.small-dragonfly/logs/dfclient.log | grep -v cdnnode ``` 如果以上命令沒有輸出結果,則說明映象沒有通過其他peer節點完成傳輸,否則說明通過其他peer節點完成傳輸。
## 在Kubernetes中部署 服務端以Deployment的形式部署 ``` apiVersion: apps/v1 kind: Deployment metadata: labels: app: supernode name: supernode namespace: kube-system spec: replicas: 1 selector: matchLabels: app: supernode template: metadata: labels: app: supernode annotations: scheduler.alpha.kubernetes.io/critical-pod: "" spec: containers: - image: dragonflyoss/supernode:0.3.0 name: supernode ports: - containerPort: 8080 hostPort: 8080 name: tomcat protocol: TCP - containerPort: 8001 hostPort: 8001 name: register protocol: TCP - containerPort: 8002 hostPort: 8002 name: download protocol: TCP volumeMounts: - mountPath: /etc/localtime name: ltime - mountPath: /home/admin/supernode/logs/ name: log - mountPath: /home/admin/supernode/repo/ name: data hostNetwork: true dnsPolicy: ClusterFirstWithHostNet restartPolicy: Always tolerations: - effect: NoExecute operator: Exists - effect: NoSchedule operator: Exists nodeSelector: node-role.kubernetes.io/master: "" volumes: - hostPath: path: /etc/localtime type: "" name: ltime - hostPath: path: /data/log/supernode type: DirectoryOrCreate name: log - hostPath: path: /data/supernode/repo/ type: DirectoryOrCreate name: data --- kind: Service apiVersion: v1 metadata: name: supernode namespace: kube-system spec: selector: app: supernode ports: - name: register protocol: TCP port: 8001 targetPort: 8001 - name: download protocol: TCP port: 8002 targetPort: 8002 ``` > 以hostNetwork的形式部署在master上。 部署過後可以看到supernode已經正常啟動了。 ``` # kubectl get pod -n kube-system | grep supernode supernode-86dc99f6d5-mblck 1/1 Running 0 4m1s ```
客戶端以daemonSet的形式部署,yaml檔案如下: ``` apiVersion: apps/v1 kind: DaemonSet metadata: name: dfdaemon namespace: kube-system spec: selector: matchLabels: app: dfdaemon template: metadata: annotations: scheduler.alpha.kubernetes.io/critical-pod: "" labels: app: dfdaemon spec: containers: - image: dragonflyoss/dfclient:v0.3.0 name: dfdaemon imagePullPolicy: IfNotPresent args: - --registry https://index.docker.io resources: requests: cpu: 250m volumeMounts: - mountPath: /etc/dragonfly/dfget.yml subPath: dfget.yml name: dragonconf hostNetwork: true dnsPolicy: ClusterFirstWithHostNet restartPolicy: Always tolerations: - effect: NoExecute operator: Exists - effect: NoSchedule operator: Exists volumes: - name: dragonconf configMap: name: dragonfly-conf ``` 配置檔案我們以configMap的形式掛載,所以我們還需要編寫一個configMap的yaml檔案,如下: ``` apiVersion: v1 kind: ConfigMap metadata: name: dragonfly-conf namespace: kube-system data: dfget.yml: | nodes: - 172.17.100.120 ``` 部署過後觀察結果 ``` # kubectl get pod -n kube-system | grep dfdaemon dfdaemon-mj4p6 1/1 Running 0 3m51s dfdaemon-wgq5d 1/1 Running 0 3m51s dfdaemon-wljt6 1/1 Running 0 3m51s ```
然後修改docker daemon的配置,如下: ``` { "registry-mirrors": ["http://127.0.0.1:65001"] } ``` 重啟docker ``` systemctl restart docker ```
現在我們來拉取映象測試,並觀察日誌輸出。
下載映象(在master上測試的): ``` docker pull nginx ``` 然後觀察日誌 ``` kubectl exec -n kube-system dfdaemon-wgq5d grep 'downloading piece' /root/.small-dragonfly/logs/dfclient.log ``` 看到日誌輸出如下,表示成功 ``` 2020-06-20 17:14:54.578 INFO sign:128-1592673287.190 : downloading piece:{"taskID":"089dc52627a346df2a2ff67f6c07497167b35c4bad2bca1e9aad087441116982","superNode":"172.17.100.120","dstCid":"cdnnode:192.168.235.192~089dc52627a346df2a2ff67f6c07497167b35c4bad2bca1e9aad087441116982","range":"0-4194303","result":503,"status":701,"pieceSize":4194304,"pieceNum":0} ``` 今天的測試就到這裡,我這是自己的小叢集實驗室,效果其實並不明顯,在大叢集效果可能更好。
- 參考 - [https://d7y.io/zh-cn/docs/userguide/multi_machines_deployment.html](https://d7y.io/zh-cn/docs/userguide/multi_machines_deploymen