构建密钥

构建密钥是任何敏感信息,例如密码或 API 令牌,作为您应用程序构建过程的一部分被消耗。

构建参数和环境变量不适合用于向构建传递机密,因为它们会持久化到最终镜像中。相反,您应该使用机密挂载或SSH挂载,它们可以安全地将机密暴露给您的构建。

构建机密的类型

  • Secret mounts 是一种通用的挂载方式,用于将密钥传递到您的构建中。Secret mounts 从构建客户端获取密钥,并在构建指令的持续时间内暂时在构建容器中提供该密钥。如果您的构建需要与私有构件服务器或 API 进行通信,这将非常有用。
  • SSH 挂载 是一种特殊用途的挂载,用于在构建中提供 SSH 套接字或密钥。当您需要在构建中获取私有 Git 仓库时,通常会使用它们。
  • 远程上下文的 Git 身份验证 是一组预定义的密钥,用于当您使用远程 Git 上下文构建时,该上下文也是一个私有仓库。这些密钥是“预检”密钥: 它们不会在构建指令中被消耗,但它们用于为构建器提供获取上下文所需的凭据。

使用构建机密

对于 secret 挂载和 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=filetype=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/<id>。您可以使用 Dockerfile 中 RUN --mount 标志的 targetenv 选项来自定义密钥在构建容器中的挂载方式。

以下示例将密钥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 ...

可以同时使用targetenv选项将密钥挂载为文件和环境变量。

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_TOKENGIT_AUTH_HEADER。使用它们来指定在使用远程私有 Git 仓库构建时的 HTTP 身份验证参数,包括:

  • 使用私有 Git 仓库作为构建上下文进行构建
  • 在构建中使用 ADD 获取私有 Git 仓库

例如,假设您有一个私有的 GitLab 项目位于 https://gitlab.com/example/todo-app.git,并且您想使用该仓库作为构建上下文来运行构建。未经过身份验证的 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 身份验证方案

默认情况下,Git 通过 HTTP 进行身份验证使用 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_TOKENGIT_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