設定多專案設定

本教學課程說明如何在多專案設定中使用二進位授權。如要簡化單一專案的設定,請參閱「開始使用 Google Cloud CLI (GKE)」。

如要建立權責劃分,您可以在多專案設定中設定 Binary Authorization。本教學課程稍後會說明每個專案的用途。

設定部署者專案

部署者專案會管理 Google Kubernetes Engine (GKE) 叢集 (您可在其中部署映像檔),以及二進位授權在部署時強制執行的二進位授權政策。視環境大小、複雜程度和其他需求而定,您可以有多個部署者專案。

設定部署者專案:

  1. 如果尚未建立專案並在 Google Cloud 控制台中啟用計費功能,請先完成這些步驟。

  2. 身分與存取權管理注意事項:部署者專案包含您的 GKE 叢集。這個專案的 Identity and Access Management 設定應反映這項變更。

  3. 設定環境變數,儲存 Google Cloud 專案和編號:

    DEPLOYER_PROJECT_ID=DEPLOYER_PROJECT_ID
    

    然後將 DEPLOYER_PROJECT_ID 替換為專案 ID。 Google Cloud

    DEPLOYER_PROJECT_NUMBER=$(gcloud projects describe "${DEPLOYER_PROJECT_ID}" \
        --format="value(projectNumber)")
    
  4. 啟用 API:

    Artifact Registry

    gcloud --project=${DEPLOYER_PROJECT_ID} \
      services enable\
      container.googleapis.com\
      artifactregistry.googleapis.com\
      binaryauthorization.googleapis.com
    
  5. 取得部署者專案服務帳戶名稱:

    DEPLOYER_SERVICE_ACCOUNT="service-${DEPLOYER_PROJECT_NUMBER}@gcp-sa-binaryauthorization."
    

    您會在後續步驟中,使用服務帳戶名稱設定與驗證者相關聯的構件分析附註權限。

設定驗證者專案

驗證者專案會儲存驗證者,這些驗證者可以確認映像檔是否已準備好部署。通常,您會有單一的認證者專案,做為授權程序中可信賴當事人資訊的集中式儲存空間。這樣一來,您就能集中管理驗證者身分驗證所需的安全金鑰,並限制只有管理員才能存取。

如要設定認證者專案,請按照下列步驟操作:

  1. 如果尚未建立專案並在 Google Cloud 控制台中啟用計費功能,請先完成這些步驟。

  2. 身分與存取權管理注意事項:由於這個專案包含驗證者,只有安全人員應具備寫入權限。

  3. 設定環境變數,儲存專案 ID 和編號:

    ATTESTOR_PROJECT_ID=ATTESTOR_PROJECT_ID
    

    ATTESTOR_PROJECT_ID 替換為認證者專案 ID。

    ATTESTOR_PROJECT_NUMBER=$(gcloud projects describe "${ATTESTOR_PROJECT_ID}" \
        --format="value(projectNumber)")
    
  4. 啟用 Artifact Analysis 和 Binary Authorization API:

    gcloud services --project=${ATTESTOR_PROJECT_ID} \
        enable containeranalysis.googleapis.com \
        binaryauthorization.googleapis.com
    
  5. 取得驗證者專案服務帳戶名稱:

    ATTESTOR_SERVICE_ACCOUNT="service-${ATTESTOR_PROJECT_NUMBER}@gcp-sa-binaryauthorization."
    

    您會在後續步驟中,使用服務帳戶名稱設定與驗證者相關聯的構件分析附註權限。

設定認證專案

認證專案會儲存認證,驗證者會在驗證映像檔時建立認證。您可以使用獨立的認證專案,更輕鬆地整理及檢查軟體準備程度的聲明。

  1. 如果尚未建立專案並在 Google Cloud 控制台中啟用計費功能,請先完成這些步驟。

  2. Identity and Access Management 注意事項:參與二進位授權的所有角色都應具備這個專案中構件分析附註和發生事項的讀取權,但只有認證管理員需要寫入權。

  3. 設定環境變數來儲存專案名稱:

    ATTESTATION_PROJECT_ID=ATTESTATION_PROJECT_ID
    

    ATTESTATION_PROJECT_ID 替換為認證專案 ID。

  4. 啟用 Artifact Analysis 和 Binary Authorization API:

    gcloud services --project=${ATTESTATION_PROJECT_ID} \
        enable containeranalysis.googleapis.com \
        binaryauthorization.googleapis.com
    

建立叢集

現在您可以在部署工具專案中建立 GKE 叢集。 這是要執行已部署容器映像檔的叢集。建立叢集時,請將 --binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE 標記傳送至 gcloud container clusters create 指令。

