构建可溯源的docker镜像
问题
在我司目前的开发迭代过程中,docker镜像作为开发同学的最终产物,其生命周期中存在多个环节多个环境的流转:从镜像构建开始,到开发环境更新验证,再到组内交付制品生成,然后来到测试环境,经过测试验证后,最终还会有生产环境交付。在这一长串的流转过程中,镜像作为流转物,只要中间的一个流程出现失误,很容易导致docker镜像的更新出现问题。这一问题在项目初期流程不够完善不够严谨、存在人工操作时更容易出现。
一方面,虽然通过镜像的tag设计可以让镜像有一定的辨识度,但是tag由于容易修改,在流转过程中不能保证在所有环节的强一致性;另一方面,镜像的id虽然可以像人类的身份证一样作为辨识身份的特征,但是可读性较差,使用起来便携程度不高。
这时,如果可以从镜像中直接获取关于其中代码的详细信息,将大大提高问题定位排查的效率。
元数据注入
为了解决以上的问题,可以基于dockerfile的ARG和LABEL指令,在dockerfile构建镜像时为镜像动态注入构建时的信息:比如和代码版本相关的分支、commit id等。除此之外,还可以注入一些和项目相关的静态信息,方便筛选。截取的部分dockerfile如下:
ARG branch=""
ARG commit=""
ARG build_time=""
LABEL vendor="某司"
LABEL project="某项目"
LABEL title="某微服务"
LABEL source="${branch}"
LABEL revision="${commit}"
LABEL created="${build_time}"
接下来在build镜像时,通过--build-arg传入需要动态注入的信息,比如分支、commit id等
docker build -t imageTag . --build-arg=branch=someBranch --build-arg=commit=$(git rev-parse --short HEAD)
注意:在多阶段构建的dockerfile中,ARG LABEL需要放到最终产物所在阶段的部分。
label相关规约
dockerfile中的label如何确定,一方面可参考标准化规范(label-schema已被废弃,可参考open container的规范)里的建议label,另一方面可以结合项目需求,加入其他常用到的label。
元数据应用
- 镜像溯源:每个镜像对应的代码分支,commit ID可轻易获得,方便问题排查时确认。
- 查看某镜像的所有标签:
docker inspect $image | grep -i labels -C 6
,此处的6是上下文行数,可以根据标签数量适当调整该数值。
- 查看某镜像的所有标签:
- 快速筛选过滤镜像:比如迅速筛选出本公司、本团队、本项目的所有镜像。
docker images --filter "label=$key"
docker images --filter "label=$key=$value"
参考
Let’s make your Docker Image better than 90% of existing ones
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。