线上 dockerd 版本: Docker version 19.03.12, build 48a66213fe

实验使用的 dockerd 版本:v20.10.9

目的

为了加速容器的启动,docker pull 做为其中的一环,调研一下如何加速 docker pull。

局域网环境问题下,docker pull 里面的解压的时间占了大头。Lz4 的解压速度比当前 Docker 默认的 gzip 要快不少,我们就在 Docker 里面实际测下看效果。

准备 dockerd 编译环境

dockered 项目现在是在 https://github.com/moby/moby,我没有找到如何编译,自己瞎试,始终过不去依赖这个坎。

后来老板给了一个说明文档,才照着搞定了。

不过还是觉得这个依赖环境有点奇怪,不是现在的 go mod 风格,还要把 moby 文件夹映射到 docker/docker 下面。总觉得不太方便。

效果

对一个 1.4G 的文件夹做压缩(是整个Centos系统的 Overlay2 目录)

root@VMS137224 /tmp/t $ time lz4 a.tar
Compressed filename will be : a.tar.lz4
Compressed 1405716538 bytes into 832821557 bytes ==> 59.25%

real    0m4.276s
user    0m3.345s
sys     0m0.923s

root@VMS137224 /tmp/t $ time lz4 -9 a.tar
Compressed filename will be : a.tar.lz4
Compressed 1405716625 bytes into 739229817 bytes ==> 52.59%

real    0m58.333s
user    0m55.140s
sys     0m1.086s

root@VMS137224 /tmp/t $ time gzip a.tar

real    1m11.509s
user    1m9.879s
sys     0m1.271s

root@VMS137224 /tmp/t $ ll a.tar.gz
-rw-r--r-- 1 root root 676578535 Nov 15 11:31 a.tar.gz

解压:

root@VMS137224 /tmp/t $ time pigz -c -d a.tar.gz | tar xf -

real    0m7.363s
user    0m8.513s
sys     0m3.739s


root@VMS137224 /tmp/t $  time gunzip -c a.tar.gz | tar xf -

real    0m13.477s
user    0m12.601s
sys     0m3.276s



root@VMS137224 /tmp/t $ time lz4 -d -c a.tar.lz4 | tar -xf -

real    0m4.013s
user    0m1.619s
sys     0m3.276s

Lz4 的效果还是好很多的。省 CPU,省时间。

这里要说明一点的是,这个 Lz4 应该是 C 实现的吧,可能是因为这个,比我们后面 Docker 里面的 Golang 的实现要快。

docker pull 效果

pigz: 下载 5 秒,解压 10 秒。 lz4: 下载 6 秒,解压 9 秒,总时间持平。

看上面 pigz 解压的 real/usr/sys 时间,好像是使用了 2 核 ?反正不会把多核 的 CPU 打满就好了,否则可能会引起 throttle 吧。

结论

lz4 总的时间和 pigz 差不多。但 lz4 还是有更多好处,比如说它使用的 CPU 时间其实更少;另外使用更高压缩率的参数,830M 可以变成730M,可以省下一点时间和宽带(解压时间几乎不变)

但 zl4 没办法推广,因为 OCI Spec 里面写了,layer mediatype 还没有对 lz4 的支持,只能自己 Hack 玩一下。

对于如何启用 pigz,dockerd 19 是安装好 pigz 之后,重启 dockerd 就好了,重启初始化的时候会检查 pigz 是不是装了。
dockerd 20 是安装好 pigz 就行,不用重启了,它会运行时检查 pigz 是不是装好了,更优秀一些。

另外提一下,虽然 OCI Spec 里面还没有明确支持 lz4,但也没有明确说不行。 像 dockerd 就会自己检查 layer 是什么压缩格式,而不是看 mediatype 里面的定义(虽然这样不好。。。)

如果没有明确规定,允许实现自己检查压缩格式的话,那我们使用 lz4 压缩,然后使用 application/vnd.oci.image.config.v1+json 好像也行。但兼容性可能无法保证。