簡體   English   中英

如何從容器化的 Dockerfile 向 GCP 進行身份驗證

[英]How to authenticate to GCP from a containerized Dockerfile

我正在嘗試使用 Cloud Build 觸發器作業動態構建一個新的 Docker 映像,但是我看不到如何安全地檢索我的憑據以使用服務帳戶對 GCP 進行身份驗證。

以下是步驟:

  1. 使用構建 Docker 映像的步驟創建的 Dockerfile。其中一個步驟包括從 Google Storage(存儲桶)下載我需要作為 GCP 服務帳戶訪問的文件。

    <\/li>

  2. Docker 鏡像是使用 Cloud Build 觸發器構建的,該觸發器在鏈接存儲庫中的每次更改后觸發並存儲在 GCR 中。

    <\/li><\/ol>

    第一步失敗,因為:

    1.) 默認情況下,出於某種原因,在 GCP 中運行 Dockerfile 的用戶未針對 GCP 進行身份驗證。它不是默認的 Google Cloud Build 帳戶,而是匿名用戶。

    2.) 我可以作為服務帳戶進行身份驗證但是

    a.) 我不想在本地或存儲庫中存儲未加密的 JSON 私鑰。 b.) 如果我將它加密存儲在 GCP 存儲庫中,那么我需要在使用 KMS 解密之前進行身份驗證。但是我沒有密鑰,因為它仍然是加密的。所以我回到我的問題。 c.) 如果我將它存儲在 GCP Storage 存儲桶中,我也需要進行身份驗證。所以我回到我的問題。

    有沒有其他方法可以執行雲構建觸發器作業並保持\/獲取 GCP 服務帳戶上下文?

    "

  1. 您可以讓 cloud build 為您從雲存儲下載文件,並讓 docker 訪問該目錄,以便它可以使用該文件。 您需要允許雲構建服務帳戶訪問您的存儲桶。

    請參閱: https : //cloud.google.com/cloud-build/docs/securing-builds/set-service-account-permissions

或者

  1. 使用gcloud auth configure-docker ,然后您可以使用--impersonate-service-account來模擬服務--impersonate-service-account並訪問存儲桶,因此 docker 用戶有足夠的權限來下載文件

    請參閱: https : //cloud.google.com/sdk/gcloud/reference/auth/configure-docker

@ParthMehta 的#1 解決方案是正確的。

在調用 Docker Build 之前,在您的 Cloud Build 中添加此步驟,以使用 Cloud Build 環境的權限從 Cloud Storage 下載文件(服務帳戶如下: <PROJECT_NUMBER>@cloudbuild.gserviceaccount.com

- name: gcr.io/cloud-builders/gsutil
  args: ['cp', 'gs://mybucket/my_file', 'my_file']

該文件被復制到 Cloud Build 執行的當前目錄/workspace 然后通過在Dockerfile添加一個簡單的COPY將文件添加到您的容器中

....
COPY ./my_file ./my_file
....

一般來說,當您在 GCP 環境中工作時,您永遠不必使用 JSON 密鑰文件。

老問題,但以上兩個答案都不能讓我滿意,因為我需要從 Artifact Registry 中提取私有包。 經過大量的反復試驗,我找到了一個使用短期訪問令牌和服務帳戶模擬的解決方案,我正在分享該解決方案,以防其他人遇到同樣的問題。

具體來說,我使用 Cloud Build 和 Docker 容器在部署我的 Node 應用程序之前對其進行轉換。 構建過程需要從 Artifact Registry 中提取私有 NPM 包,但由於未經授權而無法正常工作。

工作解決方案

  1. 首先創建一個可以訪問您需要的任何 GCP 服務的服務帳戶。 就我而言,我創建了artifact-registry-reader@<PROJECT>.iam.gserviceaccount.com並授予它對 Artifact Registry 存儲庫的訪問權限作為“Artifact Registry Reader”。 在您的情況下,您可以授予它訪問該存儲桶的權限。

  2. 編輯新創建的服務帳戶並在權限下添加您的 Cloud Builder 服務帳戶 ( <PROJECT_ID>@cloudbuild.gserviceaccount.com ) 作為 Principal 並授予它“Service Account Token Creator”角色。

  3. 接下來,您的cloudbuild.yaml文件應如下所示:

steps:
  # Step 1: Generate an Access Token and save it
  #
  # Here we call `gcloud auth print-access-token` to impersonate the service account 
  # we created above and to output a short-lived access token to the default volume 
  # `/workspace/access_token`.  This is accessible in subsequent steps.
  #
  - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk:slim'
    args:
      - '-c'
      - >
        gcloud auth print-access-token --impersonate-service-account
        artifact-registry-reader@<PROJECT>.iam.gserviceaccount.com >
        /workspace/access_token
    entrypoint: sh
  # Step 2: Build our Docker container
  #
  # We build the Docker container passing the access token we generated in Step 1 as 
  # the `--build-arg` `TOKEN`.  It's then accessible within the Dockerfile using
  # `ARG TOKEN`
  #
  - name: gcr.io/cloud-builders/docker
    args:
      - '-c'
      - >
        docker build -t us-docker.pkg.dev/<PROJECT>/services/frontend:latest
        --build-arg TOKEN=$(cat /workspace/access_token) -f
        ./docker/prod/Dockerfile . &&

        docker push us-docker.pkg.dev/<PROJECT>/services/frontend
    entrypoint: sh
  1. 下一步特定於 Artifact Registry 中的私有 npm 包,但我創建了一個部分 .npmrc 文件(缺少 :_authToken 行),其中包含以下內容:
@<NAMESPACE>:registry=https://us-npm.pkg.dev/<PROJECT>/npm/
//us-npm.pkg.dev/<PROJECT>/npm/:username=oauth2accesstoken
//us-npm.pkg.dev/<PROJECT>/npm/:email=artifact-registry-reader@<PROJECT>.iam.gserviceaccount.com
//us-npm.pkg.dev/<PROJECT>/npm/:always-auth=true
  1. 最后,我的 Dockerfile 使用鑄造的令牌來更新我的.npmrc文件,使其能夠從 Artifact Registry 中提取私有 npm 包。
ARG NODE_IMAGE=node:17.2-alpine

FROM ${NODE_IMAGE} as base

ENV APP_PORT=8080

ENV WORKDIR=/usr/src/app
ENV NODE_ENV=production

FROM base AS builder

# Create our WORKDIR
RUN mkdir -p ${WORKDIR}

# Set the current working directory
WORKDIR ${WORKDIR}

# Copy the files we need
COPY --chown=node:node package.json ./
COPY --chown=node:node ts*.json ./
COPY --chown=node:node .npmrc ./
COPY --chown=node:node src ./src

#######################
# MAGIC HAPPENS HERE
# Append our access token to the .npmrc file and the container will now be 
# authorized to download packages from the Artifact Registry
# 
# IMPORTANT! Declare the TOKEN build arg so that it's accessible
#######################

ARG TOKEN
RUN echo "//us-npm.pkg.dev/<PROJECT>/npm/:_authToken=\"$TOKEN\"" >> .npmrc

RUN npm install

RUN npm run build

EXPOSE ${APP_PORT}/tcp

CMD ["cd", "${WORKDIR}"]
ENTRYPOINT ["npm", "run", "start"]

顯然,在您的情況下,您將使用 GCS 以不同的方式使用訪問令牌進行身份驗證,但整體概念應該可以很好地轉換為任何類似的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM