對 Kubernetes API 伺服器進行驗證


本頁面說明如何從 GKE 叢集安全地向 Kubernetes API 伺服器進行驗證。您可以確保只有授權使用者和應用程式能存取 Kubernetes 資源,藉此保護叢集安全。您將瞭解可用的驗證方法、建議的驗證方法,以及如何驗證使用者、應用程式和舊版系統。

如要瞭解如何向Google Cloud API 驗證 Kubernetes 工作負載,請參閱「Workload Identity Federation for GKE」。

本頁面適用於安全專家和作業人員,他們必須從 GKE 叢集安全地向 Kubernetes API 伺服器進行驗證。本頁面提供可用驗證方法的基本資訊,以及如何實作這些方法。如要進一步瞭解 Google Cloud 內容中提及的常見角色和範例工作,請參閱常見的 GKE Enterprise 使用者角色和工作

閱讀本頁面之前,請先熟悉下列概念:

事前準備

開始之前,請確認你已完成下列工作:

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行 gcloud components update,取得最新版本。

驗證使用者

GKE 會透過 Google Cloud CLI 為您管理使用者驗證。gcloud CLI 會向Google Cloud驗證使用者身分、設定 Kubernetes、取得叢集的 OAuth 存取權杖,並持續更新存取權杖。

所有 GKE 叢集都設定成會接受 Google Cloud使用者和服務帳戶的身分,方法是驗證由 kubectl 提供的憑證,然後擷取與使用者或服務帳戶身分相關聯的電子郵件地址。因此,這些帳戶的憑證必須包含 userinfo.email OAuth 範圍,才能順利通過驗證。

當您使用 gcloud 為新或現有叢集設定環境的 kubeconfig 時,gcloud 會將 gcloud 本身使用的憑證提供給 kubectl。舉例來說,如果您使用 gcloud auth login,系統會把您的個人憑證提供給kubectl,包括 userinfo.email 範圍。這讓 GKE 叢集能夠驗證 kubectl 用戶端的真偽。

或者,您也可以選擇把 kubectl 設定成在 Compute Engine 執行個體上執行時,會使用Google Cloud 服務帳戶的憑證。不過,userinfo.email 範圍預設「不會」包含在由 Compute Engine 執行個體建立的憑證中。因此,您「必須」明確地新增這個範圍,例如在您建立 Compute Engine 執行個體時使用 --scopes 標記。

您可以使用身分與存取權管理 (IAM) 或 Kubernetes 角色型存取權控管 (RBAC),授權叢集中的動作。

使用 OAuth 進行驗證

如要使用 OAuth 方法驗證叢集,請執行下列操作:

  1. 使用憑證登入 gcloud CLI。系統會開啟網路瀏覽器,完成 Google Cloud的驗證程序:

    gcloud auth login
    
  2. 擷取特定叢集的 Kubernetes 憑證:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION
    

    更改下列內容:

    • CLUSTER_NAME:叢集名稱。
    • CONTROL_PLANE_LOCATION:叢集控制層的 Compute Engine 位置。為地區叢集提供地區,或為區域叢集提供區域。
  3. 確認您已通過驗證:

    kubectl cluster-info
    

當使用者或 Google Cloud 服務帳戶通過驗證之後,還必須「獲得授權」才能對 GKE 叢集進行任何動作。如要進一步瞭解如何設定授權,請參閱角色型存取權控管

驗證應用程式

您也可以從 Pod 中的應用程式向 API 伺服器進行驗證,不必與使用者互動,例如從 CI/CD 管道中的指令碼進行驗證。達成目標的方式取決於應用程式的執行環境。

同一叢集中的應用程式

如果應用程式在同一個 GKE 叢集中執行,請使用 Kubernetes 服務帳戶進行驗證。

  1. 建立 Kubernetes 服務帳戶,並附加至 Pod。如果 Pod 已經有 Kubernetes 服務帳戶,或是您想使用命名空間的預設服務帳戶,請略過這個步驟。

  2. 使用 Kubernetes RBAC 將應用程式所需的權限授予 Kubernetes 服務帳戶。

    以下範例會將 prod 命名空間中資源的 view 權限,授予 cicd-ns 命名空間中名為 cicd 的服務帳戶:

    kubectl create rolebinding cicd-secret-viewer \
        --namespace=prod \
        --clusterrole=view \
        --serviceaccount=cicd-ns:cicd
    
  3. 在執行階段,當應用程式傳送 Kubernetes API 要求時,API 伺服器會驗證服務帳戶憑證。

