字节跳动云原生

火山引擎基于 Dragonfly 的加速实践

Image

来源 | Dragonfly 社区

作者 | 火山引擎云原生团队

当大规模容器集群批量下载镜像时,容器镜像存储的网络带宽会成为性能瓶颈,导致镜像拉取缓慢。如果客户端使用了 Nydus 对镜像格式做转换,客户端对服务端的请求量会大幅增加,服务端 QPS 同样也会成为性能瓶颈。

为了解决这一问题,火山引擎镜像仓库(CR)支持基于 P2P 方式的大规模集群拉取:P2P 加速功能利用计算节点的带宽资源,可以进行节点之间镜像分发,减少对容器镜像存储的压力,从而大幅提升镜像拉取速度,减少应用部署时间。

那么企业该如何选用合适的 P2P 方案呢?在 2023 年 4 月的 KubeCon EU 现场,火山引擎云原生团队公开了开源 P2P 加速方案选型故事。

调研项目一:Dragonfly

Dragonfly

架构图

Image

术语

Manager

  • 存储动态配置供 Seed Peer 集群、Scheduler 集群以及 Dfdaemon 消费。

  • 维护 Seed Peer 集群和 Scheduler 集群之间关联关系。

  • 提供统一异步任务管理,用作预热等功能。

  • 监听各模块是否健康运行。

  • 为 Dfdaemon 筛选最优 Scheduler 集群调度使用。

  • 提供可视化控制台,方便用户操作管理 P2P 集群。

Scheduler

  • 基于机器学习的多场景自适应智能 P2P 节点调度, 为当前下载节点选择最优父节点。

  • 构建 P2P 下载网络的有向无环图。

  • 根据不同特征值评估节点下载能力, 剔除异常节点。

  • 当下载失败情况,主动通知 Dfdaemon 进行回源下载。

Dfdaemon

  • 基于 gRPC 提供下载功能, 并提供多源适配能力。

  • 开启 Seed Peer 模式可以作为 P2P 集群中回源下载节点, 也就是整个集群中下载的根节点。

  • 为镜像仓库或者其他 HTTP 下载任务提供代理服务。

  • 下载任务基于 HTTP 或 HTTPS 或其他自定义协议。
调研项目二:Kraken

架构图

Image

术语

Agent
  • 是 P2P 网络中的对等节点,需要在每个节点上部署。

  • 实现了 Docker Registry interface。

  • 通知 tracker 自己拥有的数据。

  • 下载其他 agent 的数据(tracker 会告诉该 agent 需要下载这块数据需要到哪个 agent 上下载)。

Origin

  • 负责从存储中读取数据做种。

  • 支持不同的存储。

  • 通过 Hash 环的形式保证高可用。

Tracker

  • P2P 网络中的协调者,追踪谁是 Peer,谁是 Seeder。

  • 追踪 Peer 拥有的数据。

  • 提供有序的 Peer 节点供 Peer 下载数据。

  • 通过 Hash 环的形式保证高可用。

Proxy

  • 实现了 Docker Registry Interface。

  • 将镜像层传给 Origin 组件。

  • 将 Tag 传给 BUILD INDEX 组件。

Build-Index

  • Tag 和 digest 映射,agent 下载对应 Tag 数据时向 Build-Index 获取对应的 Digest 值。

  • 集群之间镜像复制。

  • 保存 Tag 数据在存储中。

  • 通过 Hash 环的形式保证高可用。
Dragonfly VS Kraken
Image

基于项目整体成熟度、社区活跃度、用户数量、架构复杂度、是否针对 Nydus 优化以及未来发展趋势等因素综合考虑,我们决定采用 Dragonfly 进行尝试。

火山引擎加速实践
在火山引擎,我们的主要场景是容器服务 VKE 和弹性容器 VCI 通过镜像仓库 CR 拉取镜像:
  • VKE 是基于 ECS 部署的 K8s,因此十分适合每个节点部署 Dfdaemon,充分利用每个节点的带宽,进而充分利用 P2P 的能力。

  • VCI 的产品特点是底层有一些资源很充足虚拟节点,上层的服务以 Pod 为载体,因此无法像 VKE 那样每个节点部署 Dfdaemon,所以部署形式是部署几个 Dfdaemon 作为缓存,利用缓存的能力。

  • VKE/VCI 客户端拉取经过 Nydus 格式转化过的镜像。在该场景下,需要使用 Dfdaemon 作为缓存,不宜使用过多的节点,避免对 Scheduler 造成过大的调度压力。

