首页 > 解决方案 > 如何正确 dockerize 并持续集成 20GB 原始数据?

问题描述

我有一个使用大约 20GB 原始数据的应用程序。原始数据由二进制文件组成。

这些文件很少(如果有的话)更改。只有在需要解决的文件中存在错误时才会发生更改。

处理这个问题的最简单方法是将文件放在它自己的 git 存储库中,并基于它创建一个基础映像。然后在原始数据图像之上构建应用程序。我没有尝试过为 CI 管道提供 20GB 的基本映像,而且似乎也不是处理这种情况的最佳方式。

我在这里的方法的主要原因是为了防止额外的部署复杂性。

是否有最佳实践、“正确”或更明智的方法来做到这一点?

标签: performancedockercontinuous-integration

解决方案


像这样巨大的、大部分是静态的数据块可能是我对“Docker 镜像应该是自包含”规则的一个大例外。我建议将这些数据保存在其他地方,并与核心docker run工作流程分开下载。

过去我在处理数千兆字节的图像时遇到过麻烦。尤其是像这样的操作docker pushdocker pull容易挂在第二个千兆字节的各个层上。如果,如您所说,这种静态内容很少更改,那么还有一个问题是将其放在线性层序列中的哪个位置。写类似的东西很诱人

FROM ubuntu:18.04
ADD really-big-content.tar.gz /data
...

但即使ubuntu:18.04映像会定期更改(它相当频繁地获得安全更新;您的 CI 管道应该明确地更新docker pull它),并且当它发生新构建时,必须再次传输整个未更改的 20 GB 块。

相反,我会将它们放在 AWS S3 存储桶或类似对象存储之类的地方。(这与源代码控制系统不匹配,它 (a) 希望永久保留旧内容,并且 (b) 倾向于针对文本而不是二进制文件进行优化。)。然后我会有一个在下载该内容的主机上运行的脚本,然后将相应的主机目录挂载到需要它的容器中。

curl -LO http://downloads.example.com/really-big-content.tar.gz
tar xzf really-big-content.tar.gz
docker run -v $PWD/really-big-content:/data ...

(在 Kubernetes 或其他分布式世界中,我可能需要编写一个专门的作业来将内容下载到持久卷中并作为我的集群启动的一部分运行。你可以在普通 Docker 中做同样的事情来下载内容到命名卷中。)


推荐阅读