如要建立叢集,請按照下列步驟操作:

gcloud --project=${DEPLOYER_PROJECT_ID} \
    container clusters create \
    --binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE \
    --zone us-central1-a \
    test-cluster

您將在 GKE 區域 us-central1-a 中建立名為 test-cluster 的叢集。

您也必須更新 kubectl 安裝的本機 kubeconfig 檔案。這會提供在 GKE 中存取叢集所需的憑證和端點資訊。

如要更新本機 kubeconfig 檔案,請按照下列步驟操作:

gcloud --project=${DEPLOYER_PROJECT_ID} \
    container clusters get-credentials \
    --zone us-central1-a \
    test-cluster

建立驗證者

驗證者負責驗證必要程序是否已完成,容器映像檔必須通過驗證才能部署。這個主體可以是人類使用者,但通常是機器程序,例如建構和測試系統,或是持續整合 (CI) 和部署 (CD) 管道。您可以在驗證者專案中建立驗證者。

如要建立驗證者,請完成下列步驟:

  • 構件分析中建立附註,儲存授權程序中使用的可信中繼資料
  • 在驗證者專案中建立驗證者本身,並將您建立的附註與其建立關聯
  • 為部署者專案服務帳戶新增身分與存取權管理角色繫結至驗證者
  • 設定 Artifact Analysis 記事的權限

在本教學課程中,您有一個名為 test-attestor 的驗證者,以及一個名為 test-attestor-note 的容器分析附註。在實際情況中,您可以有任意數量的認證者,每個認證者代表參與圖片授權程序的當事人。

建立構件分析附註

  1. 設定變數,以儲存簽署者和構件分析附註的名稱:

    ATTESTOR_NAME=test-attestor
    NOTE_ID=test-attestor-note
    

    取代:

    • test-attestor:您選擇的驗證者名稱。
    • test-attestor-note:您選擇的驗證者附註名稱。
  2. /tmp/note_payload.json 中建立 JSON 檔案,說明 Container Analysis 附註:

    cat > /tmp/note_payload.json << EOM
    {
      "name": "projects/${ATTESTOR_PROJECT_ID}/notes/${NOTE_ID}",
      "attestation": {
        "hint": {
          "human_readable_name": "Attestor Note"
        }
      }
    }
    EOM
    
  3. 將 HTTP 要求傳送至 Artifact Analysis REST API,建立附註:

    curl -X POST \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $(gcloud auth print-access-token)"  \
        --data-binary @/tmp/note_payload.json  \
        "https://containeranalysis.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/notes/?noteId=${NOTE_ID}"
    
  4. 確認記事已建立:

    curl \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    "https://containeranalysis.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/notes/${NOTE_ID}"
    

建立驗證者

現在,您可以建立驗證者:

  1. 在二進位授權中建立驗證者:

    gcloud --project=${ATTESTOR_PROJECT_ID} \
        container binauthz attestors create ${ATTESTOR_NAME} \
        --attestation-authority-note=${NOTE_ID} \
        --attestation-authority-note-project=${ATTESTOR_PROJECT_ID}
    
  2. 確認驗證者是否已建立:

    gcloud --project=${ATTESTOR_PROJECT_ID} \
        container binauthz attestors list
    

您建立的驗證者尚未與 PKIX 金鑰組建立關聯,因此無法使用。請參閱下文建立金鑰組。

為部署者專案新增 IAM 角色繫結

您必須為部署者專案新增驗證者的 IAM 角色繫結。二進位授權評估政策時,會使用這項角色判斷專案是否有權存取任何相關聯的認證。

如要新增 IAM 角色繫結,請按照下列步驟操作:

gcloud --project ${ATTESTOR_PROJECT_ID} \
    container binauthz attestors add-iam-policy-binding \
    "projects/${ATTESTOR_PROJECT_ID}/attestors/${ATTESTOR_NAME}" \
    --member="serviceAccount:${DEPLOYER_SERVICE_ACCOUNT}" \
    --role=roles/binaryauthorization.attestorsVerifier

設定 Artifact Analysis 記事的權限

