本篇文章则分享在大规模的kubernetes集群中,通过Harbor与Dragonfly来优化镜像的拉取速度。

Dragonfly(蜻蜓)简介

k8s如何创建镜像 k8s镜像拉取策略_docker

项目地址:https://github.com/dragonflyoss/Dragonfly2

官方文档: https://d7y.io/zh/docs/

Dragonfly(蜻蜓)是一款开源的基于 P2P 的智能镜像和文件分发工具。它旨在提高大规模文件传输的效率和速率,最大限度地利用网络带宽。在应用分发、缓存分发、日志分发和镜像分发等领域被大规模使用。是由CNCF(云原生计算基金会)作为孵化级项目(阿里)。

1.1 Dragonfly的功能

  • 基于 P2P 的文件分发:通过利用 P2P 技术进行文件传输,它能最大限度地利用每个对等节点(Peer)的带宽资源,以提高下载效率,并节省大量跨机房带宽,尤其是昂贵的跨境带宽。
  • 非侵入式接入:Dragonfly 可无缝支持多种容器用于分发镜像。
  • 主机级别的限速:除了像许多其他下载工具针对当前下载任务的限速之外,Dragonfly 还支持针对整个机器的限速。
  • 高度一致性:Dragonfly 可确保所有下载的文件是一致的,即使用户不进行最终一致性校验。
  • 隔离异常节点:Dragonfly 会自动隔离异常节点来提高下载稳定性。
  • 生态:Harbor 可以基于 Dragonfly 进行镜像分发以及预热。镜像加速项目 Nydus 可以在容器运行时使用 Dragonfly 进行数据分发。

1.2 特性

目前,蜻蜓专注于:

  • 简单:定义明确的面向用户的API(HTTP),对所有容器引擎都是非侵入性的;
  • 高效:种子对等支持,基于P2P的文件分发,节省企业带宽;
  • 智能:主机级限速,主机检测智能流量控制;
  • 安全:阻止传输加密,HTTPS连接支持。

1.3 架构浅析

k8s如何创建镜像 k8s镜像拉取策略_k8s如何创建镜像_02

Manager组件

  • 用户管理:提供RBAC及用户态管理功能;
  • 维护P2P 集群关系:Manager管理整个P2P集群关系,保证Seed Peer集群和Scheduler集群为1:N的关系,并且选择最优Scheduler提供Dfdaemon使用;
  • 异步任务管理:提供统一异步任务管理,支持预热等功能;
  • 监控集群:监控整个P2P集群的运行状态,剔除异常节点;
  • 可视化UI:提供可视化管理界面,方便管理;

scheduler组件

  • 调度:基于Peer之间的网络、带宽流量等进行调度,组建有向无循环图为当前调度Peer寻找最优父节点;
  • 回源:通过当前Peer下载情况,若异常或无父节点则主动通知Peer回源;
  • 任务状态:维护Peer中下载的任务状态,主动推进其状态变更;
  • 下载任务优化:针对不同的下载任务进行优化处理,分为Tiny、Small、Normal类型;
  • 预热:实现镜像和对象存储的预热,文件同步任务分发。

Seed Peer组件
Dfdaemon 打开种子对等模式可用作 P2P集群中的回源下载对等点, 这是整个集群中用于下载的根对等方。P2P客户端提供上传和下载功能。当集群内任务首次下载,Scheduler会触发Seed Peer回源。提供主动触发回源能力,可以作为P2P节点中的根节点。

Peer组件
  使用 dfdaemon 部署,基于 C/S 架构,提供命令下载工具, 以及提供任务下载功能的正在运行的守护程序。P2P客户端,提供上传和下载功能。

Dfget
  客户端命令行下载工具,和Daemon之间为C/S模式。

docker部署Dragonfly

Dragonfly支持docker-compose、Helm、源码三种安装方式。

因为Harbor是使用docker-compose部署的,所以本处也使用docker-compose部署Dragonfly。

2.1 拉取源码

$ yum install -y git
$ git clone https://github.com/dragonflyoss/Dragonfly2.git -b v2.0.9   #拉取v2.0.9版本的代码
$ cd ./Dragonfly2/deploy/docker-compose/

2.2 修改参数

同harbor安装在同一主机上时需要调整redis服务的名称,否则会和Harbor的redis冲突。修改docker-compose.yaml文件的services.redis.container_name参数值。

