2024突然新增了几个PoC,需要在客户现场私有化部署(我的快速部署方案成了不二之选)。但是客户现场情况复杂:
客户所提供部署用主机为内网机器,不允许访问公网;
客户只提供一个跳板机可供我们远程连接;
跳板机可访问公网;
历史做法
使用seafile
Seafile 是一款开源的企业云盘,注重可靠性和性能。支持 Windows, Mac, Linux, iOS, Android 平台。支持文件同步或者直接挂载到本地访问。
PoC所需要的容器镜像加起来有50G左右,这里以nginx镜像为例:
docker save nginx -o nginx.tar
将
nginx.tar
上传到seafile上远程连接到客户的跳板机,从seafile上下载nginx.tar包
解压并上传镜像到客户的镜像中心
docker load -i nginx.tar docker tag nginx yourharbor.com/dev/nginx docker push theharbor.com/dev/nginx
问题
因为网速的原因,光是上传下载tar包,就相当费时间,整个过程相当地不友好,这种低效会让人非常难受,得想想办法了。
分析确定的现状:
不能用公网的镜像中心
只能用seafile
解决办法
压缩
在这种情况下只能想办法减少镜像包大小, 我最先想到是使用高压缩比,比如xz
xz使用LZMA算法进行压缩,压缩率可以达到gzip的2~3倍,是目前Linux系统中压缩率最高的压缩程序。但压缩速度非常慢。xz压缩文件的扩展名为.xz
nginx.tar: 271M
压缩后
tar -cJf nginx.tar.xz nginx.tar
nginx.tar.xz: 64M,压缩体积相当出色
tar -cJf nginx.tar.xz nginx.tar 118.46s user 1.92s system 95% cpu 2:06.01 total
tar -xf nginx.tar.xz 5.00s user 0.22s system 94% cpu 5.499 total
正如前面提到xz的缺点,压缩需2min左右,解压超过5s,但,高压缩比带来收益还是很可观的,从271M->64M,网速相对稳定的情况下,数据从seafile上传时间减少到原先的1/4,不能不说很优秀了。但是,xz对于大文件压缩时间感人,略加测试后,所以果断弃坑。那,还有没有其它的办法呢?
终极大招
前面提到nginx.tar文件大小为271M,但是使用docker images查看镜像大小为141M
nginx latest 605c77e624dd 2 years ago 141MB
而在Harbor上看到的大小为仅为54.09M
而已,这个体积甚至低于nginx.tar.xz的64M,这已经不能用优秀来形容了,but why?
harbor上显示的是压缩后的镜像体积;
docker images看到的是镜像下载到本地后展开的体积(可以试着下载一个大一点的镜像,可以观察到
Downloading
、Extracting
)过程,可以印证这一点。docker save: 因为docker镜像采用的是分层存储方式,每一层只存储与上一层的差异内容。save命令将整个镜像一起保存,导致重复内容也会被重复保存,增加了文件的大小; save命令保存的是完整可运行的镜像,包含所有的所有历史版本、元数据、环境变量和配置
经过以上分析可知,docker镜像中心对镜像的存储优化已经做到极致了(仅限于笔者的认知),所以解决方案也就呼之欲出了: 使用镜像中心 harbor? 必须是registry
Distribution implementation for storing and distributing of container images and artifacts
当然不是,轻量级本地registry即可,将镜像数据挂载到本地的 image_data 目录
docker run -d -p 12345:5000 --restart=always --name registry \
-v `pwd`/image_data:/var/lib/registry \
registry:2
registry体积小,占用资源少,在这个场景下无疑是比harbor更好的选择
重新打tag
docker tag nginx localhost:12345/dev/nginx
推送
docker push localhost:12345/dev/nginx
看一下image_data目录大小
55M image_data
xz压缩后的体积
53M image_data.tar.xz
压缩后仅减少了2M,足以可见docker对容器镜像存储的压缩技术有多优秀了。所以,xz级别的压缩就显得没那么必要了,普通tar包即可
54M image_data.tar
将 image_data.tar 上传到seafile,客户现场启用本地registry,剩下就是一些体力活了,如果客户使用的是harbor,还可以直接使用harbor的复制管理功能,稍加配置即可完成镜像从本地registry到客户的harbor这一步,好了,打完收工。
总结
念念不忘,必有回响。对于低效的不满是因,想到registry是灵光一现,也是果。高压缩比方式是最容易想到的,但是细细整理下来,才发现docker生态对于镜像存储优化下了很大功夫,实在是让人佩服。这让我想起2020年还在网银时,当时老大亮哥给我分一任务,好像是梳理镜像下载的瓶颈,现在我只记得当时使用了sisdig各种工具测试,最后得出的结论是网络是瓶颈,但是后来又发现本地解压也很费时间,CPU为陡然变高,很可惜当时没有将过程记录下来,还是要多写哇。然后本篇我也是先做完再梳理的,也会有新的收获,最重要的是将数据对比记录并展现出来了。感叹当年Solomon Hykes做docker的魄力,也对“docker”背后公司现在的处境不胜唏嘘,最后祝愿Solomon Hykes 的新项目Dagger越来越好。
参考: