使用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.json
feature中的守护程序配置设置
为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会在构建之前自动检查语法更新,以确保您使用的是最新版本。syntax
在Dockerfile参考中了解有关指令的
更多信息。
新的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=ssh
mount明确请求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