我正在寻找优化奇异HPC容器构建时间的方法。我知道我可以通过一层一层地构建它们来节省一些时间。但是,仍然有优化的空间。
我感兴趣的是在主机系统上使用/缓存任何有意义的东西。
- 用于C++构建工件缓存的CCache
- git-reo克隆
- APT软件包下载
我做了一些实验,但在任何方面都没有成功。
到目前为止我发现了什么:
CCache
我在容器中安装了ccache,并指示构建系统使用它。我知道,因为我使用sudo运行singularity build
,所以缓存将在/root
下。但是在运行构建之后,/root/.ccache
为空。我验证了生成的CMake构建文件,它们肯定使用了ccache。
我甚至创建了一个包含%post
的测试配方
touch "$HOME/.ccache/test"
但测试文件没有出现在主机系统上的任何位置(不在/root
中,也不在我的用户家中)。构建步骤是否将容器支持的目录装载到/root
,而不是主机的根目录?
是否需要做更多的工作来利用ccache?
Git
人们建议运行例如git-cachehttp服务器(https://stackoverflow.com/a/43643622/1076564)并使用CCD_ 7。
由于奇点可以读取主机文件系统的一部分,我认为甚至有一种方法可以让它在没有代理程序的情况下工作。然而,如果主机git-reos不在$HOME
或/tmp
内,奇点如何在构建过程中访问它们?singularity build
没有用于指定其他装载目录的--bind
标志。在配方中使用%files
部分听起来效率很低——每次运行构建时都要复制所有内容。
APT
人们建议使用例如squid deb代理(https://gist.github.com/dergachev/8441335)。同样,由于奇点能够读取主机文件系统文件,我只想利用主机的/var/cache/apt
。但默认情况下,/var
不会安装到容器中。因此,同样的问题再次出现——如何在容器构建期间装载/var/cache/apt
。总的来说,这是个好主意吗?考虑到主机和容器都基于相同版本的Ubuntu和体系结构,这不会损坏主机的APT缓存吗?
或者奇点本身做了一些聪明的APT缓存吗?我刚刚注意到它在25秒内下载了420MB的包,这在我的连接上是可能的,但考虑到ubuntu镜像的标准速度,这不太可能。
编辑:我创建了一个关于奇异回购的问题:https://github.com/hpcng/singularity/issues/5352。
据我所知,在从定义文件构建时,没有缓存奇点构建的机制。你可以缓存基本图像的下载,但仅此而已
关于这一点,GitHub有一个问题,奇点的一位主要开发者给出了以下回复:
您可以从磁盘上现有的容器构建一个奇点容器。因此,您可以构建基本容器并保存它,然后修改def文件以从现有容器构建,从而在原型时节省时间。
但由于Singularity并没有创建层,因此实际上没有办法像Docker那样实现这一点。
关于您的问题的一点:
我知道我可以通过逐层构建来节省一些时间
奇点没有层的概念,所以这在这里不适用。Docker使用层,并且这些层是缓存的。
构建奇点图像时,我通常遵循的工作流程是首先从Dockerfile创建Docker图像,然后将其转换为奇点图像。Docker构建步骤具有缓存,因此这可能对您有用。
# Build Docker image
docker build --tag my_image:latest .
# Convert to Singularity format
sudo singularity build my_image.sif docker-daemon://my_image:latest
这听起来像是不必要的优化。如前所述,您可以从Docker镜像构建,该镜像可以利用一些层缓存。如果你计划进行大量迭代,你可以对一个基本的docker容器进行迭代,也可以将奇点映像创建为沙盒,并在它按你喜欢的方式工作后将其写入只读SIF。如果你经常更改代码,你可以在运行映像时装入源,直到它最终确定。
Singularity在主机操作系统上进行一些缓存,默认为$HOME/.singularity/cache
(通常在/root
中,因为大多数时候它是sudo singularity build ...
)。您可以使用singularity --verbose
或singularity --debug
查看更多详细信息。我相信这主要是为了缓存其他格式的图像/层,但我还没有深入研究
据我所知,Building不装载主机文件系统,也无法这样做。这是为再现性而设计的。可以将文件(例如,apt缓存)复制到%files
块中的图像中,但这似乎非常棘手,最终值得怀疑的是,它是否会更快,同时为一些奇怪的错误打开了可能性。
%post
步骤是在容器中隔离构建的,并且没有装载任何内容,因此它将无法利用主机操作系统上的任何缓存。
它表明有一种方法可以利用主机上的一些缓存。正如一位奇点开发人员所说,主机的/tmp
是在%post
构建阶段安装的。并且不可能装载任何其他目录。
因此,利用主机的缓存就是要使数据能够从/tmp
访问。
CCache
在运行build命令之前,将ccache目录装入/tmp
:
sudo mkdir /tmp/ccache
sudo mount --bind /root/.ccache /tmp/ccache
然后在食谱的%post
中添加以下行,就完成了:
export CCACHE_DIR=/tmp/ccache
我不确定与用户共享缓存(而不是root
)的工作方式,但我认为共享缓存的文档可能会有所帮助(尤其是为ccache设置umask
)。
APT
在主机上,绑定apt缓存目录:
sudo mkdir /tmp/apt
sudo mount --bind /var/cache/apt /tmp/apt
在%setup
或%post
中,创建包含以下内容的容器文件/etc/apt/apt.conf.d/singularity-cache.conf
:
Dir{Cache /tmp/apt}
Dir::Cache /tmp/apt;
Git
git-cache-http-server
应该无缝工作——主机端口应该在构建期间可以访问。我只是最后没有使用它,因为它不支持SSH身份验证。另一种方法是手动将所有repo克隆到/tmp
,然后在构建过程中使用--reference
标志进行克隆,这将加快克隆速度。