一、P2P镜像分发简述
随着云原生架构被越来越多的企业接受,企业应用中容器集群的规模也越来越大。当容器集群达到一定的规模且单容器应用副本数达到一定级别时,集群中容器镜像的分发将面临挑战。
P2P
(Peer-to-Peer,点对点)镜像分发借鉴了互联网P2P文件传输的思路,旨在提高镜像在容器集群中的分发效率,以更快的镜像拉取速度来对kubernetes集群进行优化。
本篇主要讲述 Kraken+Harbor的理论部分,部署及使用的实践部分在下篇文章进行详细的描述。
1.1 P2P镜像分发的原理
镜像分发规模达到一定数量时,首先面临压力的是Harbor服务或者后端存储的带宽。如果100个节点同时拉取镜像,镜像被压缩为500MB,此时需要在10秒内完成拉取,则后端存储面临5GB/s的带宽。
在一些较大的集群中,可能有上千个节点同时拉取一个镜像,带宽压力可想而知。
解决这个问题的方法有很多,比如划分集群、增加缓存和负载均衡等,但较好的解决方法可能是采用P2P镜像分发技术。
Ps: Harbor在镜像同步、镜像拉取的默认超时时间是900s,镜像拉取超时时间可以在Harbor的Nginx配置文件/etc/nginx/nginx.conf中进行修改。
$ cat /etc/nginx/nginx.conf
http {
...
proxy_connect_timeout 600; #连接超时时间
proxy_send_timeout 600; #发送超时时间
proxy_read_timeout 600; #读取超时时间
...
}
修改完成后,需要重新启动Harbor服务和Nginx服务,使配置生效。
P2P镜像分发技术将需要分发的文件做分片处理,生成种子文件,每个P2P节点都根据种子文件下载分片。做分片时可以将文件拆分成多个任务并行执行,不同的节点可以从种子节点拉取不同的分片,下载完成之后自己再作为种子节点供别的节点下载。采用去中心化的拉取方式之后,流量被均匀分配到P2P网络中的节点上,可以显著提升分发速度。
1.2 P2P镜像分发技术有哪些?
以下是一些常见的P2P镜像分发技术:
Kraken: Uber使用Go语言开发而开源的一个镜像P2P分发项目
Dragonfly: 阿里巴巴开源的 P2P 镜像和文件分发系统,可以解决原生云应用中面临的分发问题。
BitTorrent: BitTorrent是一种常用的P2P文件分发协议,可以用于分发镜像文件。BitTorrent协议将文件划分为多个块,每个块由多个节点共享,下载者可以同时从多个节点下载块,从而提高下载速度。
IPFS: IPFS(InterPlanetary File System)是一种分布式文件系统,可以用于存储和分发镜像文件。IPFS将文件分割为多个块,每个块由多个节点存储,下载者可以从多个节点下载块,从而提高下载速度和可靠性。
Docker Swarm: Docker Swarm是Docker官方提供的容器编排工具,可以用于分发镜像文件。Docker Swarm将镜像分发到多个节点上,下载者可以从多个节点下载镜像,从而提高下载速度和可靠性。
Alibaba Cloud P2P镜像服务: 阿里云提供了P2P镜像服务,可以用于分发镜像文件。P2P镜像服务将镜像分发到多个节点上,下载者可以从就近的节点下载镜像,从而提高下载速度和可靠性。
需要注意的是,P2P镜像分发技术需要在多个节点之间共享和下载文件,因此需要考虑安全性和版权问题。此外,不同的P2P镜像分发技术有不同的实现方式和特点,需要根据实际情况选择合适的技术。
二、Kraken P2P镜像分发
项目地址:https://github.com/uber/kraken
2.1 Kraken是什么?
Kraken 是一个 P2P 驱动的 Docker 注册表,专注于可扩展性和可用性。它专为混合云环境中的 Docker 镜像管理、复制和分发而设计。借助可插拔的后端支持,Kraken 可以作为分发层轻松集成到现有的 Docker 注册表设置中。
自 2018 年初以来,Kraken 一直在 Uber 投入生产。在我们最繁忙的集群中,Kraken 每天分发超过 100 万个 blob,其中包括 10 万个 1G+ blob。在生产负载高峰期,Kraken 在 30 秒内分发了 20K 100MB-1G 的 blob。
解决这个问题的方法有很多,比如划分集群、增加缓存和负载均衡等,但较好的解决方法可能是采用P2P镜像分发技术。Kraken是Uber使用Go语言开发而开源的一个镜像P2P分发项目。其采用了无共享架构,具有部署简单、容错性高的特点,所以整体上系统的运维成本比较低。
解决这个问题的方法有很多,比如划分集群、增加缓存和负载均衡等,但较好的解决方法可能是采用P2P镜像分发技术。Kraken的核心是P2P文件分发,主要功能是容器镜像的P2P分发,目前并不支持通用文件的分发。
2.2 Kraken组件
Kraken由Proxy、Build-Index、Tracker、Origin、Agent五个组件组成:
Proxy: 作为Kraken的门户,实现了Docker Registry V2接口。
Build-Index: 和后端存储对接,负责镜像Tag和Digest的映射。
Origin: 和后端存储对接,负责文件对象的存储,在分发时作为种子节点。
Tracker :P2P分发的中心服务,记录节点内容,负责形成P2P分发网络。
Agent: 部署在节点上,实现了Docker Registry V2接口,负责通过P2P拉取镜像文件。
2.3 特征
以下是 Kraken 的一些亮点:
高度可扩展: Kraken 能够以超过每台主机最大下载速度限制的 50% 的速度分发 Docker 映像。簇大小和图像大小对下载速度没有显着影响。
每个集群至少支持 15k 台主机。
支持任意大的斑点/层。我们通常将最大大小限制为 20G 以获得最佳性能。
高度可用: 没有组件是单点故障。
安全: 通过 TLS 支持上传者身份验证和数据完整性保护。
可插拔存储选项: Kraken 不是管理数据,而是插入可靠的 blob 存储选项,如 S3、GCS、ECR、HDFS 或其他注册表。存储界面简单,新选项易于添加。
无损跨集群复制: Kraken 支持集群间基于规则的异步复制。
最小的依赖性: 除了可插拔存储,Kraken 仅对 DNS 具有可选依赖性。
2.4 Kraken+Harbor的3种可选方案
结合Kraken的P2P镜像分发技术,其基本思路是将Harbor作为镜像管理系统,将Kraken作为镜像分发工具,有三种可选方案:
方案一:
以Harbor作为统一的对外接口,将Kraken作为后端,后面对接Registry;
方案二:
以Kraken作为统一的对外接口,将Harbor作为后端;
方案三:
使用一个公共的Registry作为统一的后端,Harbor和Kraken都使用这个Registry。
其中,在第3种方案中解耦了两个系统,当Harbor或者Kraken出现问题时,另一个系统仍可以正常工作。这种方案要求Harbor和Kraken能访问同一个Registry,最好是将Harbor和Kraken部署在同一个Kubernetes集群中,然后通过Service模式访问同一个Registry服务。
如果不能将它们部署在同一个集群中,就需要跨集群访问,效率受到影响。所以,当Harbor和Kraken被部署在不同集群中时,也可采用第2种方案,这样Kraken会对Harbor强依赖。Kraken通过Harbor对外暴露的Docker Registry V2接口访问Harbor,用户依旧可以通过Harbor管理镜像,并通过Kraken分发镜像。
在上所示的方案中,Harbor和Kraken共享Registry服务,镜像数据只会在Registry中保存一份。通过Kraken的镜像预热功能,可以让镜像在推送到Harbor后,就在Kraken中缓存一份,用户可以设置Kraken缓存的大小和过期策略。
在P2P分发系统中,当开始分发一个文件时,P2P分发系统首先需要生成这个文件的种子文件(Torrent文件),在种子文件中包含了文件的基本信息、文件的分片信息、Tracker服务器(P2P中心服务)的地址等。
当P2P网络的节点需要下载文件时,会先获取对应文件的种子文件,然后从P2P中心服务上获取每个分片可下载节点的信息,再按照分片去不同的节点上下载,在全部分片文件都下载完成之后再拼装成一个完整的文件。具体的实现在不同的P2P分发系统中是不一样的,但核心机制都一样。
就Kraken而言,当Kraken系统中没有文件缓存而有节点需要下载这个文件时,Kraken会首先从后端存储中取出这个文件,然后计算文件的种子信息,再进行分片分发。
在生成种子文件时需要先下载文件,这属于比较耗时的环节,Kraken为了省去下载文件的时间,设计了镜像的预热系统,用户可以通过Kraken提供的接口告知Kraken即将需要分发的镜像,Kraken会预先将对应的镜像从后端存储中下载下来,并计算好种子文件等待分发,这大大缩短了镜像分发的时长。
2.5 Kraken的预热流程
Kraken的预热方案是基于Registry的通知机制实现的,如图1-2所示,触发的流程如下。
(1)用户向Harbor端推送镜像。
(2)Registry触发通知机制,向Kraken-proxy发送通知请求。
(3)Kraken-proxy解析收到的请求,在这个请求中包含了推送镜像的所有信息。
(4)Kraken-proxy向Kraken-origin请求获取镜像对应的Manifest文件。
(5)Kraken-proxy解析Manifest文件,获取镜像所有的层文件信息。
(6)Kraken-proxy会逐个请求Kraken-origin下载每个层文件。
(7)Kraken-origin从Registry下载层文件时,会先将层文件都缓存在本地,计算出每个层文件的种子信息。
Kraken 的预热方案会导致所有镜像都被缓存到Kraken-origin中,从而导致Kraken-origin的磁盘吞吐量和占用都较高。为了避免这个问题,通常建议将测试和生产镜像仓库分离,使用两个Harbor,其中测试仓库独立使用,生产环境集成Kraken使用P2P分发,在两个仓库之间通过Harbor的远程复制功能实现镜像同步。
因为通常只有在测试环境下验证通过的镜像才会被发布到生产环境下的 Harbor 中,所以大大减少了生产仓库的压力,也能减少 Kraken 系统中缓存镜像的数量;将测试和生产环境分离时,可以将角色权限划分清楚,实现多方协作。
Harbor在未来的版本规划中设计了基于策略的预热功能,可以根据设置的策略将匹配的镜像预热到Kraken中,这是解决问题的最好方案。
Complain that it is better to walk in the dark than to carry a lamp.