本頁面說明如何從 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 方法驗證叢集,請執行下列操作:
使用憑證登入 gcloud CLI。系統會開啟網路瀏覽器,完成 Google Cloud的驗證程序:
gcloud auth login
擷取特定叢集的 Kubernetes 憑證:
gcloud container clusters get-credentials CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION
更改下列內容:
CLUSTER_NAME
:叢集名稱。CONTROL_PLANE_LOCATION
:叢集控制層的 Compute Engine 位置。為地區叢集提供地區,或為區域叢集提供區域。
確認您已通過驗證:
kubectl cluster-info
當使用者或 Google Cloud 服務帳戶通過驗證之後,還必須「獲得授權」才能對 GKE 叢集進行任何動作。如要進一步瞭解如何設定授權,請參閱角色型存取權控管。
驗證應用程式
您也可以從 Pod 中的應用程式向 API 伺服器進行驗證,不必與使用者互動,例如從 CI/CD 管道中的指令碼進行驗證。達成目標的方式取決於應用程式的執行環境。
同一叢集中的應用程式
如果應用程式在同一個 GKE 叢集中執行,請使用 Kubernetes 服務帳戶進行驗證。
建立 Kubernetes 服務帳戶,並附加至 Pod。如果 Pod 已經有 Kubernetes 服務帳戶,或是您想使用命名空間的預設服務帳戶,請略過這個步驟。
使用 Kubernetes RBAC 將應用程式所需的權限授予 Kubernetes 服務帳戶。
以下範例會將
prod
命名空間中資源的view
權限,授予cicd-ns
命名空間中名為cicd
的服務帳戶:kubectl create rolebinding cicd-secret-viewer \ --namespace=prod \ --clusterrole=view \ --serviceaccount=cicd-ns:cicd
在執行階段,當應用程式傳送 Kubernetes API 要求時,API 伺服器會驗證服務帳戶憑證。
應用程式 Google Cloud
如果應用程式在目標叢集內 Google Cloud 但外部執行 (例如 Compute Engine VM 或其他 GKE 叢集),您應使用環境中可用的 IAM 服務帳戶憑證,向 API 伺服器進行驗證。
將 IAM 服務帳戶指派給環境。如果應用程式是在 Compute Engine VM 內執行,請將 IAM 服務帳戶指派給執行個體。如果應用程式在其他 GKE 叢集中執行,請使用 Workload Identity Federation for GKE,將 Pod 設為以 IAM 服務帳戶身分執行。
下列範例使用
ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com
做為 IAM 服務帳戶。授予 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
旗標。擷取叢集憑證:
gcloud container clusters get-credentials CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION
系統會使用環境中設定的 IAM 服務帳戶,自動驗證您的應用程式。
其他環境中的應用程式
如果應用程式是從Google Cloud以外的環境進行驗證,就無法存取受管理的 IAM 服務帳戶憑證。如要擷取叢集憑證,您可以建立 IAM 服務帳戶、下載其金鑰,並在執行階段從服務使用該金鑰,透過 gcloud CLI 擷取叢集憑證。
為應用程式建立 IAM 服務帳戶。如果您已有 IAM 服務帳戶,請略過這個步驟。
下列指令會建立名為
ci-cd-pipeline
的 IAM 服務帳戶:gcloud iam service-accounts create ci-cd-pipeline
將叢集存取權授予 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
旗標。建立並下載 IAM 服務帳戶的金鑰。在執行階段提供給應用程式:
gcloud iam service-accounts keys create gsa-key.json \ --iam-account=ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com
在執行階段,於執行應用程式的環境中,使用 IAM 服務帳戶金鑰向 gcloud CLI 進行驗證:
gcloud auth activate-service-account ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com \ --key-file=gsa-key.json
使用 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 檔案,向叢集進行驗證:
為應用程式建立 IAM 服務帳戶。如果您已有 IAM 服務帳戶,請略過這個步驟。
下列指令會建立名為
ci-cd-pipeline
的 IAM 服務帳戶:gcloud iam service-accounts create ci-cd-pipeline
將叢集存取權授予 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 角色,精細控管授予的權限。
建立並下載 IAM 服務帳戶的金鑰。
在以下範例中,金鑰檔案名為
gsa-key.json
:gcloud iam service-accounts keys create gsa-key.json \ --iam-account=ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com
如果您使用 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)"
建立
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 編碼的憑證。
在環境中,將
kubeconfig.yaml
和gsa-key.json
與應用程式一併部署。在執行階段,於執行應用程式的環境中設定下列環境變數:export KUBECONFIG=path/to/kubeconfig.yaml export GOOGLE_APPLICATION_CREDENTIALS=path/to/gsa-key.json
現在應用程式可以將要求傳送至 Kubernetes API,並以 IAM 服務帳戶的身分通過驗證。
更新舊版驗證方法
在 GKE 與 OAuth 整合之前,預先佈建的 X.509 憑證或靜態密碼是唯一可用的驗證方法,但現在我們不建議使用以上方法,且應停用。這些方法會擴大叢集遭入侵的攻擊面,因此執行 GKE 1.12 以上版本的叢集預設會停用這些方法。如果您使用舊版驗證方法,建議關閉這些方法。
如果啟用這項設定,具備 container.clusters.getCredentials
權限的使用者就能擷取用戶端憑證和靜態密碼。roles/container.admin
、roles/owner
和 roles/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,並確保用戶端憑證在叢集上沒有任何授權。
後續步驟
- 瞭解Google Cloud 驗證。
- 瞭解 GKE 中的存取權控管。
- 瞭解 Google 服務帳戶。
- 瞭解 GKE 適用的工作負載身分聯盟。
- 瞭解如何強化叢集的安全防護機制