應用程式 Google Cloud

如果應用程式在目標叢集內 Google Cloud 但外部執行 (例如 Compute Engine VM 或其他 GKE 叢集),您應使用環境中可用的 IAM 服務帳戶憑證,向 API 伺服器進行驗證。

  1. 將 IAM 服務帳戶指派給環境。如果應用程式是在 Compute Engine VM 內執行,請將 IAM 服務帳戶指派給執行個體。如果應用程式在其他 GKE 叢集中執行,請使用 Workload Identity Federation for GKE,將 Pod 設為以 IAM 服務帳戶身分執行。

    下列範例使用 ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com 做為 IAM 服務帳戶。

  2. 授予 IAM 服務帳戶叢集存取權。

    以下範例會授予 roles/container.developer IAM 角色,提供叢集內部 Kubernetes API 物件的存取權:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com \
        --role=roles/container.developer
    

    或者,您也可以使用 RBAC 授予 IAM 服務帳戶叢集存取權。從同一個叢集中的應用程式執行 kubectl create rolebinding 指令,並使用 --user=ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com,而不是 --service-account 旗標。

  3. 擷取叢集憑證:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION
    

    系統會使用環境中設定的 IAM 服務帳戶,自動驗證您的應用程式。

其他環境中的應用程式

如果應用程式是從Google Cloud以外的環境進行驗證,就無法存取受管理的 IAM 服務帳戶憑證。如要擷取叢集憑證,您可以建立 IAM 服務帳戶、下載其金鑰,並在執行階段從服務使用該金鑰,透過 gcloud CLI 擷取叢集憑證。

  1. 為應用程式建立 IAM 服務帳戶。如果您已有 IAM 服務帳戶,請略過這個步驟。

    下列指令會建立名為 ci-cd-pipeline 的 IAM 服務帳戶:

    gcloud iam service-accounts create ci-cd-pipeline
    
  2. 將叢集存取權授予 IAM 服務帳戶。

    下列指令會將 roles/container.developer 身分與存取權管理角色授予 ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com 身分與存取權管理服務帳戶:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com \
        --role=roles/container.developer
    

    您也可以使用 RBAC 授予 IAM 服務帳戶叢集存取權。從同一個叢集中的應用程式執行 kubectl create rolebinding 指令,並使用 --user=ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com,而不是 --service-account 旗標。

  3. 建立並下載 IAM 服務帳戶的金鑰。在執行階段提供給應用程式:

    gcloud iam service-accounts keys create gsa-key.json \
        --iam-account=ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com
    
  4. 在執行階段,於執行應用程式的環境中,使用 IAM 服務帳戶金鑰向 gcloud CLI 進行驗證:

    gcloud auth activate-service-account ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com \
        --key-file=gsa-key.json
    
  5. 使用 gcloud CLI 擷取叢集憑證:

    gcloud config set project PROJECT_ID
    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION
    

沒有 gcloud 的環境