$ cat docker-compose.yaml
services:
  redis:
    image: redis:6-alpine
    container_name: redis_dragonfly  #需要修改(harbor的为redis)
    command: >
      --requirepass dragonfly
    healthcheck:
      test: ["CMD", "redis-cli", "-a", "dragonfly", "ping"]
      interval: 1s
      timeout: 2s
      retries: 30
    ports:
      - 6379:6379

2.3 执行安装脚本进行安装

$ export IP=192.168.2.19  && echo $IP  #声明环境变量指定当前主机IP
$ ./run.sh

k8s如何创建镜像 k8s镜像拉取策略_redis_03

2.4 查看组件服务状态

$ docker-compose ps
NAME                COMMAND                  SERVICE             STATUS              PORTS
manager             "/opt/dragonfly/bin/…"   manager             running (healthy)   0.0.0.0:8080->8080/tcp, 0.0.0.0:65003->65003/tcp
mysql               "docker-entrypoint.s…"   mysql               running (healthy)   0.0.0.0:3306->3306/tcp
peer                "/opt/dragonfly/bin/…"   dfdaemon            running (healthy)   0.0.0.0:65000-65002->65000-65002/tcp
redis-dragonfly     "docker-entrypoint.s…"   redis               running (healthy)   0.0.0.0:6379->6379/tcp
scheduler           "/opt/dragonfly/bin/…"   scheduler           running (healthy)   0.0.0.0:8002->8002/tcp
seed-peer           "/opt/dragonfly/bin/…"   seed-peer           running (healthy)   0.0.0.0:65006-65008->65006-65008/tcp

2.5 修改docker配置

$ cat /etc/docker/daemon.json
{
   ...
"registry-mirrors":["http://127.0.0.1:65001"],   #添加该项配置参数
...
}
$ sudo systemctl restart docker      #重启docker

2.6 重启Dragonfly2

$ docker-compose down && docker-compose up -d && docker-compose ps

2.7 验证测试

从dockerhub上拉取一个镜像,然后检验该镜像是否通过 Dragonfly 来传输完成。

$ docker rmi nginx:1.23.3
$ docker pull nginx:1.23.3
$ docker-compose exec dfdaemon grep "peer task done" /var/log/dragonfly/daemon/core.log

输出以下结果则正常:

{
  "level":"info",
  "ts":"2023-06-08 01:55:19.445",
  "caller":"peer/peertask_conductor.go:1330",
  "msg":"peer task done, cost: 37128ms",
  "peer":"192.168.2.19-1-a40c51df-315d-462a-ac4b-f55e9610065b",
  "task":"baaea6a3f961160e86d114571b3dd4d95b2145bc72d27969448da4570b32ae3f",
  "component":"PeerTask",
  "trace":"31814778b12db5a0834f916dc269e442"
}

k8s如何创建镜像 k8s镜像拉取策略_redis_04

2.8 登录Manager控制台管理界面

在浏览器输入主机IP和8080端口访问manager控制台,再输入用户和密码:root/dragonfly首次登录:

k8s如何创建镜像 k8s镜像拉取策略_k8s如何创建镜像_05


k8s如何创建镜像 k8s镜像拉取策略_IP_06


k8s如何创建镜像 k8s镜像拉取策略_redis_07

重新登录:

k8s如何创建镜像 k8s镜像拉取策略_IP_08


k8s如何创建镜像 k8s镜像拉取策略_redis_09

Harbor配置分布式分发

登录Harbor UI管理界面,找到【系统管理】-【分布式分发】-【新建实例】

k8s如何创建镜像 k8s镜像拉取策略_docker_10

填写信息:

供应商(必填):本处选择Dragonfly;
名称(必填):自定义一个名称即可;
端点(必填):http协议与Dragonfly地址及manager组件服务端口;
认证模式:NONE(无需身份验证)、Basic(需要 HTTP 基本身份验证模式、用户名和密码)、OAuth(OAuth 持有者令牌模式,需要持有者令牌)
选项:选择“启用”

k8s如何创建镜像 k8s镜像拉取策略_redis_11

k8s如何创建镜像 k8s镜像拉取策略_IP_12

检测失败可查看harbor的服务日志/var/log/harbor/core.log进行排错。