使用 Envoy 和負載平衡 API (舊版) 設定服務安全性
請按照本指南中的操作說明,為使用 Cloud Service Mesh 和 Envoy Proxy 部署的服務,設定驗證和授權,並使用負載平衡 API。如果您使用服務路由 API,請參閱使用 Envoy 設定服務安全性。
如需完整資訊,請參閱「使用負載平衡 API 保護 Cloud Service Mesh 服務」。
本文適用於使用負載平衡 API 的設定。這是舊版文件。
需求條件
使用 Envoy 為 Cloud Service Mesh 設定服務安全性之前,請確認您的設定是否符合下列先決條件:
請使用 Envoy 1.20.0 以上版本的 xDS v3 API。
您可以滿足部署 Cloud Service Mesh 的所有必要條件。如需這些需求的完整資訊,請參閱「準備使用 Envoy 設定 Cloud Service Mesh」。
您具備足夠的權限,可建立或更新 Cloud Service Mesh 和Google Cloud 服務網格資源,以便使用服務安全性,如「準備使用 Envoy 設定 Cloud Service Mesh」一文所述。
準備設定
以下各節說明設定 Cloud Service Mesh 安全性服務前,需要完成的任務。這些工作包括:
- 更新 Google Cloud CLI
- 設定變數
- 啟用 Cloud Service Mesh 與憑證授權單位服務搭配運作所需的 API
更新 gcloud
指令列工具
如要更新 Google Cloud CLI,請在本機電腦上執行以下指令:
gcloud components update
設定變數
設定下列變數,以便您在本文件的範例中複製及貼上含有一致值的程式碼。請使用下列值。
- PROJECT_ID:請替換為專案 ID。
- CLUSTER_NAME:請替換為您要提供給我們的叢集名稱,例如
secure-td-cluster
。 - ZONE:請替換叢集所在的可用區。
- GKE_CLUSTER_URL:替換
https://container.googleapis.com/v1/projects/PROJECT_ID/locations/ZONE/clusters/CLUSTER_NAME
- WORKLOAD_POOL:替換
PROJECT_ID.svc.id.goog
- K8S_NAMESPACE:替換
default
。 - DEMO_CLIENT_KSA:請替換為您的用戶端 Kubernetes 服務帳戶名稱。
- DEMO_SERVER_KSA:請替換為伺服器 Kubernetes 服務帳戶的名稱。
PROJNUM:請將專案編號替換為您的專案編號,您可以透過 Google Cloud 主控台或以下指令判斷:
gcloud projects describe PROJECT_ID --format="value(projectNumber)"
SA_GKE:替換
service-PROJNUM@container-engine-robot.iam.gserviceaccount.com
CLUSTER_VERSION:替換可用的最新版本。您可以參閱快速版版本資訊。最低版本需求為 1.21.4-gke.1801。這是本例中要使用的 GKE 叢集版本。
請在此處設定值:
# Substitute your project ID PROJECT_ID=PROJECT_ID # GKE cluster name and zone for this example. CLUSTER_NAME=CLUSTER_NAME ZONE=ZONE # GKE cluster URL derived from the above GKE_CLUSTER_URL="https://container.googleapis.com/v1/projects/PROJECT_ID/locations/ZONE/clusters/CLUSTER_NAME" # Workload pool to be used with the GKE cluster WORKLOAD_POOL="PROJECT_ID.svc.id.goog" # Kubernetes namespace to run client and server demo. K8S_NAMESPACE=K8S_NAMESPACE DEMO_CLIENT_KSA=DEMO_CLIENT_KSA DEMO_SERVER_KSA=DEMO_SERVER_KSA # Compute other values # Project number for your project PROJNUM=PROJNUM CLUSTER_VERSION=CLUSTER_VERSION SA_GKE=service-PROJNUM@container-engine-robot.iam.gserviceaccount.com
啟用 API
使用 gcloud services enable
指令啟用所有 API,以便透過憑證授權單位服務設定 Cloud Service Mesh 安全性。
gcloud services enable \ container.googleapis.com \ cloudresourcemanager.googleapis.com \ compute.googleapis.com \ trafficdirector.googleapis.com \ networkservices.googleapis.com \ networksecurity.googleapis.com \ privateca.googleapis.com \ gkehub.googleapis.com
建立或更新 GKE 叢集
Cloud Service Mesh 服務安全性取決於 CA 服務與 GKE 的整合方式。除了設定需求外,GKE 叢集還必須符合下列條件:
- 叢集版本至少須為 1.21.4-gke.1801。如果您需要後續版本中的功能,可以透過快速發布管道取得該版本。
- 您必須啟用 GKE 叢集,並使用網格憑證進行設定,如建立憑證授權單位以核發憑證一文所述。
建立使用 Workload Identity Federation for GKE 的新叢集。如果您要更新現有叢集,請跳至下一個步驟。您為
--tags
提供的值必須與 使用 Cloud Load Balancing 元件設定 Cloud Service Mesh 一節中,firewall-rules create
指令傳遞至--target-tags
標記的名稱相符。# Create a GKE cluster with GKE managed mesh certificates. gcloud container clusters create CLUSTER_NAME \ --release-channel=rapid \ --scopes=cloud-platform \ --image-type=cos_containerd \ --machine-type=e2-standard-2 \ --zone=ZONE \ --workload-pool=PROJECT_ID.svc.id.goog \ --enable-mesh-certificates \ --cluster-version=CLUSTER_VERSION \ --enable-ip-alias \ --tags=allow-health-checks \ --workload-metadata=GKE_METADATA
叢集建立作業可能需要幾分鐘才能完成。
如果您使用現有叢集,請啟用 Workload Identity Federation for GKE 和 GKE 網格憑證。請確認叢集是使用
--enable-ip-alias
旗標建立的,因為update
指令無法使用該旗標。gcloud container clusters update CLUSTER_NAME \ --enable-mesh-certificates
執行下列指令,將新叢集設為
kubectl
指令的預設叢集:gcloud container clusters get-credentials CLUSTER_NAME \ --zone ZONE
在多叢集環境中部署
如果您是在多叢集環境中進行部署,請按照本節所述的一般程序進行。這些操作說明假設用戶端 Pod 在一個叢集中執行,而伺服器 Pod 在另一個叢集中執行。
按照上一個章節的指示建立或更新叢集。
使用下列指令擷取各叢集的 Pod IP 位址範圍:
gcloud compute firewall-rules list \ --filter="name~gke-{CLUSTER_NAME}-[0-9a-z]*-all" \ --format="value(sourceRanges)"
舉例來說,如果叢集名稱為
cluster-a
和cluster-b
,指令會傳回以下結果:cluster-a, pod CIDR: 10.4.0.0/14, node network tag: gke-cluster-a-9cd18751-node cluster-b, pod CIDR: 10.8.0.0/14, node network tag: gke-cluster-b-acd14479-node
建立 VPC 防火牆規則,允許叢集彼此通訊。舉例來說,下列指令會建立防火牆規則,允許
cluster-a
容器 IP 位址與cluster-b
節點通訊:gcloud compute firewall-rules create per-cluster-a-pods \ --allow="tcp,udp,icmp,esp,ah,sctp" \ --target-tags="gke-cluster-b-acd14479-node"
下列指令會建立防火牆規則,允許
cluster-b
叢集 IP 位址與cluster-a
節點通訊:gcloud compute firewall-rules create per-cluster-b-pods \ --allow="tcp,udp,icmp,esp,ah,sctp" \ --target-tags="gke-cluster-a-9cd18751-node"
向機群註冊叢集
將您在「建立 GKE 叢集」中建立或更新的叢集註冊至機群。註冊叢集後,您就能更輕鬆地在多個專案中設定叢集。
請注意,每個步驟最多可能需要十分鐘才能完成。
向機群註冊叢集:
gcloud container fleet memberships register CLUSTER_NAME \ --gke-cluster=ZONE/CLUSTER_NAME \ --enable-workload-identity --install-connect-agent \ --manifest-output-file=MANIFEST-FILE_NAME
請依下列方式替換變數:
- CLUSTER_NAME:叢集名稱。
- ZONE:叢集所在的可用區。
- MANIFEST-FILE_NAME:這些指令產生註冊資訊清單的路徑。
註冊程序成功後,您會看到類似以下的訊息:
Finished registering the cluster CLUSTER_NAME with the fleet.
將產生的資訊清單檔案套用至叢集:
kubectl apply -f MANIFEST-FILE_NAME
申請程序成功後,您會看到類似以下的訊息:
namespace/gke-connect created serviceaccount/connect-agent-sa created podsecuritypolicy.policy/gkeconnect-psp created role.rbac.authorization.k8s.io/gkeconnect-psp:role created rolebinding.rbac.authorization.k8s.io/gkeconnect-psp:rolebinding created role.rbac.authorization.k8s.io/agent-updater created rolebinding.rbac.authorization.k8s.io/agent-updater created role.rbac.authorization.k8s.io/gke-connect-agent-20210416-01-00 created clusterrole.rbac.authorization.k8s.io/gke-connect-impersonation-20210416-01-00 created clusterrolebinding.rbac.authorization.k8s.io/gke-connect-impersonation-20210416-01-00 created clusterrolebinding.rbac.authorization.k8s.io/gke-connect-feature-authorizer-20210416-01-00 created rolebinding.rbac.authorization.k8s.io/gke-connect-agent-20210416-01-00 created role.rbac.authorization.k8s.io/gke-connect-namespace-getter created rolebinding.rbac.authorization.k8s.io/gke-connect-namespace-getter created secret/http-proxy created deployment.apps/gke-connect-agent-20210416-01-00 created service/gke-connect-monitoring created secret/creds-gcp create
從叢集取得會員資源:
kubectl get memberships membership -o yaml
輸出內容應包含車隊指派的工作負載身分池,其中 PROJECT_ID 是您的專案 ID:
workload_identity_pool: PROJECT_ID.svc.id.goog
這表示叢集已成功註冊。
建立憑證授權單位以核發憑證
如要為 Pod 核發憑證,請建立 CA 服務集區和下列憑證授權單位 (CA):
- 根 CA。這是所有核發的 Mesh 憑證的信任根。如果您有現有的根 CA,可以使用該 CA。在
enterprise
層級建立根 CA,這類 CA 適用於長期且數量較少的憑證核發作業。 - 從屬 CA。這個 CA 會為工作負載核發憑證。在部署叢集的區域中建立子 CA。在
devops
層級建立子 CA,這類 CA 用於核發短期大量憑證。
建立從屬 CA 是可選的做法,但我們強烈建議您建立一個,而非使用根 CA 核發 GKE 網格憑證。如果您決定使用根 CA 核發網格憑證,請確認預設的以設定為準核發模式仍可使用。
子 CA 可以位於與叢集不同的區域,但我們強烈建議您在與叢集相同的區域中建立子 CA,以便提升效能。不過,您可以在不同的區域建立根 CA 和從屬 CA,不會影響效能或可用性。
CA 服務支援以下地區:
地區名稱 | 地區說明 |
---|---|
asia-east1 |
台灣 |
asia-east2 |
香港 |
asia-northeast1 |
東京 |
asia-northeast2 |
大阪 |
asia-northeast3 |
首爾 |
asia-south1 |
孟買 |
asia-south2 |
德里 |
asia-southeast1 |
新加坡 |
asia-southeast2 |
雅加達 |
australia-southeast1 |
雪梨 |
australia-southeast2 |
墨爾本 |
europe-central2 |
華沙 |
europe-north1 |
芬蘭 |
europe-southwest1 |
馬德里 |
europe-west1 |
比利時 |
europe-west2 |
倫敦 |
europe-west3 |
法蘭克福 |
europe-west4 |
荷蘭 |
europe-west6 |
蘇黎世 |
europe-west8 |
米蘭 |
europe-west9 |
巴黎 |
europe-west10 |
柏林 |
europe-west12 |
杜林 |
me-central1 |
杜哈 |
me-central2 |
達曼 |
me-west1 |
特拉維夫市 |
northamerica-northeast1 |
蒙特婁 |
northamerica-northeast2 |
多倫多 |
southamerica-east1 |
聖保羅 |
southamerica-west1 |
聖地亞哥 |
us-central1 |
愛荷華州 |
us-east1 |
南卡羅來納州 |
us-east4 |
北維吉尼亞州 |
us-east5 |
哥倫布 |
us-south1 |
達拉斯 |
us-west1 |
奧勒岡州 |
us-west2 |
洛杉磯 |
us-west3 |
鹽湖城 |
us-west4 |
拉斯維加斯 |
您也可以執行下列指令,查看支援的位置清單:
gcloud privateca locations list
將 IAM
roles/privateca.caManager
授予建立 CA 集區和 CA 的使用者。請注意,MEMBER 的正確格式為user:userid@example.com
。如果該使用者是目前的使用者,您可以使用殼層指令$(gcloud auth list --filter=status:ACTIVE --format="value(account)")
取得目前的使用者 ID。gcloud projects add-iam-policy-binding PROJECT_ID \ --member=MEMBER \ --role=roles/privateca.caManager
將 CA 服務的
role/privateca.admin
角色授予需要修改 IAM 政策的使用者,其中MEMBER
是需要此存取權的使用者,具體來說,是指執行下列授予privateca.auditor
和privateca.certificateManager
角色步驟的任何使用者:gcloud projects add-iam-policy-binding PROJECT_ID \ --member=MEMBER \ --role=roles/privateca.admin
建立根 CA 服務集區。
gcloud privateca pools create ROOT_CA_POOL_NAME \ --location ROOT_CA_POOL_LOCATION \ --tier enterprise
建立根 CA。
gcloud privateca roots create ROOT_CA_NAME --pool ROOT_CA_POOL_NAME \ --subject "CN=ROOT_CA_NAME, O=ROOT_CA_ORGANIZATION" \ --key-algorithm="ec-p256-sha256" \ --max-chain-length=1 \ --location ROOT_CA_POOL_LOCATION
在這個示範設定中,請使用下列值做為變數:
- ROOT_CA_POOL_NAME=td_sec_pool
- ROOT_CA_NAME=pkcs2-ca
- ROOT_CA_POOL_LOCATION=us-east1
- ROOT_CA_ORGANIZATION="TestCorpLLC"
建立從屬集區和從屬 CA。確認預設的設定為發布模式仍可使用。
gcloud privateca pools create SUBORDINATE_CA_POOL_NAME \ --location SUBORDINATE_CA_POOL_LOCATION \ --tier devops
gcloud privateca subordinates create SUBORDINATE_CA_NAME \ --pool SUBORDINATE_CA_POOL_NAME \ --location SUBORDINATE_CA_POOL_LOCATION \ --issuer-pool ROOT_CA_POOL_NAME \ --issuer-location ROOT_CA_POOL_LOCATION \ --subject "CN=SUBORDINATE_CA_NAME, O=SUBORDINATE_CA_ORGANIZATION" \ --key-algorithm "ec-p256-sha256" \ --use-preset-profile subordinate_mtls_pathlen_0
在這個示範設定中,請使用下列值做為變數:
- SUBORDINATE_CA_POOL_NAME="td-ca-pool"
- SUBORDINATE_CA_POOL_LOCATION=us-east1
- SUBORDINATE_CA_NAME="td-ca"
- SUBORDINATE_CA_ORGANIZATION="TestCorpLLC"
- ROOT_CA_POOL_NAME=td_sec_pool
- ROOT_CA_POOL_LOCATION=us-east1
授予根 CA 集區的 IAM
privateca.auditor
角色,允許 GKE 服務帳戶存取:gcloud privateca pools add-iam-policy-binding ROOT_CA_POOL_NAME \ --location ROOT_CA_POOL_LOCATION \ --role roles/privateca.auditor \ --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
為子 CA 資源池授予 IAM
privateca.certificateManager
角色,允許 GKE 服務帳戶存取:gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_NAME \ --location SUBORDINATE_CA_POOL_LOCATION \ --role roles/privateca.certificateManager \ --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
儲存下列
WorkloadCertificateConfig
YAML 設定,告訴叢集如何核發網格憑證:apiVersion: security.cloud.google.com/v1 kind: WorkloadCertificateConfig metadata: name: default spec: # Required. The CA service that issues your certificates. certificateAuthorityConfig: certificateAuthorityServiceConfig: endpointURI: ISSUING_CA_POOL_URI # Required. The key algorithm to use. Choice of RSA or ECDSA. # # To maximize compatibility with various TLS stacks, your workloads # should use keys of the same family as your root and subordinate CAs. # # To use RSA, specify configuration such as: # keyAlgorithm: # rsa: # modulusSize: 4096 # # Currently, the only supported ECDSA curves are "P256" and "P384", and the only # supported RSA modulus sizes are 2048, 3072 and 4096. keyAlgorithm: rsa: modulusSize: 4096 # Optional. Validity duration of issued certificates, in seconds. # # Defaults to 86400 (1 day) if not specified. validityDurationSeconds: 86400 # Optional. Try to start rotating the certificate once this # percentage of validityDurationSeconds is remaining. # # Defaults to 50 if not specified. rotationWindowPercentage: 50
更改下列內容:
- 叢集執行所在專案的專案 ID:
PROJECT_ID
- 核發網格憑證 (ISSUING_CA_POOL_URI) 的 CA 完整 URI。這可以是從屬 CA (建議) 或根 CA。格式如下:
//privateca.googleapis.com/projects/PROJECT_ID/locations/SUBORDINATE_CA_POOL_LOCATION/caPools/SUBORDINATE_CA_POOL_NAME
- 叢集執行所在專案的專案 ID:
儲存下列
TrustConfig
YAML 設定,告訴叢集如何信任核發的憑證:apiVersion: security.cloud.google.com/v1 kind: TrustConfig metadata: name: default spec: # You must include a trustStores entry for the trust domain that # your cluster is enrolled in. trustStores: - trustDomain: PROJECT_ID.svc.id.goog # Trust identities in this trustDomain if they appear in a certificate # that chains up to this root CA. trustAnchors: - certificateAuthorityServiceURI: ROOT_CA_POOL_URI
更改下列內容:
- 叢集執行所在專案的專案 ID:
PROJECT_ID
- 根 CA 集區 (ROOT_CA_POOL_URI) 的完整 URI。格式如下:
//privateca.googleapis.com/projects/PROJECT_ID/locations/ROOT_CA_POOL_LOCATION/caPools/ROOT_CA_POOL_NAME
- 叢集執行所在專案的專案 ID:
將設定套用至叢集:
kubectl apply -f WorkloadCertificateConfig.yaml kubectl apply -f TrustConfig.yaml
設定身分與存取權管理
如要建立設定所需的資源,您必須具備 compute.NetworkAdmin
角色。這個角色包含所有必要權限,可用於建立、更新、刪除、列出及使用 (也就是在其他資源中參照) 必要資源。如果您是專案的擁有者/編輯者,就會自動獲得這個角色。
請注意,如果您在後端服務和目標 HTTPS Proxy 資源中參照這些資源,系統就不會強制執行 networksecurity.googleapis.com.clientTlsPolicies.use
和 networksecurity.googleapis.com.serverTlsPolicies.use
。
如果日後強制執行這些權限,且您使用的是 compute.NetworkAdmin
角色,則在強制執行這項檢查時,您不會發現任何問題。
如果您使用的是自訂角色,且日後會強制執行這項檢查,請務必加入相應的 .use
權限。否則,您日後可能會發現自訂角色沒有必要的權限,無法分別從後端服務或指定的 HTTPS Proxy 參照 clientTlsPolicy
或 serverTlsPolicy
。
下列操作說明可讓預設服務帳戶存取 Cloud Service Mesh Security API,並建立 Kubernetes 服務帳戶。
設定 IAM,允許預設服務帳戶存取 Cloud Service Mesh 安全性 API。
GSA_EMAIL=$(gcloud iam service-accounts list --format='value(email)' \ --filter='displayName:Compute Engine default service account') gcloud projects add-iam-policy-binding PROJECT_ID \ --member serviceAccount:${GSA_EMAIL} \ --role roles/trafficdirector.client
設定 Kubernetes 服務帳戶。以下各節中的用戶端和伺服器部署作業會使用 Kubernetes 伺服器和用戶端服務帳戶的 Kname。
kubectl create serviceaccount --namespace K8S_NAMESPACE DEMO_SERVER_KSA kubectl create serviceaccount --namespace K8S_NAMESPACE DEMO_CLIENT_KSA
在兩者之間建立 IAM 政策繫結,允許 Kubernetes 服務帳戶冒用預設 Compute Engine 服務帳戶。這個繫結可讓 Kubernetes 服務帳戶充當預設的 Compute Engine 服務帳戶。
gcloud iam service-accounts add-iam-policy-binding \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/DEMO_SERVER_KSA]" ${GSA_EMAIL} gcloud iam service-accounts add-iam-policy-binding \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/DEMO_CLIENT_KSA]" ${GSA_EMAIL}
為 Kubernetes 服務帳戶加上註解,將這些帳戶與預設的 Compute Engine 服務帳戶建立關聯。
kubectl annotate --namespace K8S_NAMESPACE \ serviceaccount DEMO_SERVER_KSA \ iam.gke.io/gcp-service-account=${GSA_EMAIL} kubectl annotate --namespace K8S_NAMESPACE \ serviceaccount DEMO_CLIENT_KSA \ iam.gke.io/gcp-service-account=${GSA_EMAIL}
設定 Cloud Service Mesh
請按照下列操作說明安裝側邊插入器、設定測試服務,並完成其他部署作業。
在叢集中安裝 Envoy 附加元件注入器
請參閱「為 GKE Pod 設定 Cloud Service Mesh,並自動注入 Envoy」一文的以下兩個部分,按照指示在叢集中部署並啟用 Envoy 附屬程式注入功能:
請務必先完成這兩組操作說明,再設定測試服務。
設定測試服務
安裝 Envoy 附加元件注入器後,請按照下列操作說明為部署作業設定測試服務。
wget -q -O - https://storage.googleapis.com/traffic-director/security/ga/service_sample.yaml | sed -e s/DEMO_SERVER_KSA_PLACEHOLDER/DEMO_SERVER_KSA/g > service_sample.yaml kubectl apply -f service_sample.yaml
service_sample.yaml
檔案包含示範伺服器應用程式的 podspec。有些註解是 Cloud Service Mesh 安全性專用。
Cloud Service Mesh 代理中繼資料
Podspec 會指定 proxyMetadata
註解:
spec: ... annotations: cloud.google.com/proxyMetadata: '{"app": "payments"}' ...
在 Pod 初始化時,側邊代理會擷取這個註解,並傳送至 Cloud Service Mesh。接著,Cloud Service Mesh 就能使用這項資訊,傳回經過篩選的設定:
- 請注意,本指南後續章節會說明端點政策如何指定端點比對工具。
- 端點比對器會指定只有名稱為
app
且值為payments
的標籤提供者,才能收到篩選後的設定。
使用由 CA 服務簽署的網格憑證和金鑰
Podspec 會指定 enableManagedCerts
註解:
spec: ... annotations: ... cloud.google.com/enableManagedCerts: "true" ...
初始化 Pod 時,CA 服務簽署的憑證和金鑰會自動掛載至本機 Sidecar 代理檔案系統。
設定內送流量攔截埠
Podspec 會指定 includeInboundPorts
註解:
spec: ... annotations: ... cloud.google.com/includeInboundPorts: "8000" ...
這是伺服器應用程式用來監聽連線的通訊埠。在 Pod 初始化時,附加元件 Proxy 會擷取這項註解,並傳送至 Cloud Service Mesh。接著,Cloud Service Mesh 會使用這項資訊傳回經過篩選的設定,藉此攔截傳入這個連接埠的所有流量,並套用安全性政策。
健康狀態檢查通訊埠必須與應用程式通訊埠不同。否則,相同的安全政策會套用至健康檢查通訊埠的傳入連線,這可能導致連線遭拒,進而導致伺服器誤認為處於不良狀態。
設定 NEG 適用的 GKE 服務
GKE 服務必須透過網路端點群組 (NEG) 公開,才能將這些服務設為 Cloud Service Mesh 後端服務的後端。本設定指南提供的 service_sample.yaml
套件會使用下列註解中的 NEG 名稱 service-test-neg
:
... metadata: annotations: cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "service-test-neg"}}}' spec: ports: - port: 80 name: service-test protocol: TCP targetPort: 8000
您不需要變更 service_sample.yaml
檔案。
儲存 NEG 的名稱
在 NEG_NAME 變數中儲存 NEG 名稱:
NEG_NAME="service-test-neg"
將用戶端應用程式部署至 GKE
執行下列指令,以 Envoy 代理程式做為附屬程式,啟動示範用途的用戶端,您需要示範安全性功能。
wget -q -O - https://storage.googleapis.com/traffic-director/security/ga/client_sample.yaml | sed -e s/DEMO_CLIENT_KSA_PLACEHOLDER/DEMO_CLIENT_KSA/g > client_sample.yaml kubectl apply -f client_sample.yaml
用戶端 Podspec 只包含 enableManagedCerts
註解。這項設定是為了為 GKE 管理的網格憑證和金鑰 (由 CA 服務執行個體簽署) 掛接必要的磁碟區。
設定 Cloud Service Mesh Google Cloud 資源
請按照「使用 Cloud Load Balancing 元件設定 Cloud Service Mesh」中的步驟操作。請務必確認範例用戶端的流量會轉送至範例服務。
Cloud Service Mesh 設定已完成,現在您可以設定驗證和授權政策。
設定服務對服務安全性
請按照下列各節的操作說明,設定服務對服務安全性。
在網格中啟用 mTLS
如要在網格中設定 mTLS,您必須保護傳往後端服務的傳出流量,以及傳往端點的傳入流量。
政策參照資料格式
請注意,如要參照伺服器 TLS、用戶端 TLS 和授權政策,請使用下列必要格式:
projects/PROJECT_ID/locations/global/[serverTlsPolicies|clientTlsPolicies|authorizationPolicies]/[server-tls-policy|client-mtls-policy|authz-policy]
例如:
projects/PROJECT_ID/locations/global/serverTlsPolicies/server-tls-policy
projects/PROJECT_ID/locations/global/clientTlsPolicies/client-mtls-policy
projects/PROJECT_ID/locations/global/authorizationPolicies/authz-policy
保護傳出至後端服務的流量
如要保護外送流量,請先建立用戶端 TLS 政策,執行下列操作:
- 使用
google_cloud_private_spiffe
做為clientCertificate
的外掛程式,讓 Envoy 程式使用 GKE 管理的 Mesh 憑證做為用戶端身分。 - 使用
google_cloud_private_spiffe
做為serverValidationCa
的外掛程式,讓 Envoy 程式使用 GKE 管理的網格憑證進行伺服器驗證。
接下來,您將用戶端 TLS 政策附加至後端服務。這會執行以下操作:
- 將用戶端 TLS 政策的驗證政策套用至後端服務端點的傳出連線。
- SAN (主體別名) 會指示用戶端宣告連線的伺服器確切身分。
在檔案
client-mtls-policy.yaml
中建立用戶端的傳輸層安全標準 (TLS) 政策:name: "client-mtls-policy" clientCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe serverValidationCa: - certificateProviderInstance: pluginInstance: google_cloud_private_spiffe
匯入用戶端的 TLS 政策:
gcloud network-security client-tls-policies import client-mtls-policy \ --source=client-mtls-policy.yaml --location=global
將用戶端 TLS 政策附加至後端服務。這會針對從用戶端傳送至此後端服務的所有連出要求,強制執行 mTLS 驗證。
gcloud compute backend-services export td-gke-service \ --global --destination=demo-backend-service.yaml
在
demo-backend-service.yaml
中附加以下行:securitySettings: clientTlsPolicy: projects/PROJECT_ID/locations/global/clientTlsPolicies/client-mtls-policy subjectAltNames: - "spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA"
匯入值:
gcloud compute backend-services import td-gke-service \ --global --source=demo-backend-service.yaml
您可以選擇執行下列指令,檢查要求是否失敗。這是預期的失敗情形,因為用戶端預期端點會提供憑證,但端點並未設定安全性政策。
# Get the name of the Podrunning Busybox. BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}') # Command to execute that tests connectivity to the service service-test. TEST_CMD="wget -q -O - service-test; echo" # Execute the test command on the pod. kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"
您會看到類似以下的輸出內容:
wget: server returned error: HTTP/1.1 503 Service Unavailable
保護端點的傳入流量
如要保護傳入流量,請先建立伺服器 TLS 政策,執行下列操作:
- 使用
google_cloud_private_spiffe
做為serverCertificate
的外掛程式,讓 Envoy 程式使用 GKE 管理的 Mesh 憑證做為伺服器身分。 - 使用
google_cloud_private_spiffe
做為clientValidationCa
的外掛程式,讓 Envoy 程式使用 GKE 管理的 Mesh 憑證進行用戶端驗證。
將伺服器 TLS 政策值儲存至名為
server-mtls-policy.yaml
的檔案中。name: "server-mtls-policy" serverCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe mtlsPolicy: clientValidationCa: - certificateProviderInstance: pluginInstance: google_cloud_private_spiffe
建立伺服器 TLS 政策:
gcloud network-security server-tls-policies import server-mtls-policy \ --source=server-mtls-policy.yaml --location=global
建立名為
ep_mtls.yaml
的檔案,其中包含端點比對器,並附加伺服器 TLS 政策。endpointMatcher: metadataLabelMatcher: metadataLabelMatchCriteria: MATCH_ALL metadataLabels: - labelName: app labelValue: payments name: "ep" serverTlsPolicy: projects/PROJECT_ID/locations/global/serverTlsPolicies/server-mtls-policy type: SIDECAR_PROXY
匯入端點比對器。
gcloud network-services endpoint-policies import ep \ --source=ep_mtls.yaml --location=global
驗證設定
執行下列 curl
指令。如果要求順利完成,您會在輸出內容中看到 x-forwarded-client-cert
。只有在連線為 mTLS 連線時,系統才會列印標頭。
# Get the name of the Podrunning Busybox. BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}') # Command to execute that tests connectivity to the service service-test. TEST_CMD="wget -q -O - service-test; echo" # Execute the test command on the pod. kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"
您會看到類似以下的輸出內容:
GET /get HTTP/1.1 Host: service-test content-length: 0 x-envoy-internal: true accept: */* x-forwarded-for: 10.48.0.6 x-envoy-expected-rq-timeout-ms: 15000 user-agent: curl/7.35.0 x-forwarded-proto: http x-request-id: redacted x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
請注意,x-forwarded-client-cert
標頭是由伺服器端 Envoy 插入,並包含其自身的識別資訊 (伺服器) 和來源用戶端的識別資訊。因為我們同時看到用戶端和伺服器的 ID,因此這是 mTLS 連線的信號。
使用授權政策設定服務層級存取權
這些操作說明會建立授權政策,允許 DEMO_CLIENT_KSA
帳戶傳送要求,其中主機名稱為 service-test
、通訊埠為 8000
,且 HTTP 方法為 GET
。建立授權政策前,請先詳閱「使用授權限制存取權」中的警告。
建立名為
authz-policy.yaml
的檔案,以建立授權政策。action: ALLOW name: authz-policy rules: - sources: - principals: - spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA destinations: - hosts: - service-test ports: - 8000 methods: - GET
匯入政策:
gcloud network-security authorization-policies import authz-policy \ --source=authz-policy.yaml \ --location=global
將下列內容附加至檔案
ep_mtls.yaml
,藉此更新端點政策,以便參照新的授權政策:authorizationPolicy: projects/PROJECT_ID/locations/global/authorizationPolicies/authz-policy
端點政策現在會指定,針對 Pod 的傳入要求,必須同時套用 mTLS 和授權政策,且 Envoy 附屬代理程式會顯示標籤
app:payments
。匯入政策:
gcloud network-services endpoint-policies import ep \ --source=ep_mtls.yaml --location=global
驗證設定
執行下列指令,驗證設定。
# Get the name of the Podrunning Busybox. BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}') # Command to execute that tests connectivity to the service service-test. # This is a valid request and will be allowed. TEST_CMD="wget -q -O - service-test; echo" # Execute the test command on the pod. kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"
預期的輸出內容如下所示:
GET /get HTTP/1.1 Host: service-test content-length: 0 x-envoy-internal: true accept: */* x-forwarded-for: redacted x-envoy-expected-rq-timeout-ms: 15000 user-agent: curl/7.35.0 x-forwarded-proto: http x-request-id: redacted x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
執行下列指令,測試授權政策是否正確拒絕無效要求:
# Failure case # Command to execute that tests connectivity to the service service-test. # This is an invalid request and server will reject because the server # authorization policy only allows GET requests. TEST_CMD="wget -q -O - service-test --post-data='' ; echo" # Execute the test command on the pod. kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"
預期的輸出內容如下所示:
<RBAC: access denied HTTP/1.1 403 Forbidden>
設定入站閘道安全性
本節假設您已完成服務與服務間的安全性部分,包括使用附加元件自動插入器設定 GKE 叢集、建立憑證授權單位,以及建立端點政策。
在本節中,您將部署 Envoy Proxy 做為入口網關,用於終止 TLS 連線,並授權叢集內部用戶端的要求。
如要設定入口網域閘道以終止 TLS,請按照下列步驟操作:
- 部署可透過叢集內部 IP 位址存取的 Kubernetes 服務。
- 部署作業包含獨立的 Envoy Proxy,會以 Kubernetes 服務的形式公開,並連線至 Cloud Service Mesh。
- 建立伺服器 TLS 政策來終止 TLS。
- 建立授權政策,授權傳入的請求。
將入口閘道服務部署至 GKE
執行下列指令,在 GKE 上部署入口網站閘道服務:
wget -q -O - https://storage.googleapis.com/traffic-director/security/ga/gateway_sample_xdsv3.yaml | sed -e s/PROJECT_NUMBER_PLACEHOLDER/PROJNUM/g | sed -e s/NETWORK_PLACEHOLDER/default/g | sed -e s/DEMO_CLIENT_KSA_PLACEHOLDER/DEMO_CLIENT_KSA/g > gateway_sample.yaml kubectl apply -f gateway_sample.yaml
gateway_sample.yaml
檔案是輸入閘道的規格。以下各節將說明規格新增的部分內容。
停用 Cloud Service Mesh 補充植入功能
gateway_sample.yaml
規格會將 Envoy Proxy 部署為唯一容器。在先前的步驟中,Envoy 會以附屬程式的方式注入應用程式容器。為避免有多個 Envoy 處理要求,您可以使用下列陳述式,為此 Kubernetes 服務停用附加元件注入:
sidecar.istio.io/inject: "false"
掛載正確的磁碟區
gateway_sample.yaml
規格會掛接磁碟區 gke-workload-certificates
。這個音量也用於側載器部署作業,但側載器注入器會在看到註解 cloud.google.com/enableManagedCerts: "true"
時自動新增此音量。gke-workload-certificates
磁碟區包含 GKE 管理的 SPIFFE 憑證和金鑰,這些憑證和金鑰是由您設定的 CA 服務執行個體簽署。
設定叢集的內部 IP 位址
使用類型為 ClusterInternal
的服務設定 ingress 閘道。這會為 mesh-gateway
建立可在內部解析的 DNS 主機名稱。當用戶端將要求傳送至 mesh-gateway:443
時,Kubernetes 會立即將要求轉送至輸入閘道 Envoy 部署的通訊埠 8080
。
在入口閘道上啟用 TLS
請按照以下操作說明,在輸入閘道上啟用 TLS。
建立伺服器 TLS 政策資源,以便終止 TLS 連線,並使用名為
server-tls-policy.yaml
的檔案中的值:description: tls server policy name: server-tls-policy serverCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe
匯入伺服器 TLS 政策:
gcloud network-security server-tls-policies import server-tls-policy \ --source=server-tls-policy.yaml --location=global
建立新的網址對應,將所有要求轉送至
td-gke-service
後端服務。入口網頁閘道會處理傳入的要求,並將其傳送至屬於td-gke-service
後端服務的 Pod。gcloud compute url-maps create td-gke-ig-url-map \ --default-service=td-gke-service
在
td-gke-https-proxy.yaml
檔案中建立新的目標 HTTPS Proxy,並附加先前建立的網址對應和伺服器 TLS 政策。這會設定 Envoy Proxy 入口閘道,以終止傳入的 TLS 流量。kind: compute#targetHttpsProxy name: td-gke-https-proxy proxyBind: true urlMap: https://www.googleapis.com/compute/beta/projects/PROJECT_ID/global/urlMaps/td-gke-ig-url-map serverTlsPolicy: projects/PROJECT_ID/locations/global/serverTlsPolicies/server-tls-policy
匯入政策:
gcloud compute target-https-proxies import td-gke-https-proxy \ --global --source=td-gke-https-proxy.yaml
建立新的轉送規則,並附加目標 HTTPS Proxy。這會將 Envoy Proxy 設為監聽通訊埠 8080,並套用
td-gke-https-proxy
中定義的路由和安全性政策。gcloud compute forwarding-rules create td-gke-gateway-forwarding-rule --global \ --load-balancing-scheme=INTERNAL_SELF_MANAGED --address=0.0.0.0 \ --target-https-proxy=td-gke-https-proxy --ports 8080 \ --network default
您可以選擇更新後端的授權政策,在符合下列所有條件時允許要求:
DEMO_CLIENT_KSA
傳送的要求。(入口網站閘道部署作業會使用DEMO_CLIENT_KSA
服務帳戶)。- 主機為
mesh-gateway
或service-test
的要求 - 通訊埠:
8000
除非您為後端設定授權政策,否則不需要執行這些指令。如果端點沒有授權政策,或是授權政策中沒有主機或來源主體比對,則系統會允許要求,而不需要執行這個步驟。將這些值新增至
authz-policy.yaml
。action: ALLOW name: authz-policy rules: - sources: - principals: - spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA destinations: - hosts: - service-test - mesh-gateway ports: - 8000 methods: - GET
匯入政策:
gcloud network-security authorization-policies import authz-policy \ --source=authz-policy.yaml \ --location=global
驗證輸入閘道部署
您可以使用名為 debug
的新容器,將要求傳送至入口閘道,以驗證部署作業。
在以下規格中,註解 "sidecar.istio.io/inject":"false"
會防止 Cloud Service Mesh 附屬元件插入器自動插入附屬元件 Proxy。沒有輔助程式可協助 debug
容器進行要求路由。容器必須連線至輸入閘道才能進行路由。
規格包含 --no-check-certificate
標記,可忽略伺服器憑證驗證。debug
容器沒有憑證授權單位驗證憑證,而憑證授權單位驗證憑證是 CA 服務簽署有效憑證時所需的憑證,這些憑證會用於由入口網關用來終止 TLS。
在實際工作環境中,建議您下載 CA 服務驗證憑證,並在用戶端上掛載或安裝。安裝驗證憑證後,請移除 wget
指令的 --no-check-certificate
選項。
執行下列指令:
kubectl run -i --tty --rm debug --image=busybox --restart=Never --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }' -- /bin/sh -c "wget --no-check-certificate -qS -O - https://mesh-gateway; echo"
您會看到與以下類似的輸出內容:
GET / HTTP/1.1 Host: 10.68.7.132 x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA x-envoy-expected-rq-timeout-ms: 15000 x-envoy-internal: true x-request-id: 5ae429e7-0e18-4bd9-bb79-4e4149cf8fef x-forwarded-for: 10.64.0.53 x-forwarded-proto: https content-length: 0 user-agent: Wget
執行下列負面測試指令:
# Negative test # Expect this to fail because gateway expects TLS. kubectl run -i --tty --rm debug --image=busybox --restart=Never --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }' -- /bin/sh -c "wget --no-check-certificate -qS -O - http://mesh-gateway:443/headers; echo"
畫面會顯示類似以下內容的輸出:
wget: error getting response: Connection reset by peer
執行下列負面測試指令:
# Negative test. # AuthorizationPolicy applied on the endpoints expect a GET request. Otherwise # the request is denied authorization. kubectl run -i --tty --rm debug --image=busybox --restart=Never --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }' -- /bin/sh -c "wget --no-check-certificate -qS -O - https://mesh-gateway --post-data=''; echo"
畫面會顯示類似以下內容的輸出:
HTTP/1.1 403 Forbidden wget: server returned error: HTTP/1.1 403 Forbidden
為輸入閘道設定授權政策
您在此處設定的授權政策可讓入口網關在符合下列所有條件時,允許將要求傳送至網格:
- 主機:
mesh-gateway
- 通訊埠:
8080
- path:
*
- HTTP 方法 GET
在
authz-gateway-policy.yaml
檔案中建立授權政策:action: ALLOW name: authz-gateway-policy rules: - destinations: - hosts: - mesh-gateway ports: - 8080 methods: - GET
匯入檔案中的值:
gcloud network-security authorization-policies import authz-gateway-policy \ --source=authz-gateway-policy.yaml --location=global
編輯
td-gke-https-proxy.yaml
檔案,並新增以下內容:authorizationPolicy: projects/PROJECT_ID/locations/global/authorizationPolicies/authz-gateway-policy
再次匯入 td-gke-https-proxy.yaml 檔案:
gcloud compute target-https-proxies import td-gke-https-proxy \ --global --source=td-gke-https-proxy.yaml
驗證部署作業
執行下列指令,驗證部署作業。
# On your localhost. kubectl run -i --tty --rm debug --image=busybox --restart=Never --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }' -- /bin/sh -c "wget --no-check-certificate -qS -O - https://mesh-gateway; echo"
畫面會顯示類似以下內容的輸出:
GET / HTTP/1.1 Host: 35.196.50.2 x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA x-envoy-expected-rq-timeout-ms: 15000 user-agent: curl/7.72.0 x-forwarded-proto: https content-length: 0 x-envoy-internal: true x-request-id: 98bec135-6df8-4082-8edc-b2c23609295a accept: */* x-forwarded-for: 10.142.0.7
執行下列負面測試指令:
# Negative test. Expect failure because only POST method is allowed by \ # authz-gateway-policy kubectl run -i --tty --rm debug --image=busybox --restart=Never --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }' -- /bin/sh -c "wget --no-check-certificate -qS -O - https://mesh-gateway/ --post-data=''; echo"
畫面會顯示類似以下內容的輸出:
wget: server returned error: HTTP/1.1 403 Forbidden
刪除部署作業
您可以選擇執行這些指令,刪除您使用本指南建立的部署。
如要刪除叢集,請執行下列指令:
gcloud container clusters delete CLUSTER_NAME --zone ZONE --quiet
如要刪除您建立的資源,請執行下列指令:
gcloud compute forwarding-rules delete td-gke-forwarding-rule --global --quiet gcloud compute forwarding-rules delete td-gke-gateway-forwarding-rule --global \ --quiet gcloud compute target-http-proxies delete td-gke-proxy --quiet gcloud compute target-https-proxies delete td-gke-https-proxy --quiet gcloud compute url-maps delete td-gke-url-map --quiet gcloud compute url-maps delete td-gke-ig-url-map --quiet gcloud compute backend-services delete td-gke-service --global --quiet cloud compute network-endpoint-groups delete service-test-neg --zone ZONE --quiet gcloud compute firewall-rules delete fw-allow-health-checks --quiet gcloud compute health-checks delete td-gke-health-check --quiet gcloud network-services endpoint-policies delete ep \ --location=global --quiet gcloud network-security authorization-policies delete authz-gateway-policy \ --location=global --quiet gcloud network-security authorization-policies delete authz-policy \ --location=global --quiet gcloud network-security client-tls-policies delete client-mtls-policy \ --location=global --quiet gcloud network-security server-tls-policies delete server-tls-policy \ --location=global --quiet gcloud network-security server-tls-policies delete server-mtls-policy \ --location=global --quiet
限制
只有 GKE 支援 Cloud Service Mesh 服務安全性。您無法使用 Compute Engine 部署服務安全性。
疑難排解
本節說明如何修正在安全性服務設定期間遇到的問題。
連線失敗
如果連線失敗並顯示 upstream connect
錯誤或 disconnect/reset
before headers
錯誤,請檢查 Envoy 記錄,您可能會看到下列其中一個記錄訊息:
gRPC config stream closed: 5, Requested entity was not found
gRPC config stream closed: 2, no credential token is found
如果您在 Envoy 記錄中看到這些錯誤,可能是服務帳戶權杖掛載方式不正確,或是使用不同的 audience
,或是兩者皆有。
詳情請參閱「Envoy 記錄中的錯誤訊息表示設定有問題」。
未建立 Pod
如要排解這個問題,請參閱「排解 GKE Pod 自動部署問題」。
Envoy 無法透過 Cloud Service Mesh 進行驗證
當 Envoy (envoy-proxy
) 連線至 Cloud Service Mesh 以擷取 xDS 設定時,會使用 GKE 適用的工作負載身分聯盟和 Compute Engine VM 預設服務帳戶 (除非已變更引導程序)。如果驗證失敗,Envoy 就不會進入就緒狀態。
無法使用 --workload-identity-certificate-authority flag
建立叢集
如果您看到這則錯誤訊息,請確認您執行的是最新版的 Google Cloud CLI:
gcloud components update
Pod 仍處於待處理狀態
如果 Pod 在設定程序期間維持在待處理狀態,請在部署規格中增加 Pod 的 CPU 和記憶體資源。
無法使用 --enable-mesh-certificates
標記建立叢集
請確認您執行的是最新版的 gcloud 指令列:
gcloud components update
請注意,--enable-mesh-certificates
標記僅適用於 gcloud beta
。
Pod 無法啟動
如果憑證佈建失敗,使用 GKE 網格憑證的 Pod 可能無法啟動。這可能發生在以下情況:
WorkloadCertificateConfig
或TrustConfig
設定錯誤或遺漏。- 客戶服務回應未獲核准。
您可以檢查 Pod 事件,確認憑證佈建是否失敗。
檢查 Pod 的狀態:
kubectl get pod -n POD_NAMESPACE POD_NAME
更改下列內容:
POD_NAMESPACE
:Pod 的命名空間。POD_NAME
:Pod 名稱。
查看 Pod 的近期事件:
kubectl describe pod -n POD_NAMESPACE POD_NAME
如果憑證佈建失敗,您會看到含有
Type=Warning
、Reason=FailedMount
、From=kubelet
的事件,以及以MountVolume.SetUp failed for volume "gke-workload-certificates"
開頭的Message
欄位。Message
欄位包含疑難排解資訊。Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedMount 13s (x7 over 46s) kubelet MountVolume.SetUp failed for volume "gke-workload-certificates" : rpc error: code = Internal desc = unable to mount volume: store.CreateVolume, err: unable to create volume "csi-4d540ed59ef937fbb41a9bf5380a5a534edb3eedf037fe64be36bab0abf45c9c": caPEM is nil (check active WorkloadCertificateConfig)
如果 Pod 無法啟動的原因是物件設定錯誤,或 CSR 遭到拒絕,請參閱以下疑難排解步驟。
WorkloadCertificateConfig
或 TrustConfig
設定有誤
請確認您已正確建立 WorkloadCertificateConfig
和 TrustConfig
物件。您可以使用 kubectl
診斷這兩種物件中的任何一個物件設定錯誤。
擷取目前狀態。
針對
WorkloadCertificateConfig
:kubectl get WorkloadCertificateConfig default -o yaml
針對
TrustConfig
:kubectl get TrustConfig default -o yaml
檢查狀態輸出內容。有效物件會包含含有
type: Ready
和status: "True"
的條件。status: conditions: - lastTransitionTime: "2021-03-04T22:24:11Z" message: WorkloadCertificateConfig is ready observedGeneration: 1 reason: ConfigReady status: "True" type: Ready
如果是無效物件,則會顯示
status: "False"
。reason
和message
欄位則包含其他疑難排解詳細資料。
CSR 未獲核准
如果 CSR 核准程序發生錯誤,您可以查看 CSR 的 type: Approved
和 type: Issued
條件中的錯誤詳細資料。
使用
kubectl
列出相關的 CSR:kubectl get csr \ --field-selector='spec.signerName=spiffe.gke.io/spiffe-leaf-signer'
選擇 CSR,該 CSR 必須為
Approved
且不是Issued
,或不是Approved
。使用 kubectl 取得所選 CSR 的詳細資料:
kubectl get csr CSR_NAME -o yaml
將
CSR_NAME
替換為您選擇的 CSR 名稱。
有效的 CSR 會包含 type: Approved
和 status: "True"
的條件,並在 status.certificate
欄位中提供有效的憑證:
status:
certificate: <base64-encoded data>
conditions:
- lastTransitionTime: "2021-03-04T21:58:46Z"
lastUpdateTime: "2021-03-04T21:58:46Z"
message: Approved CSR because it is a valid SPIFFE SVID for the correct identity.
reason: AutoApproved
status: "True"
type: Approved
message
和 reason
欄位會顯示無效 CSR 的疑難排解資訊。
應用程式無法使用核發的 mTLS 憑證
確認憑證未過期:
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
確認應用程式支援您使用的金鑰類型。
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Public Key Algorithm" -A 3
確認核發 CA 是否使用與憑證金鑰相同的金鑰系列。
取得 CA 服務 (預先發布版) 執行個體的狀態:
gcloud privateca ISSUING_CA_TYPE describe ISSUING_CA_NAME \ --location ISSUING_CA_LOCATION
更改下列內容:
ISSUING_CA_TYPE
:核發憑證授權單位類型,必須是subordinates
或roots
。ISSUING_CA_NAME
:核發 CA 的名稱。ISSUING_CA_LOCATION
:核發 CA 的區域。
檢查輸出內容中的
keySpec.algorithm
是否與您在WorkloadCertificateConfig
YAML 資訊清單中定義的鍵演算法相同。輸出如下所示:config: ... subjectConfig: commonName: td-sub-ca subject: organization: TestOrgLLC subjectAltName: {} createTime: '2021-05-04T05:37:58.329293525Z' issuingOptions: includeCaCertUrl: true keySpec: algorithm: RSA_PKCS1_2048_SHA256 ...
憑證遭拒
- 確認對等應用程式使用相同信任套件來驗證憑證。
確認憑證未過期:
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
請確認用戶端程式碼是否會定期從檔案系統重新整理憑證,如果未使用 gRPC Go 憑證重新載入 API。
請確認工作負載與 CA 位於相同的信任網域。GKE 網格憑證可支援單一信任網域中工作負載之間的通訊。