基于上述需求,结合 Dragonfly 的特点,我们设计了一套兼容诸多因素的部署方案,方案设计如下:
Image
  • 火山引擎上的资源都是归属于主账号下。P2P 控制组件以主账号级别隔离,每个主账号下一套 P2P 控制组件。服务端实现 P2P Manager Controller,通过该 Controller 来管控控制面所有 P2P 控制组件。

  • P2P 控制组件部署在镜像仓库数据面 VPC,通过 LB 与用户集群打通。

  • 在 VKE 集群上,Dfdaemon 以 DaemonSet 方式部署,每个节点上部署一个 Dfdaemon。

  • 在 VCI 上,Dfdaemon 以 Deployment 方式部署。

  • ECS 上 Containerd 通过 127.0.0.1:65001 访问本节点上的 Dfdaemon。

  • 通过在用户集群部署一个 controller 组件,基于 PrivateZone 功能,在用户集群生成 clusterid.p2p.volces.com 域名, controller 会根据一定的规则挑选特定节点(包括 VKE、VCI)的 Dfdaemon pod,以 A 记录的形式解析到上述域名。

    • ECS 上 Nydusd 通过 clusterid.p2p.volces.com 域名访问 Dfdaemon。

    • VCI 上镜像服务客户端和 Nydusd 通过 clusterid.p2p.volces.com 域名访问 Dfdaemon。
压测数据
环境:
  • 镜像仓库:带宽 10Gbit/s。

  • ECS: 4C8G,挂载本地盘,带宽 6Gbit/s。

镜像

  • Nginx (500M)

  • TensorFlow (3G)

组件版本

  • Dragonfly v2.0.8。

Quota

  • Dfdaemon: Limit 2C6G。

  • Scheduler: 2 Replicas,Request 1C2G,Limit 4C8G。

  • Manager: 2 Replicas,Request 1C2G,Limit 4C8G。

POD 启动时间对比

Nginx Pod 分别并发 50、100、200、500 的所有 Pod 从创建到启动消耗时间。

Image

TensorFlow Pod 分别并发 50、100、200、500 的所有 Pod 从创建到启动消耗时间。

Image

在大规模拉镜像的场景下,在使用 Dragonfly 和 Dragonfly & Nydus 场景对比 OCIv1 场景能够节省 90% 以上的容器启动时间。使用 Nydus 之后启动时间更短是因为镜像 lazyload 的特性,只需要拉取很小的一部分元数据 Pod 就能启动。

存储源端带宽峰值对比
Nginx Pod 分别并发 50、100、200、500 的存储端峰值流量。
Image
TensorFlow Pod 分别并发 50、100、200、500 的存储端峰值流量。
Image
回源流量对比
Nginx Pod 分别并发 50、100、200、500 的回源流量。
Image
TensorFlow Pod 分别并发 50、100、200、500 的回源流量。
Image
在大规模场景下,使用 Dragonfly 回源拉取镜像的数量很少。OCIv1 的场景所有的镜像拉取都要回源,因此使用 Dragonfly 回源峰值和回源流量相比 OCIv1 的场景少很多。并且使用 Dragonfly 后随着并发数提高,回源峰值和流量不会显著提高。
总结
以上是火山引擎云原生团队在 P2P 镜像加速上的实践,在大规模节点拉镜像的场景下,我们的容器镜像拉取用时已节省超过 90%,在产品性能和客户服务能力方面都取得了极大的提升。
未来,我们将继续与 CNCF 基金会和 Dragonfly 社区开展更多合作,将更多场景化经验和设计沉淀到开源社区,方便更多企业和开发者参考。
Image
相关链接

[1] Volcano Engine: https://www.volcengine.com/

[2] Volcano Engine VKE: https://www.volcengine.com/product/vke

[3] Volcano Engine CR: https://www.volcengine.com/product/cr

[4] Dragonfly 官网: https://d7y.io/

[5] Dragonfly Github Repo: https://github.com/dragonflyoss/Dragonfly2

[6] Nydus 官网: https://nydus.dev/

[7] Nydus Gihtub Repo: https://github.com/dragonflyoss/image-service

- END -

加入我们

Image