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

本文說明如何設定 DNS 項目,以便在 VPC Service Controls 服務範圍內使用 Google Kubernetes Engine 私人叢集時,透過受限虛擬 IP (VIP) 將要求路由至 pkg.devgcr.io 網域。

登錄網域通常會解析為網際網路上的公開 IP 位址。在 GKE 私人叢集中,節點預設會與網際網路隔離。也就是說,如果您未將 DNS 路由設定為受限的 VIP,對註冊管理機構網域的要求就會失敗。

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

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

  • 您使用的是 GKE 私人叢集。
  • 您尚未將 pkg.devgcr.io 登錄網域的轉送設定為 restricted.googleapis.com

事前準備

建立服務範圍前,請先設定新的私人叢集,或找出您要保護的現有私人叢集。

此外,您必須允許輸出至通訊埠 443 上的 199.36.153.4/30。一般來說,虛擬私有雲網路會有一項隱含規則,允許所有輸出流量前往任何目的地。不過,如果規則拒絕這類流量,您必須建立輸出防火牆規則,允許通訊埠 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 Registrypkg.dev
      • gcr.io,適用於 Container Registry 或 gcr.io Artifact Registry 中託管的存放區
  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 Registrypkg.dev
      • gcr.io,適用於 Container Registry 或 gcr.io Artifact Registry 中託管的存放區
  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 Registrypkg.dev
      • gcr.io,適用於 Container Registry 或 gcr.io Artifact Registry 中託管的存放區
  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,請參閱下一節。

設定服務範圍

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

  1. 建立新的服務邊界,或更新現有服務邊界
  2. 將 Container Registry 或 Artifact Registry 服務新增到要使用服務範圍保護的服務清單中。
  3. 將與登錄檔搭配使用的其他支援服務 (例如 Cloud Build、Artifact Analysis 和二進位授權) 新增至服務周邊。
  4. 如要存取 Container Registry,您也必須將 Cloud Storage 新增至服務範圍。

確認範圍是否可運作

設定服務安全防護範圍後,如果映像檔儲存在服務安全防護範圍內的專案中,GKE 私人叢集中的節點就能存取 Artifact Registry 和 Container Registry 中的容器映像檔。

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

舉例來說,如果 google-samples 專案不在服務安全防護範圍內,從 hello-app 容器建立 Deployment 的指令就會失敗:

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