3个版本
0.2.2 | 2021年2月16日 |
---|---|
0.2.1 | 2020年3月14日 |
0.2.0 | 2020年3月8日 |
#931 在 开发工具 中
21KB
233 行
基于源码的确定性Docker镜像校验和
使用案例
您有一个CI管道,该管道构建一个包含许多Dockerfile的单仓。
您希望有效地避免重建没有变化的Dockerfile,即使单仓的其他部分已经更改。
docker-source-checksum
将计算
Dockerfile
内容的哈希值- 该
Dockerfile
中引用的所有源文件(通过解析得出) - 可能影响构建的任何额外参数
然后将这些内容一起哈希,在尝试调用docker build
之前,为您提供确定性校验和。您可以用它作为基于内容的确定性ID来避免重建已经构建的容器(例如,通过使用该校验和进行标记)。
在您的CI管道中使用
假设,通常您的CI管道会做类似的事情。
docker build -f someproject/Dockerfile .
这种方法存在一些问题
- 将所有文件发送到docker守护进程需要一些时间。这部分本身可能需要相当长的时间,即使在没有需要重建的情况下,容器镜像已经缓存在本地上,这种情况也不例外。
- 如果在某些不同的机器上已经完成了完全相同的构建,那么在这个机器上不会重用,除非您已经设置了一些更智能的系统来共享它们。
- 您需要等待
docker build
完成以获取构建的唯一ID。
使用DSC,您会
BUILD_FULL_ID=$(docker-source-checksum -f someproject/Dockerfile .)
BUILD_ID=${BUILD_FULL_ID:0:8} # take just first 8 characters
TAG_NAME=my-docker-repository.com/$PACKAGE_NAME:$BUILD_ID
并且在不到一秒钟的时间内,即使对于大型项目,您也会得到构建的确定性加密ID(在此之前,您甚至还没有尝试构建任何内容)。此时,您可能可以尝试性地启动CI的一部分,使用已经知道的docker镜像url。
您的CI脚本的其他部分可以快速检查是否已经存在此确切的构建
if DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect $TAG_NAME > /dev/null; then
echo "$TAG_NAME already built. Skipping build and push"
exit 0
fi
(或者如果您想将其缓存在本地上,也可以使用docker pull
)。
并且只有在它从未构建过的情况下,您才会本地构建并将其推送到您的注册表
docker build -t $TAG_NAME -f someproject/Dockerfile .
docker push $TAG_NAME
警告和缺失功能
- 不要在不受信任的
Dockerfiles
上使用它 - 确切的校验和尚不稳定,可能在版本之间发生变化
- 变量扩展不会执行,因此
ADD
和COPY
中的源路径内的变量将无法工作。 ["src1", "src", "dst"]
的ADD
和COPY
语法不受支持(欢迎提出问题)- 忽略文件所有权
- 它是用2个小时拼凑起来的,所以如果你打算在生产中使用它,也许...审查一下代码,或者告诉我你的想法
话虽如此,似乎工作得很好。
安装
查看 docker-source-checksum 发布版,或者使用 cargo install docker-source-checksum
。
使用
与 docker build
类似
$ docker-source-checksum --help
docker-source-checksum 0.2.0
Dockerfile source checksum
USAGE:
docker-source-checksum [FLAGS] [OPTIONS] <context-path>
FLAGS:
-h, --help Prints help information
--hex Output hash in hex
-V, --version Prints version information
OPTIONS:
--extra-path <extra-path>... Path relative to context to include in the checksum
--extra-string <extra-string>... String (like arguments to dockerfile) to include in the checksum
-f, --file <file> Path to `Dockerfile`
--ignore-path <ignore-path>... Path relative to context to ignore in the checksum
ARGS:
<context-path> Dockerfile build context path
依赖
约3–11MB
约110K SLoC