前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用DragonFly进行智能镜像分发

使用DragonFly进行智能镜像分发

作者头像
极客运维圈
发布2020-06-22 12:02:50
1.8K0
发布2020-06-22 12:02:50
举报
文章被收录于专栏:乔边故事乔边故事

使用DragonFly进行智能镜像分发

Dragonfly 是一款基于 P2P 的智能镜像和文件分发工具。它旨在提高文件传输的效率和速率,最大限度地利用网络带宽,尤其是在分发大量数据时,例如应用分发、缓存分发、日志分发和镜像分发。 在阿里巴巴,Dragonfly 每个月会被调用 20 亿次,分发的数据量高达 3.4PB。Dragonfly 已成为阿里巴巴基础设施中的重要一环。 尽管容器技术大部分时候简化了运维工作,但是它也带来了一些挑战:例如镜像分发的效率问题,尤其是必须在多个主机上复制镜像分发时。 Dragonfly 在这种场景下能够完美支持 Docker 和 PouchContainer。它也兼容其他格式的容器。相比原生方式,它能将容器分发速度提高 57 倍,并让 Registry 网络出口流量降低 99.5%。 Dragonfly 能让所有类型的文件、镜像或数据分发变得简单而经济。 更多请通过官方文档了解。

纯Docker部署

这里采用多机部署,方案如下:

应用

IP

服务端

172.17.100.120

客户端

172.17.100.121

客户端

172.17.100.122

部署服务端

以docker方式部署,命令如下:

代码语言:javascript
复制
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 地址:

代码语言:javascript
复制
cat <<EOD > /etc/dragonfly/dfget.yml
nodes:
    - 172.17.100.120
EOD
启动客户端
代码语言:javascript
复制
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 中添加或更新如下配置项:

代码语言:javascript
复制
{
  "registry-mirrors": ["http://127.0.0.1:65001"]
}

然后重启Docker

代码语言:javascript
复制
systemctl restart docker

拉取镜像测试

在任意一台客户端上进行测试,比如:

代码语言:javascript
复制
docker pull tomcat

验证

查看client端的日志,如果输出如下,则表示是通过DragonFly来传输的。

代码语言:javascript
复制
docker exec dfclient grep 'downloading piece' /root/.small-dragonfly/logs/dfclient.log
代码语言:javascript
复制
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 节点来完成传输,可以执行以下命令:

代码语言:javascript
复制
docker exec dfclient grep 'downloading piece' /root/.small-dragonfly/logs/dfclient.log | grep -v cdnnode

如果以上命令没有输出结果,则说明镜像没有通过其他peer节点完成传输,否则说明通过其他peer节点完成传输。

在Kubernetes中部署

服务端以Deployment的形式部署

代码语言:javascript
复制
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已经正常启动了。

代码语言:javascript
复制
# kubectl get pod -n kube-system | grep supernode
supernode-86dc99f6d5-mblck                 1/1     Running   0          4m1s

客户端以daemonSet的形式部署,yaml文件如下:

代码语言:javascript
复制
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文件,如下:

代码语言:javascript
复制
apiVersion: v1
kind: ConfigMap
metadata:
  name: dragonfly-conf
  namespace: kube-system
data:
  dfget.yml: |
    nodes:
    - 172.17.100.120

部署过后观察结果

代码语言:javascript
复制
# 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的配置,如下:

代码语言:javascript
复制
{
  "registry-mirrors": ["http://127.0.0.1:65001"]
}

重启docker

代码语言:javascript
复制
systemctl restart docker

现在我们来拉取镜像测试,并观察日志输出。 下载镜像(在master上测试的):

代码语言:javascript
复制
docker pull nginx

然后观察日志

代码语言:javascript
复制
kubectl exec  -n kube-system dfdaemon-wgq5d  grep 'downloading piece' /root/.small-dragonfly/logs/dfclient.log

看到日志输出如下,表示成功

代码语言:javascript
复制
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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 极客运维圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用DragonFly进行智能镜像分发
    • 纯Docker部署
      • 部署服务端
      • 部署客户端
      • 修改Docker Daemon配置
      • 拉取镜像测试
      • 验证
    • 在Kubernetes中部署
    相关产品与服务
    容器镜像服务
    容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档