建置 Secrets

建置密鑰是指在應用程式建置過程中使用的任何敏感資訊,例如密碼或 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_TOKENGIT_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_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