你先在正在做一个新的基于容器的项目。你几乎要完成了,现在你想要编译你的docker image并将其公开发布。 底层操作系统是linux, 然后你的工具打包入其中,最后获得了一个80Mb的包,你打上latest的tag并将其推到公共的Docker Hub。
很快,人们开始基于你的工具开始他们的工作。很酷吧。然后你解决了一些小问题,然后重新编译你的包,再次打上latest的tag并推到公共的Docker Hub。
但是这次,工具本身的工作方式发生了改变,现在的输出,文档和手册的工作方式都和以前不同。但是你又不能发布一个新的版本,因为这些改变不够重要。
你可以在你的Docker Hub界面提到latest的commit ID,但是很快就会变的特别麻烦,每个小不定都发布补丁版本更是如此。另外,这个image本身并不包含tool的任何信息。
解决以上问题的一个方法是我们可以将commit ID作为metadata包含到Docker Image本身。
试想这个场景,你想把包的内部包含证书信息,而不是存在于包的外部的文档或者博客的位置,所有可以检查这个包的工具,都可以根据它们的需求去确定其是否合适。
或者另外一个场景,当我们需要Docker image中内置无论人和机器都可读的metadata。
这就是Docker的LABEL扮演的角色。Docker的Labels允许你为Docker对象指定metadata,例如Images, containers, volumes等。
我们对如何对Docker images使用Labels非常感兴趣。
对一个docker image指定label非常简单,使用以下指令:
LABEL =""
LABEL
指令会添加元数据到镜像。LABEL
是以键值对形式出现的。为了在LABEL
的值里面可以包含空格,你可以在命令行解析中使用引号和反斜杠
我们也可以定义一组labels去展示作者,编译日期等,如下:
FROM openjdk:jre-alpine
LABEL maintainer="[email protected]"LABEL build_date="2017-09-05"
COPY tool.tar.gz /mnt
WORKDIR /mnt
RUN tar zxvf /mnt/tool.tar.gzCMD ["/mnt/tool/tool.sh"]
这个包编译完成后,docker inspect就可以提取出我们在编译时嵌入的LABEL的信息。
那么我们该如何label我们的包呢?
Labels允许我们指定metadata,它也只能干这事。接下来,我们会展示一组第三方工具可以在Image中的查看到的标准的Labels。
庆幸的是,label-schema已经作了这些。label-schema是Docker build time的一个标准的命名空间,代表了在可值入Docker Image的绝大多数的metadata。其包括:
- build-date
- name
- description
- url
- vcs-ref
- docker.cmd
每一个label都必须有org.label-schema的前缀,另一个必须有的label是org.label-schema.schema-version
,其值应该是1.0。想要获取commit ID,使用vcs-ref。基于相同的目的,你也可以使用build-date,如果你想获取timestamps,则可如下:
LABEL org.label-schema.build-date="2017-08-28T09:24:41Z"
我们也可以通过Bash生成date timestamp,如下:
date -u +'%Y-%m-%dT%H:%M:%SZ'
和Docker build ARGs一起使用,则build script可以将当前的current build time传入到dockerfile中。
ARG BUILD_DATELABEL org.label-schema.build-date=$BUILD_DATE
COPY tool.tar.gz /mnt
WORKDIR /mnt
RUN tar zxvf /mnt/tool.tar.gzCMD ["/mnt/tool/tool.sh"]
则我们可以使用以下命令,传入BUILD_DATA参数:
docker build --no-cache=true --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') -t mytool:latest .
Label你的images, 让你的image独一无二
除了我们写的以上的那些点,我们写label就像我们在READM.md文件中写How-To手册,然后在GitHub Wiki中完成手册。我们应该尽可能多的在我们的docker image中值入更多的metadata, 这样的会让我们的docker image变的更透明,更好。
让我们展示一个模版:
FROM openjdk:jre-alpine
LABEL maintainer="[email protected]"
# Ballerina runtime distribution filename.
ARG BALLERINA_DIST
ARG BUILD_DATE
ARG VCS_REF
ARG BUILD_VERSION
# Labels.
LABEL org.label-schema.schema-version="1.0"
LABEL org.label-schema.build-date=$BUILD_DATE
LABEL org.label-schema.name="ballerinalang/ballerina"
LABEL org.label-schema.description="Ballerina language runtime"
LABEL org.label-schema.url="http://ballerinalang.org/"
LABEL org.label-schema.vcs-url="https://github.com/ballerinalang/container-support"
LABEL org.label-schema.vcs-ref=$VCS_REF
LABEL org.label-schema.vendor="WSO2"
LABEL org.label-schema.version=$BUILD_VERSION
LABEL org.label-schema.docker.cmd="docker run -v ~/ballerina/packages:/ballerina/files -p 9090:9090 -d ballerinalang/ballerina"