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

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

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

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

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

  • 您使用的是 GKE 私人叢集。
  • 您尚未將 pkg.dev 或 gcr.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