18.09对Docker Build的增强

Docker Build增强

Docker Build是Docker引擎最常用的功能之一-开发人员,构建团队和发行团队等用户均使用Docker Build。

针对18.09版本的Docker Build增强引入了对构建架构的急需的全面检查。 通过集成BuildKit,用户可以看到性能,存储管理,功能和安全性方面的改进。

  • 可以将使用buildkit创建的Docker镜像推送到Docker Hub和DTR中,就像使用旧版生成的Docker镜像一样
  • 适用于旧版构建的Dockerfile格式也适用于使用buildkit构建
  • 新的--secret命令行选项允许用户传递机密信息,以使用指定的Dockerfile构建新镜像 有关构建选项的更多信息,请参见参考指南命令行上的构建选项

先决条件

  • 系统要求是docker-ce x86_64,ppc64le,s390x,aarch64,armhf; 或仅限docker-ee x86_64
  • 下载自定义前端的镜像所需的网络连接

局限性

  • 仅支持构建Linux容器
  • BuildKit模式与UCP 3.2或更高版本兼容
  • BuildKit模式与Swarm Classic不兼容

启用buildkit构建

新安装的docker启用的最简单方法是在调用docker build命令时设置DOCKER_BUILDKIT = 1环境变量,例如:

$ DOCKER_BUILDKIT=1 docker build .

要默认启用docker buildkit,请将/etc/docker/daemon.jsonfeatures中设置为true并重新启动后台程序:

{ "features": { "buildkit": true } }

新的Docker Build命令行构建输出

新的Docker构建BuildKit TTY输出(默认):

$ docker build . 
[+] Building 70.9s (34/59)                                                      
 => [runc 1/4] COPY hack/dockerfile/install/install.sh ./install.sh       14.0s
 => [frozen-images 3/4] RUN /download-frozen-image-v2.sh /build  buildpa  24.9s
 => [containerd 4/5] RUN PREFIX=/build/ ./install.sh containerd           37.1s
 => [tini 2/5] COPY hack/dockerfile/install/install.sh ./install.sh        4.9s
 => [vndr 2/4] COPY hack/dockerfile/install/vndr.installer ./              1.6s
 => [dockercli 2/4] COPY hack/dockerfile/install/dockercli.installer ./    5.9s
 => [proxy 2/4] COPY hack/dockerfile/install/proxy.installer ./           15.7s
 => [tomlv 2/4] COPY hack/dockerfile/install/tomlv.installer ./           12.4s
 => [gometalinter 2/4] COPY hack/dockerfile/install/gometalinter.install  25.5s
 => [vndr 3/4] RUN PREFIX=/build/ ./install.sh vndr                       33.2s
 => [tini 3/5] COPY hack/dockerfile/install/tini.installer ./              6.1s
 => [dockercli 3/4] RUN PREFIX=/build/ ./install.sh dockercli             18.0s
 => [runc 2/4] COPY hack/dockerfile/install/runc.installer ./              2.4s
 => [tini 4/5] RUN PREFIX=/build/ ./install.sh tini                       11.6s
 => [runc 3/4] RUN PREFIX=/build/ ./install.sh runc                       23.4s
 => [tomlv 3/4] RUN PREFIX=/build/ ./install.sh tomlv                      9.7s
 => [proxy 3/4] RUN PREFIX=/build/ ./install.sh proxy                     14.6s
 => [dev 2/23] RUN useradd --create-home --gid docker unprivilegeduser     5.1s
 => [gometalinter 3/4] RUN PREFIX=/build/ ./install.sh gometalinter        9.4s
 => [dev 3/23] RUN ln -sfv /go/src/github.com/docker/docker/.bashrc ~/.ba  4.3s
 => [dev 4/23] RUN echo source /usr/share/bash-completion/bash_completion  2.5s
 => [dev 5/23] RUN ln -s /usr/local/completion/bash/docker /etc/bash_comp  2.1s

新的Docker构建BuildKit普通输出:

$ docker build --progress=plain . 

#1 [internal] load .dockerignore
#1       digest: sha256:d0b5f1b2d994bfdacee98198b07119b61cf2442e548a41cf4cd6d0471a627414
#1         name: "[internal] load .dockerignore"
#1      started: 2018-08-31 19:07:09.246319297 +0000 UTC
#1    completed: 2018-08-31 19:07:09.246386115 +0000 UTC
#1     duration: 66.818μs
#1      started: 2018-08-31 19:07:09.246547272 +0000 UTC
#1    completed: 2018-08-31 19:07:09.260979324 +0000 UTC
#1     duration: 14.432052ms
#1 transferring context: 142B done


#2 [internal] load Dockerfile
#2       digest: sha256:2f10ef7338b6eebaf1b072752d0d936c3d38c4383476a3985824ff70398569fa
#2         name: "[internal] load Dockerfile"
#2      started: 2018-08-31 19:07:09.246331352 +0000 UTC
#2    completed: 2018-08-31 19:07:09.246386021 +0000 UTC
#2     duration: 54.669μs
#2      started: 2018-08-31 19:07:09.246720773 +0000 UTC
#2    completed: 2018-08-31 19:07:09.270231987 +0000 UTC
#2     duration: 23.511214ms
#2 transferring dockerfile: 9.26kB done

覆盖默认前端

如果您覆盖默认前端,则可以使用Dockerfile中的新语法特性。要覆盖默认的前端,请将Dockerfile的第一行设置为带有特定前端镜像的注释:

# syntax = <frontend image>, e.g. # syntax = docker/dockerfile:1.0-experimental

新的Docker Build机密信息

docker build的新--secret标记允许用户以安全的方式传递要在Dockerfile中使用的用于构建docker镜像的机密信息,这些信息最终不会存储在最终镜像中。

id是要在docker build --secret中传递的标识符。 此标识符与要在Dockerfile中使用的RUN --mount标识符相关联。 Docker不使用在Dockerfile外部保存机密的文件名,因为这可能是敏感信息。

dst将机密文件重命名为Dockerfile RUN命令中要使用的特定文件。

例如,将机密信息存储在文本文件中:

$ echo 'WARMACHINEROX' > mysecret.txt

并且使用指定buildkit前端docker/dockerfile:1.0-experimental的Dockerfile,可以访问该秘密。

例如:

# syntax = docker/dockerfile:1.0-experimental
FROM alpine
RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecret # shows secret from default secret location
RUN --mount=type=secret,id=mysecret,dst=/foobar cat /foobar # shows secret from custom secret location

该Dockerfile只是为了证明可以访问该机密。 如您所见,机密信息显示在构建输出中。 构建的最终镜像将没有机密文件:

$ docker build --no-cache --progress=plain --secret id=mysecret,src=mysecret.txt .
...
#8 [2/3] RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecret
#8       digest: sha256:5d8cbaeb66183993700828632bfbde246cae8feded11aad40e524f54ce7438d6
#8         name: "[2/3] RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecret"
#8      started: 2018-08-31 21:03:30.703550864 +0000 UTC
#8 1.081 WARMACHINEROX
#8    completed: 2018-08-31 21:03:32.051053831 +0000 UTC
#8     duration: 1.347502967s


#9 [3/3] RUN --mount=type=secret,id=mysecret,dst=/foobar cat /foobar
#9       digest: sha256:6c7ebda4599ec6acb40358017e51ccb4c5471dc434573b9b7188143757459efa
#9         name: "[3/3] RUN --mount=type=secret,id=mysecret,dst=/foobar cat /foobar"
#9      started: 2018-08-31 21:03:32.052880985 +0000 UTC
#9 1.216 WARMACHINEROX
#9    completed: 2018-08-31 21:03:33.523282118 +0000 UTC
#9     duration: 1.470401133s
...

使用SSH访问构建中的私有数据

*致谢:*有关更多信息和示例,请参阅Docker 18.09中的Build secret和SSH转发

docker build具有--ssh选项,以允许Docker Engine转发SSH代理连接。 有关SSH代理的更多信息,请参见OpenSSH手册

Dockerfile中只有通过定义type=ssh的mount明确要求SSH访问的,命令才能访问SSH代理连接。 其他命令不知道任何SSH代理可用。

Dockerfile中的RUN命令需要请求SSH访问,请定义ssh类型的mount。 这将设置SSH_AUTH_SOCK环境变量,以使依赖SSH的程序自动使用该套接字。

这是在容器中使用SSH的Dockerfile示例:

# syntax=docker/dockerfile:experimental
FROM alpine

# Install ssh client and git
RUN apk add --no-cache openssh-client git

# Download public key for github.com
RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts

# Clone private repository
RUN --mount=type=ssh git clone git@github.com:myorg/myproject.git myproject

创建Dockerfile后,请使用--ssh选项与SSH代理进行连接。

$ docker build --ssh default .

故障排除:私有注册中心的问题

X509:未知授权机构签署的证书

如果您要从不安全的注册中心获取镜像(使用自签名证书)和/或将此类注册中心用作镜像,那么您将面临Docker 18.09中的一个已知问题:

[+] Building 0.4s (3/3) FINISHED
 => [internal] load build definition from Dockerfile
 => => transferring dockerfile: 169B
 => [internal] load .dockerignore
 => => transferring context: 2B
 => ERROR resolve image config for docker.io/docker/dockerfile:experimental
------
 > resolve image config for docker.io/docker/dockerfile:experimental:
------
failed to do request: Head https://repo.mycompany.com/v2/docker/dockerfile/manifests/experimental: x509: certificate signed by unknown authority

解决方案:正确保护注册中心。 您可以免费从Let's Encrypt获取SSL证书。 参见https://docs.docker.com/registry/deploying/

私有注册中心在SONATYPE NEXUS版本<3.15上运行时,未找到镜像

------
 > [internal] load metadata for docker.io/library/maven:3.5.3-alpine:
------
------
 > [1/4] FROM docker.io/library/maven:3.5.3-alpine:
------
rpc error: code = Unknown desc = docker.io/library/maven:3.5.3-alpine not found

您可能会遇到以下错误:https://issues.sonatype.org/browse/NEXUS-12684

解决方案是将Nexus升级到3.15或更高版本。