问题

在我司目前的开发迭代过程中,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。

元数据应用

  1. 镜像溯源:每个镜像对应的代码分支,commit ID可轻易获得,方便问题排查时确认。
    • 查看某镜像的所有标签:docker inspect $image | grep -i labels -C 6,此处的6是上下文行数,可以根据标签数量适当调整该数值。
  2. 快速筛选过滤镜像:比如迅速筛选出本公司、本团队、本项目的所有镜像。
    • docker images --filter "label=$key"
    • docker images --filter "label=$key=$value"

参考

Let’s make your Docker Image better than 90% of existing ones

label规范-已废弃

opencontainers规范

docker中 arg 和 env 的区别

docker-docs-label

文章目录