Docker良好实践&引用;“数据”;在卷与图像中
我目前有一个应用程序(为了简单起见)只需要一个Docker良好实践&引用;“数据”;在卷与图像中,docker,Docker,我目前有一个应用程序(为了简单起见)只需要一个.csv文件。但是,这个文件需要用脚本构建,我们称之为create_db.py 我有两个映像(我们称它们为API1和API2),它们需要.csv文件,因此我声明了一个两阶段构建,两个映像都将.csv复制到它们的文件系统中。这使得Dockerfile有些丑陋,因为API1和API2具有Dockerfile的相同的第一行,而且不能保证两个图像具有相同的.csv,因为它是“动态”构造的 对于这个问题,我有两种可能的解决方案: 第一种选择: 制作一个单独的
.csv
文件。但是,这个文件需要用脚本构建,我们称之为create_db.py
我有两个映像(我们称它们为API1和API2),它们需要.csv
文件,因此我声明了一个两阶段构建,两个映像都将.csv
复制到它们的文件系统中。这使得Dockerfile有些丑陋,因为API1和API2具有Dockerfile的相同的第一行,而且不能保证两个图像具有相同的.csv
,因为它是“动态”构造的
对于这个问题,我有两种可能的解决方案:
第一种选择:
- 制作一个单独的docker映像,执行
,然后将其标记为create_db.py
。复制API1和API2中的data:latest
.csv
data:latest
(并且是最新的)
优点:如果您在另一台机器中,则可以从存储库中提取数据,无需再次“重建”
缺点:每次构建API1和API2时,我都需要确保数据:最新的
是最新的。API1和API2需要使用数据:最新的
第二种选择:
- 创建一个卷
data/
和一个运行Create_db.py
的映像,并装入该卷,使.csv
位于data/
中。然后装入API1和API2的卷。我还需要某种机制来确保data/
包含所需的文件
在处理共享数据时,安装卷听起来是正确的选择,但在这种情况下,我不确定,因为我的数据需要“构建”才能使用。那么我应该选择第一个选项吗
选择的解决方案,感谢@David Maze
我最后做的是在自己的Docker映像中分离数据管道,然后在API1和API2中从该映像进行复制
为了确保API1和API2始终具有最新的“数据映像”版本,数据管道计算所有输出文件的哈希值,然后尝试执行docker pull data:
如果失败,则表示此版本的数据不在注册表中,并且数据映像被标记为数据:
和数据:最新的
,并推送到注册表。这保证了数据:latest
始终指向推送到注册表的最后一个数据,同时我可以跟踪所有数据:
版本如果大小可控,我更愿意将其烘焙到图像中。这样做有两个主要原因:它使docker能够在没有任何外部主机依赖的情况下运行映像,并且在共享文件可能有问题的集群环境(docker Swarm、Kubernetes)中工作得更好
您还可以对此进行另外两项更改,以改进建议的Dockerfile。您可以将正在使用的数据集的特定版本传递为ARG
,这将有助于您构建图像的两个副本并使它们具有相同的数据集。您还可以直接COPY--from=
复制图像,而无需将其声明为stage
FROM continuumio/miniconda3:4.7.12
ARG data_version=latest
COPY --from=data:${data_version} file.csv .
只有当数据文件非常大(千兆字节)时,我才会考虑卷方法。Docker图像在这种大小下开始变得笨拙,因此,如果您有一个定义良好的辅助数据集,您可以突破它,这将有助于更好地运行。另一个可行的方法是将数据文件存储在远程位置,如AWS S3存储桶,并在启动时下载(增加启动时间失败的风险,增加启动时间,但使映像能够自动启动)。我正在设想一个生成文件,它将构建“数据”映像和应用程序映像。是否有任何机制来检查数据是否已更改,并在这种情况下构建和标记图像,或者我需要编写代码?例如,使用md5哈希?回答得很好+1.关于@GonzaloHernandez的最新问题,您可能希望使用docker build--pull
选项,该选项“始终尝试从隐含docker注册表中提取较新版本的图像”(这适用于from…
和COPY--from=…
指令)。
FROM continuumio/miniconda3:4.7.12
ARG data_version=latest
COPY --from=data:${data_version} file.csv .