构建密钥
构建密钥是任何敏感信息片段,例如密码或API令牌,作为应用程序构建过程的一部分使用。
构建参数和环境变量不适合将密钥传递到您的构建中,因为它们会保留在最终镜像中。相反,您应该使用密钥挂载或SSH挂载,它们可以安全地将密钥公开给您的构建。
构建密钥的类型
- 密钥挂载是用于将密钥传递到构建中的通用挂载。密钥挂载从构建客户端获取密钥,并在构建指令期间将其暂时提供给构建容器。例如,如果您的构建需要与私有工件服务器或API通信,这将非常有用。
- SSH 挂载是用于在构建中提供 SSH 套接字或密钥的专用挂载。当您需要在构建中获取私有 Git 存储库时,它们通常会用到。
- 远程上下文的 Git 身份验证是一组预定义的密钥,用于使用远程 Git 上下文(也是私有存储库)进行构建。这些密钥是“预检”密钥:它们不会在构建指令中使用,但它们用于为构建器提供必要的凭据以获取上下文。
使用构建密钥
对于密钥挂载和 SSH 挂载,使用构建密钥是一个两步过程。首先,您需要将密钥传递到docker build
命令,然后您需要在 Dockerfile 中使用该密钥。
要将密钥传递到构建,请使用docker build --secret
标志,或Bake 的等效选项。
$ docker build --secret id=aws,src=$HOME/.aws/credentials .
variable "HOME" {
default = null
}
target "default" {
secret = [
"id=aws,src=${HOME}/.aws/credentials"
]
}
要在构建中使用密钥并使其可访问RUN
指令,请在 Dockerfile 中使用--mount=type=secret
标志。
RUN --mount=type=secret,id=aws \
AWS_SHARED_CREDENTIALS_FILE=/run/secrets/aws \
aws s3 cp ...
密钥挂载
密钥挂载将密钥作为文件或环境变量公开给构建容器。您可以使用密钥挂载将敏感信息(例如 API 令牌、密码或 SSH 密钥)传递到您的构建中。
来源
密钥的来源可以是文件或环境变量。当您使用 CLI 或 Bake 时,可以自动检测类型。您也可以使用type=file
或type=env
显式指定它。
以下示例将环境变量KUBECONFIG
挂载到密钥 ID kube
,作为构建容器中/run/secrets/kube
中的文件。
$ docker build --secret id=kube,env=KUBECONFIG .
当您使用环境变量中的密钥时,您可以省略env
参数以将密钥绑定到与变量同名的文件。在以下示例中,API_TOKEN
变量的值将挂载到构建容器中的/run/secrets/API_TOKEN
。
$ docker build --secret id=API_TOKEN .
目标
在 Dockerfile 中使用密钥时,密钥默认情况下会挂载到文件中。密钥在构建容器内的默认文件路径是/run/secrets/
。您可以使用 Dockerfile 中RUN --mount
标志的target
和env
选项自定义密钥在构建容器中的挂载方式。
以下示例获取密钥 ID aws
并将其挂载到构建容器中/run/secrets/aws
中的文件。
RUN --mount=type=secret,id=aws \
AWS_SHARED_CREDENTIALS_FILE=/run/secrets/aws \
aws s3 cp ...
要将密钥挂载到名称不同的文件,请在--mount
标志中使用target
选项。
RUN --mount=type=secret,id=aws,target=/root/.aws/credentials \
aws s3 cp ...
要将密钥挂载为环境变量而不是文件,请在--mount
标志中使用env
选项。
RUN --mount=type=secret,id=aws-key-id,env=AWS_ACCESS_KEY_ID \
--mount=type=secret,id=aws-secret-key,env=AWS_SECRET_ACCESS_KEY \
--mount=type=secret,id=aws-session-token,env=AWS_SESSION_TOKEN \
aws s3 cp ...
可以同时使用target
和env
选项将密钥同时挂载为文件和环境变量。
SSH 挂载
如果构建中要使用的凭据是SSH代理套接字或密钥,则可以使用SSH挂载而不是密钥挂载。克隆私有Git仓库是SSH挂载的常见用例。
以下示例使用Dockerfile SSH挂载克隆私有的GitHub仓库。
# syntax=docker/dockerfile:1
FROM alpine
ADD git@github.com:me/myprivaterepo.git /src/
要将SSH套接字传递给构建,可以使用docker build --ssh
标志,或Bake的等效选项。
$ docker buildx build --ssh default .
远程上下文的 Git 身份验证
BuildKit支持两个预定义的构建密钥,GIT_AUTH_TOKEN
和GIT_AUTH_HEADER
。使用它们在使用远程私有Git仓库构建时指定HTTP身份验证参数,包括
- 使用私有Git仓库作为构建上下文进行构建
- 使用
ADD
在构建中获取私有Git仓库
例如,假设您在https://gitlab.com/example/todo-app.git
有一个私有的GitLab项目,并且想要使用该仓库作为构建上下文运行构建。未经身份验证的docker build
命令会失败,因为构建器无权拉取该仓库。
$ docker build https://gitlab.com/example/todo-app.git
[+] Building 0.4s (1/1) FINISHED
=> ERROR [internal] load git source https://gitlab.com/example/todo-app.git
------
> [internal] load git source https://gitlab.com/example/todo-app.git:
0.313 fatal: could not read Username for 'https://gitlab.com': terminal prompts disabled
------
要对Git服务器进行构建器身份验证,请将GIT_AUTH_TOKEN
环境变量设置为包含有效的GitLab访问令牌,并将其作为密钥传递给构建。
$ GIT_AUTH_TOKEN=$(cat gitlab-token.txt) docker build \
--secret id=GIT_AUTH_TOKEN \
https://gitlab.com/example/todo-app.git
GIT_AUTH_TOKEN
也适用于ADD
,用于在构建过程中获取私有Git仓库。
FROM alpine
ADD https://gitlab.com/example/todo-app.git /src
HTTP 身份验证方案
默认情况下,通过HTTP进行的Git身份验证使用Bearer身份验证方案。
Authorization: Bearer <GIT_AUTH_TOKEN>
如果需要使用Basic方案(使用用户名和密码),则可以设置GIT_AUTH_HEADER
构建密钥。
$ export GIT_AUTH_TOKEN=$(cat gitlab-token.txt)
$ export GIT_AUTH_HEADER=basic
$ docker build \
--secret id=GIT_AUTH_TOKEN \
--secret id=GIT_AUTH_HEADER \
https://gitlab.com/example/todo-app.git
BuildKit目前仅支持Bearer和Basic方案。
多个主机
您可以为每个主机设置GIT_AUTH_TOKEN
和GIT_AUTH_HEADER
密钥,这允许您为不同的主机名使用不同的身份验证参数。要指定主机名,请将主机名作为后缀附加到密钥ID。
$ export GITLAB_TOKEN=$(cat gitlab-token.txt)
$ export GERRIT_TOKEN=$(cat gerrit-username-password.txt)
$ export GERRIT_SCHEME=basic
$ docker build \
--secret id=GIT_AUTH_TOKEN.gitlab.com,env=GITLAB_TOKEN \
--secret id=GIT_AUTH_TOKEN.gerrit.internal.example,env=GERRIT_TOKEN \
--secret id=GIT_AUTH_HEADER.gerrit.internal.example,env=GERRIT_SCHEME \
https://gitlab.com/example/todo-app.git