您也必須在建立的構件分析附註中設定權限,讓部署者專案和認證者專案都能存取。方法是更新記事的 IAM 政策,將「檢視者」存取權指派給專案服務帳戶。

  1. 產生 JSON 檔案,其中包含在記事上設定 IAM 政策所需的資訊。

    cat > /tmp/iam_request.json << EOM
    {
      'resource': 'projects/${ATTESTOR_PROJECT_ID}/notes/${NOTE_ID}',
      'policy': {
        'bindings': [
          {
            'role': 'roles/containeranalysis.notes.occurrences.viewer',
            'members': [
              'serviceAccount:${ATTESTOR_SERVICE_ACCOUNT}',
              'serviceAccount:${DEPLOYER_SERVICE_ACCOUNT}'
            ]
          }
        ]
      }
    }
    EOM
    
  2. 將服務帳戶和要求的存取角色新增至您建立的記事 IAM 政策:

    curl -X POST  \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        --data-binary @/tmp/iam_request.json \
        "https://containeranalysis.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/notes/${NOTE_ID}:setIamPolicy"
    

設定 PKIX 金鑰

二進位授權會使用加密編譯金鑰,安全地驗證認證者的身分。這可確保只有經過驗證的當事人可以授權容器映像檔。金鑰組包含私密金鑰 (認證者用來數位簽署認證) 和公開金鑰 (您新增至認證者,由 Binary Authorization 服務儲存)。

在本教學課程中,您將使用建議的橢圓曲線數位簽章演算法 (ECDSA) 建立金鑰組。您也可以使用 RSA 或 PGP 金鑰簽署。如要進一步瞭解簽署演算法,請參閱「金鑰用途與演算法」一文。

Cloud Key Management Service (Cloud KMS) 產生及儲存的非對稱金鑰符合 PKIX 標準。如要進一步瞭解如何使用 PKIX 金鑰和 Cloud KMS,請參閱「使用 CLI 建立驗證者」。

產生金鑰組

PKIX 金鑰組包含私密金鑰 (簽署者用來以數位方式簽署認證) 和公開金鑰 (您新增至認證者)。部署時,Binary Authorization 會使用這個公開金鑰,驗證以私密金鑰簽署的驗證。

  1. 產生私密金鑰:

    如要產生新的本機非對稱 PKIX 金鑰配對,並儲存在檔案中,請執行下列指令:

    PKIX (Cloud KMS)

    這個步驟說明如何使用 Cloud Key Management Service 產生及儲存的金鑰執行認證。

    1. 設定環境變數,儲存 Cloud KMS 管理的金鑰配對相關資訊:

      如果您已有金鑰配對,可以設定這些環境變數,並略過下一個步驟。

      KMS_KEY_PROJECT_ID=KMS_KEY_PROJECT_ID
      KMS_KEY_LOCATION=KMS_KEY_LOCATION
      KMS_KEYRING_NAME=KMS_KEYRING_NAME
      KMS_KEY_NAME=KMS_KEY_NAME
      KMS_KEY_VERSION=KMS_KEY_VERSION
      

      更改下列內容:

      • KMS_KEY_PROJECT_ID:儲存金鑰的專案 ID
      • KMS_KEY_LOCATION:金鑰位置
      • KMS_KEYRING_NAME:金鑰環的名稱
      • KMS_KEY_NAME:金鑰名稱
      • KMS_KEY_VERSION:金鑰版本
    2. [選用] 設定 KMS 金鑰:

      1. 建立 KMS 金鑰,其公開金鑰可儲存在認證者中。 這個步驟也會設定您在下方使用的環境變數。

        如要建立金鑰並設定環境變數,請按照下列步驟操作:

        KMS_KEY_PROJECT_ID=${PROJECT_ID}
        KMS_KEYRING_NAME=my-binauthz-keyring
        KMS_KEY_NAME=my-binauthz-kms-key-name
        KMS_KEY_LOCATION=global
        KMS_KEY_PURPOSE=asymmetric-signing
        KMS_KEY_ALGORITHM=ec-sign-p256-sha256
        KMS_PROTECTION_LEVEL=software
        KMS_KEY_VERSION=1
        
      2. 建立 KMS 金鑰環:

        gcloud kms keyrings create ${KMS_KEYRING_NAME} \
          --location ${KMS_KEY_LOCATION} \
          --project ${KMS_KEY_PROJECT_ID}
        
      3. 建立金鑰:

        gcloud kms keys create ${KMS_KEY_NAME} \
          --location ${KMS_KEY_LOCATION} \
          --keyring ${KMS_KEYRING_NAME}  \
          --purpose ${KMS_KEY_PURPOSE} \
          --default-algorithm ${KMS_KEY_ALGORITHM} \
          --protection-level ${KMS_PROTECTION_LEVEL} \
          --project ${KMS_KEY_PROJECT_ID}
        

        如要進一步瞭解如何建立 KMS 金鑰,請參閱「建立非對稱金鑰」。

    3. 將公開金鑰新增至驗證者:

      gcloud --project="${ATTESTOR_PROJECT_ID}" \
          container binauthz attestors public-keys add \
          --attestor="${ATTESTOR_NAME}" \
          --keyversion-project="${KMS_KEY_PROJECT_ID}" \
          --keyversion-location="${KMS_KEY_LOCATION}" \
          --keyversion-keyring="${KMS_KEYRING_NAME}" \
          --keyversion-key="${KMS_KEY_NAME}" \
          --keyversion="${KMS_KEY_VERSION}"
      

    PKIX (本機金鑰)

    1. 如要產生私密金鑰,請執行下列指令:

      PRIVATE_KEY_FILE="/tmp/ec_private.pem"
      openssl ecparam -genkey -name prime256v1 -noout -out ${PRIVATE_KEY_FILE}
      

      PRIVATE_KEY_FILE 是包含儲存在認證者中私密金鑰的檔案名稱。

    2. 從私密金鑰中擷取公開金鑰,並儲存在檔案中:

      PUBLIC_KEY_FILE="/tmp/ec_public.pem"
      openssl ec -in ${PRIVATE_KEY_FILE} -pubout -out ${PUBLIC_KEY_FILE}
      

      PUBLIC_KEY_FILE 是包含儲存在認證者中的公開金鑰的檔案名稱。

    3. 如要將匯出的公開金鑰新增至驗證者,請執行下列程式碼。

      gcloud --project="${ATTESTOR_PROJECT_ID}" \
        container binauthz attestors public-keys add \
        --attestor="${ATTESTOR_NAME}" \
        --pkix-public-key-file=${PUBLIC_KEY_FILE} \
        --pkix-public-key-algorithm=ecdsa-p256-sha256
      

      二進位授權會使用認證者中的公開金鑰驗證認證。

