設定 GKE 私人叢集的受限存取權

設定 DNS 轉送至受限制的虛擬 IP (VIP),可讓 Google Kubernetes Engine 私人叢集存取 VPC Service Controls service perimeter 內的 Artifact Registry 存放區。

由於私人叢集節點與網際網路隔離,且預設情況下,登錄檔網域會解析為公開 IP 位址,因此您必須透過受限制的 VIP 轉送 pkg.dev 和 gcr.io 網域的要求。

總覽

私人叢集應一律透過受限制的 VIP 存取 Artifact Registry 或 Container Registry,防止資料從支援的服務外洩至不支援的服務。

如果符合下列所有條件,請為 GKE 私人叢集設定受限存取權:

  • 您使用的是 GKE 私人叢集。
  • 您尚未將 pkg.dev 或 gcr.io 註冊資料庫網域的轉送設定設為 restricted.googleapis.com。

事前準備

建立 service perimeter 前,請先設定新的私人叢集,或找出要保護的現有私人叢集。

此外,您必須允許輸出至 199.36.153.4/30 的通訊埠 443。一般來說,虛擬私有雲網路具有默示規則,允許所有輸出流量傳送至任何目的地。不過,如果您有規則拒絕這類流量,則必須建立輸出防火牆規則,允許通訊埠 443 上的 TCP 流量傳送至 199.36.153.4/30。

設定 DNS

設定 DNS 伺服器,將傳送至註冊資料庫位址的要求解析為 restricted.googleapis.com (受限制的 VIP)。您可以使用 Cloud DNS 私人 DNS 區域執行這項操作。

  1. 建立代管不公開區域。

    gcloud dns managed-zones create ZONE_NAME \
        --visibility=private \
        --networks=https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/networks/NETWORK \
        --description=DESCRIPTION \
        --dns-name=REGISTRY_DOMAIN \
        --project=PROJECT_ID
    

    其中:

    • ZONE_NAME:您要建立的區域名稱。例如,registry。後續步驟都會用到這個名稱。
    • PROJECT_ID 是託管 GKE 私人叢集的專案 ID。
    • NETWORK 是選用清單,列出要重新導向要求的叢集網路名稱。
    • DESCRIPTION 是代管區域的人類可讀說明。
    • REGISTRY_DOMAIN 是登錄檔的網域:
      • Artifact Registry 的pkg.dev
      • Container Registry 的 gcr.io,或託管於 Artifact Registry 的 gcr.io 存放區
  2. 啟動交易。

    gcloud dns record-sets transaction start \
      --zone=ZONE_NAME \
      --project=PROJECT_ID
    

    其中:

    • ZONE_NAME 是您在第一個步驟中建立的區域名稱。

    • PROJECT_ID:託管 GKE 私人叢集的專案 ID。

  3. 為註冊資料庫新增 CNAME 記錄。

    gcloud dns record-sets transaction add \
      --name=*.REGISTRY_DOMAIN. \
      --type=CNAME REGISTRY_DOMAIN. \
      --zone=ZONE_NAME \
      --ttl=300 \
      --project=PROJECT_ID
    

    其中:

    • ZONE_NAME 是您在第一個步驟中建立的區域名稱。
    • PROJECT_ID 是託管 GKE 私人叢集的專案 ID。
    • REGISTRY_DOMAIN 是登錄檔的網域:
      • Artifact Registry 的 pkg.dev
      • Container Registry 的 gcr.io,或託管於 Artifact Registry 的 gcr.io 存放區
  4. 為受限制的 VIP 新增 A 記錄。

    gcloud dns record-sets transaction add \
      --name=REGISTRY_DOMAIN. \
      --type=A 199.36.153.4 199.36.153.5 199.36.153.6 199.36.153.7 \
      --zone=ZONE_NAME \
      --ttl=300 \
      --project=PROJECT_ID
    

    其中:

    • ZONE_NAME 是您在第一個步驟中建立的區域名稱。
    • PROJECT_ID 是託管 GKE 私人叢集的專案 ID。
    • REGISTRY_DOMAIN 是登錄檔的網域:
      • Artifact Registry 的 pkg.dev
      • Container Registry 的 gcr.io,或託管於 Artifact Registry 的 gcr.io 存放區
  5. 執行交易。

    gcloud dns record-sets transaction execute \
      --zone=ZONE_NAME \
      --project=PROJECT_ID
    

    其中:

    • ZONE_NAME 是您在第一個步驟中建立的區域名稱。

    • PROJECT_ID:託管 GKE 私人叢集的專案 ID。

設定 DNS 轉送後,請確認 GKE、登錄檔和其他必要服務都位於 VPC Service Controls service perimeter 內。如要設定 service perimeter,請參閱下一節。

設定 service perimeter

設定 DNS 記錄後,請執行下列操作:

  1. 建立新的 service perimeter 或更新現有 perimeter。
  2. 將 Container Registry 或 Artifact Registry 服務,新增至要使用 service perimeter 保護的服務清單。
  3. 將與該存放區搭配使用的其他支援服務新增至 service perimeter,例如 Cloud Build、Artifact Analysis 和二進位授權。
  4. 如要存取 Container Registry,您也必須將 Cloud Storage 新增至 service perimeter。

確認範圍是否可運作

設定 service perimeter 後,如果映像檔儲存在 service perimeter 內的專案中,GKE 私人叢集中的節點就能存取 Artifact Registry 和 Container Registry 中的容器映像檔。

除了特定唯讀公開存放區外,perimeter 外部專案中的容器映像檔仍無法存取。

舉例來說,如果 google-samples 專案不在 service perimeter 內,執行指令從 hello-app 容器建立部署作業就會失敗:

pkg.dev 網域

kubectl create deployment hello-server --image=us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0

gcr.io 網域

kubectl create deployment hello-server --image=gcr.io/google-samples/hello-app:1.0

使用下列指令檢查 Pod 的狀態:

kubectl get pods

指令會傳回類似以下範例的資料表。Pod 狀態 ErrImagePull 表示提取失敗。

NAME                            READY   STATUS         RESTARTS   AGE
hello-server-dbd86c8c4-h5wsf    1/1     ErrImagePull   0          45s

您可以使用 kubectl describe pod 指令,查看部署作業的詳細資料。以上述範例中的 Pod 為例,指令如下:

kubectl describe pod hello-server-dbd86c8c4-h5wsf