构建密钥
构建密钥是任何敏感信息的一部分,例如密码或API令牌,作为应用程序构建过程的一部分被使用。
构建参数和环境变量不适合用于将秘密传递给您的构建,因为它们会保留在最终镜像中。相反,您应该使用秘密挂载或SSH挂载,这些方法可以安全地将秘密暴露给您的构建。
构建机密的类型
- Secret mounts 是用于将秘密传递到构建中的通用挂载。秘密挂载从构建客户端获取一个秘密,并在构建指令期间使其在构建容器内临时可用。例如,如果您的构建需要与私有工件服务器或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 ...Secret mounts
Secret mounts 将秘密以文件或环境变量的形式暴露给构建容器。您可以使用 secret mounts 将敏感信息传递给您的构建,例如 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 /srcHTTP 认证方案
默认情况下,Git 通过 HTTP 进行身份验证时使用 Bearer 身份验证方案:
Authorization: Bearer <GIT_AUTH_TOKEN>如果您需要使用基本方案,包括用户名和密码,您可以设置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