設定政策

現在您可以在部署者專案中設定政策。在這個步驟中,您會將政策 YAML 檔案匯出至本機系統,並修改預設規則,要求使用您在上方定義的驗證者進行驗證。

如要設定政策,請按照下列步驟操作:

  1. 建立新的政策檔案,允許使用 Google 維護的系統映像檔,將 evaluationMode 設為 REQUIRE_ATTESTATION,並新增名為 requireAttestationsBy 的節點,參照您建立的驗證者:

    cat > /tmp/policy.yaml << EOM
        globalPolicyEvaluationMode: ENABLE
        defaultAdmissionRule:
          evaluationMode: REQUIRE_ATTESTATION
          enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
          requireAttestationsBy:
            - projects/${ATTESTOR_PROJECT_ID}/attestors/${ATTESTOR_NAME}
        name: projects/${DEPLOYER_PROJECT_ID}/policy
    EOM
    
  2. 將政策 YAML 檔案匯入二進位授權:

    gcloud --project=${DEPLOYER_PROJECT_ID} \
        container binauthz policy import /tmp/policy.yaml
    

如要進一步瞭解如何設定政策,請參閱「使用 CLI 設定政策」。

測試政策

在本教學課程中,您會為 Artifact Registry 中的公開「Hello World!」映像檔建立認證。一開始,由於缺少必要認證,執行者會禁止部署映像檔。

如要嘗試部署映像檔,請按照下列步驟操作:

Artifact Registry

kubectl run hello-server --image us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0 --port 8080

現在,請驗證二進位授權是否封鎖了部署作業:

kubectl get pods

指令會列印下列訊息,表示映像檔未部署:

No resources found.

您可以取得部署作業的進一步詳細資料:

kubectl get event --template \
'{{range.items}}{{"\033[0;36m"}}{{.reason}}:{{"\033[0m"}}\{{.message}}{{"\n"}}{{end}}'

你會看到類似以下的回應:

FailedCreate: Error creating: pods POD_NAME is forbidden: admission webhook "imagepolicywebhook.image-policy.k8s.io" denied the request: Image IMAGE_NAME denied by Binary Authorization default admission rule. Image IMAGE_NAME denied by attestor ATTESTOR_NAME: No attestations found

輸出內容如下:

  • POD_NAME:Pod 的名稱。
  • IMAGE_NAME:圖片名稱。
  • ATTESTOR_NAME:驗證者名稱。

請務必刪除部署作業,才能繼續下一個步驟:

kubectl delete deployment hello-server

建立認證

驗證是驗證者所做的聲明,表示管道中必要的程序已完成,且相關的容器映像檔已獲授權可供部署。認證本身是經過數位簽署的記錄,其中包含映像檔版本的完整路徑 (儲存在容器映像檔登錄檔中),以及認證者的身分。

在本教學課程中,驗證程序只會聲明您授權部署映像檔。您會在認證專案中建立認證。