建議使用 gcloud CLI 擷取叢集憑證,因為這種方法可因應叢集事件,例如控制層 IP 輪替憑證輪替。不過,如果無法在環境中安裝 gcloud CLI,您還是可以建立靜態 kubeconfig 檔案,向叢集進行驗證:

  1. 為應用程式建立 IAM 服務帳戶。如果您已有 IAM 服務帳戶,請略過這個步驟。

    下列指令會建立名為 ci-cd-pipeline 的 IAM 服務帳戶:

    gcloud iam service-accounts create ci-cd-pipeline
    
  2. 將叢集存取權授予 IAM 服務帳戶。

    下列指令會將 roles/container.developer 身分與存取權管理角色授予 ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com 身分與存取權管理服務帳戶:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com \
        --role=roles/container.developer
    

    您也可以建立自訂 IAM 角色,精細控管授予的權限。

  3. 建立並下載 IAM 服務帳戶的金鑰。

    在以下範例中,金鑰檔案名為 gsa-key.json

    gcloud iam service-accounts keys create gsa-key.json \
        --iam-account=ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com
    
  4. 如果您使用 DNS 型端點存取控制層,請取得叢集的 endpoint 值:

    gcloud container clusters describe CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION \
        --format="value(endpoint)"
    

    如果您使用以 IP 為基礎的端點存取控制層,請從上述指令取得 endpoint 值,並取得叢集的 clusterCaCertificate 值:

    gcloud container clusters describe CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION \
        --format="value(masterAuth.clusterCaCertificate)"
    
  5. 建立 kubeconfig.yaml 檔案。如果您使用 DNS 型端點存取控制層,請採用下列格式:

    apiVersion: v1
    kind: Config
    clusters:
    - name: CLUSTER_NAME
      cluster:
        server: https://endpoint
    users:
    - name: ci-cd-pipeline-gsa
      user:
        exec:
          apiVersion: client.authentication.k8s.io/v1beta1
          args:
          - --use_application_default_credentials
          command: gke-gcloud-auth-plugin
          installHint: Install gke-gcloud-auth-plugin for kubectl by following
            https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-access-for-kubectl#install_plugin
          provideClusterInfo: true
    contexts:
    - context:
        cluster: CLUSTER_NAME
        user: ci-cd-pipeline-gsa
      name: CLUSTER_NAME-ci-cd
    current-context: CLUSTER_NAME-ci-cd
    

    更改下列內容:

    • CLUSTER_NAME:叢集名稱。
    • endpoint:您在先前步驟中取得的 endpoint 值。

    如果您使用以 IP 為基礎的端點存取控制平面,請在 kubeconfig.yaml 檔案的 cluster 參數中,新增您在上一個步驟中取得的 clusterCaCertificate 值:

    apiVersion: v1
    kind: Config
    clusters:
    - name: CLUSTER_NAME
      cluster:
        server: https://endpoint
        certificate-authority-data: masterAuth.clusterCaCertificate
    users:
    ...
    

    您不需要解碼 Base64 編碼的憑證。

  6. 在環境中,將 kubeconfig.yamlgsa-key.json 與應用程式一併部署。在執行階段,於執行應用程式的環境中設定下列環境變數:

    export KUBECONFIG=path/to/kubeconfig.yaml
    export GOOGLE_APPLICATION_CREDENTIALS=path/to/gsa-key.json
    
  7. 現在應用程式可以將要求傳送至 Kubernetes API,並以 IAM 服務帳戶的身分通過驗證。

更新舊版驗證方法

在 GKE 與 OAuth 整合之前,預先佈建的 X.509 憑證或靜態密碼是唯一可用的驗證方法,但現在我們不建議使用以上方法,且應停用。這些方法會擴大叢集遭入侵的攻擊面,因此執行 GKE 1.12 以上版本的叢集預設會停用這些方法。如果您使用舊版驗證方法,建議關閉這些方法。

如果啟用這項設定,具備 container.clusters.getCredentials 權限的使用者就能擷取用戶端憑證和靜態密碼。roles/container.adminroles/ownerroles/editor 這三種角色都具備該權限,因此請謹慎使用這類角色。進一步瞭解 GKE 中的 IAM 角色

停用靜態密碼驗證

靜態密碼就是使用者名稱和密碼的組合,API 伺服器會對該組合進行驗證。在 GKE 中,這種驗證方法稱為基本驗證。

更新現有叢集並移除靜態密碼:

gcloud container clusters update CLUSTER_NAME \
     --location=CONTROL_PLANE_LOCATION \
     --no-enable-basic-auth

停用用戶端憑證驗證

如果使用憑證驗證,用戶端會提出憑證,而 API 伺服器會以指定的憑證授權單位對該憑證進行驗證。在 GKE 中,叢集根憑證授權單位 (CA) 會簽署用戶端憑證。

用戶端憑證驗證會影響 Kubernetes API 伺服器的授權。如果叢集已啟用舊版屬性式存取控管 (ABAC) 授權,用戶端憑證預設可通過驗證,並在 API 伺服器上執行任何動作。另一方面,啟用角色型存取控管 (RBAC) 後,就必須將 Kubernetes 資源的特定授權授予用戶端憑證。

如要建立叢集而不產生用戶端憑證,請使用 --no-issue-client-certificate 標記:

gcloud container clusters create CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION
    --no-issue-client-certificate

目前沒有方法可從現有叢集移除用戶端憑證。如要在現有叢集上停止使用用戶端憑證驗證,請務必在叢集上啟用 RBAC,並確保用戶端憑證在叢集上沒有任何授權。

後續步驟