使用BuildKit生成图像

预计阅读时间:9分钟

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

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

  • 可以将使用BuildKit创建的Docker映像推送到Docker Hub,就像使用旧版构建的Docker映像一样
  • 适用于旧版构建的Dockerfile格式也将与BuildKit构建一起使用
  • 新的--secret命令行选项允许用户传递秘密信息,以使用指定的Dockerfile构建新映像

有关构建选项的更多信息,请参阅命令行构建选项Dockerfile参考页面上的参考指南 。

要求

  • 当前版本的Docker(18.09或更高版本)
  • 下载自定义前端的图像所需的网络连接

局限性

  • 仅支持构建Linux容器

启用BuildKit构建

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

$ DOCKER_BUILDKIT=1 docker build .

要在默认情况下启用Docker BuildKit,请将/etc/docker/daemon.jsonfeature中的守护程序配置设置 为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.2

本页上的示例使用docker/dockerfile 1.2.0及更高版本中可用的功能。我们建议您使用docker/dockerfile:1,它始终指向版本1语法的最新版本。BuildKit会在构建之前自动检查语法更新,以确保您使用的是最新版本。syntaxDockerfile参考中了解有关指令的 更多信息。

新的Docker Build机密信息

--secret用于docker build的新标志允许用户以安全的方式传递将在Dockerfile中使用的秘密信息,以构建docker映像,而最终不会存储在最终映像中。

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

dst在DockerfileRUN命令中将机密文件重命名为特定文件以使用。

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

$ echo 'WARMACHINEROX' > mysecret.txt

通过指定使用BuildKit前端的Dockerfile docker/dockerfile:1.2,可以在执行以下操作时访问秘密RUN

# syntax=docker/dockerfile:1.2

FROM alpine

# shows secret from default secret location:
RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecret

# shows secret from custom secret location:
RUN --mount=type=secret,id=mysecret,dst=/foobar cat /foobar

机密需要使用--secret标志传递给构建。该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中的构建机密和SSH转发以 获取更多信息和示例。

docker build有一个--ssh选项,允许多克尔引擎进行转发SSH代理连接。有关SSH代理的更多信息,请参见 OpenSSH手册页

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

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

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

# syntax=docker/dockerfile:1
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 .

您可能需要先运行ssh-add将私钥身份添加到身份验证代理,然后才能运行。

故障排除:私人注册表的问题

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证书。参见/ registry / deploying /

在Sonatype Nexus版本<3.15上运行专用注册表时找不到图像

如果您正在使用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

您可能遇到以下错误:NEXUS-12684

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

构建安全引擎机密BuildKit