如要建立認證,請按照下列指示操作:

  1. 設定儲存登錄路徑和映像檔摘要的變數:

    Artifact Registry

    IMAGE_PATH="us-docker.pkg.dev/google-samples/containers/gke/hello-app"
    IMAGE_DIGEST="sha256:37e5287945774f27b418ce567cd77f4bbc9ef44a1bcd1a2312369f31f9cce567"
    IMAGE_TO_ATTEST=${IMAGE_PATH}@${IMAGE_DIGEST}
    
  2. 建立認證

    PKIX Cloud KMS

    如要使用 Cloud KMS 金鑰建立認證,請執行下列指令:

    gcloud beta container binauthz attestations sign-and-create \
        --project="${PROJECT_ID}" \
        --artifact-url="${IMAGE_TO_ATTEST}" \
        --attestor="${ATTESTOR_NAME}" \
        --attestor-project="${PROJECT_ID}" \
        --keyversion-project="${KMS_KEY_PROJECT_ID}" \
        --keyversion-location="${KMS_KEY_LOCATION}" \
        --keyversion-keyring="${KMS_KEYRING_NAME}" \
        --keyversion-key="${KMS_KEY_NAME}" \
        --keyversion="${KMS_KEY_VERSION}"
    

    PKIX (本機金鑰)

    如要使用本機金鑰建立認證,請執行下列操作:

    1. 產生認證酬載:

      gcloud --project=${ATTESTATION_PROJECT_ID} \
        container binauthz create-signature-payload \
        --artifact-url=${IMAGE_TO_ATTEST} > /tmp/generated_payload.json
      

      酬載 JSON 檔案包含下列內容:

      Artifact Registry

      {
      "critical": {
        "identity": {
          "docker-reference": "us-docker.pkg.dev/google-samples/containers/gke/hello-app"
        },
        "image": {
          "docker-manifest-digest": "sha256:37e5287945774f27b418ce567cd77f4bbc9ef44a1bcd1a2312369f31f9cce567"
        },
        "type": "Google cloud binauthz container signature"
      }
      }
      
    2. 簽署酬載。

      如果使用本機 PKIX 檔案,請使用本機 PKIX 私密金鑰簽署酬載,並輸出簽章檔案:

      openssl dgst -sha256 -sign ${PRIVATE_KEY_FILE} /tmp/generated_payload.json > /tmp/ec_signature
      

      輸出檔案是您在上方建立的酬載 JSON 檔案簽署版本。

    3. 從驗證者取得公開金鑰 ID。

      您隨時可以使用 gcloud container binauthz attestors describe ATTESTOR_NAME 指令查看公開金鑰 ID。

      如要將公開金鑰 ID 儲存至環境變數,請輸入下列指令:

      PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${ATTESTOR_NAME} \
      --format='value(userOwnedGrafeasNote.publicKeys[0].id)' --project ${ATTESTOR_PROJECT_ID})
      
    4. 建立及驗證認證:

      gcloud container binauthz attestations create \
        --project="${ATTESTATION_PROJECT_ID}" \
        --artifact-url="${IMAGE_TO_ATTEST}" \
        --attestor="projects/${ATTESTOR_PROJECT_ID}/attestors/${ATTESTOR_NAME}" \
        --signature-file=/tmp/ec_signature \
        --public-key-id="${PUBLIC_KEY_ID}" \
        --validate
      

      validate 旗標會檢查您在政策中設定的認證者是否可驗證認證。

  3. 確認認證是否已建立:

    gcloud --project=${ATTESTATION_PROJECT_ID} \
        container binauthz attestations list \
        --attestor=$ATTESTOR_NAME --attestor-project=$ATTESTOR_PROJECT_ID
    

如要進一步瞭解如何建立認證,請參閱建立認證

重新測試政策

將範例容器映像檔部署到叢集,測試政策。這次您必須使用摘要 (而非 1.0latest 等標記) 部署映像檔,因為二進位授權會使用摘要來查詢認證。在此情況下,二進位授權允許部署映像檔,因為該映像檔具有相關聯的認證。

如要部署映像檔,請按照下列步驟操作:

kubectl run hello-server --image ${IMAGE_TO_ATTEST} --port 8080

如要確認映像檔是否已部署,請執行下列步驟:

kubectl get pods

指令會列印類似以下的訊息,表示部署作業已成功:

NAME                            READY     STATUS    RESTARTS   AGE
hello-server-579859fb5b-h2k8s   1/1       Running   0          1m

您已成功部署容器映像檔,並確認設定正常運作,現在可以刪除在 GKE 中建立的叢集:

gcloud --project=${DEPLOYER_PROJECT_ID} \
    container clusters delete \
    --zone=us-central1-a \
    test-cluster