镜像仓库保存了所有容器的启动镜像,当面对大规模容器集群(1000 节点)时,由于所有的镜像都需要从镜像仓库下载,镜像仓库往往会成为性能的瓶颈,几年前,在笔者之前的工作环境中曾经遇到一次生产环境扩容2000个副本的场景,结果用了2个多小时才完成,等到扩容完成,业务的高峰期已经过去了。

临时的解决方案是通过部署多个镜像仓库,然后通过划分区域,将一部分主机节点使用的镜像源指定到特定的镜像仓库(修改域名解析),从而分摊流量,并将两个镜像仓库做同步,保持两个镜像仓库数据一致。

k8s 上线时间(k8s朋友圈五Dragonfly)(1)

这种方案能够很好解决中型的容器集群,但如果是大规模集群,就需要维护很多套镜像仓库。而且需要配置很多主机的域名解析,维护主机和域名解析的关系,很不灵活。多个镜像仓库之间还需要保持数据的一致性,这些都需要花费很多的运维成本。那么有没有一种更加快速高效的镜像分发技术呢?想必每个人都用过迅雷或者电驴之类的P2P下载技术,它的本质原理就是通过将每个下载节点也作为数据的服务节点,提供下载文件的能力,从而快速的分发文件,避免单点瓶颈。在这个技术背景下,开源社区有两个相对成熟的项目,阿里的Dragonfly(蜻蜓)以及Uber的Kraken(海怪)。

Dragonfly 是一款基于 P2P 的智能镜像和文件分发工具。借助P2P分发技术提高文件传输的效率和速率,最大限度地利用网络带宽,尤其是在分发大量数据时,例如应用分发、缓存分发、日志分发和镜像分发。

Dragonfly 是一种无侵入式的解决方案,并不需要修改Docker的源代码。下图展现了Dragonfly整个架构图,在每个节点上面会启动一个dfdaemon和dfget,dfdaemon是一个代理程序,它会截获dockerd上传或者下载镜像的请求,dfget是一个下载客户端工具,每个dfget启动后首先通过“/peer/registry”接口将自己注册到supernode。supernode超级节点以被动CDN的方式产生种子数据块并调度数据块分布。

k8s 上线时间(k8s朋友圈五Dragonfly)(2)

当dockerd拉取镜像分层的时候,dfdaemon通过dfget请求supernode下载数据,supernode会从最终的镜像仓库拉取镜像分割成多个数据块。dfdaemon下载数据块并对外共享数据块,后续如果有其它节点也需要下载该镜像,那么会直接从之前的节点的节点下载,避免将所以请求都转发到镜像仓库。

,