使用憑證授權單位服務,自動管理 Cloud Service Mesh 進入閘道的 TLS 憑證
本教學課程說明平台營運人員如何使用 cert-manager 工具的憑證授權單位服務 (CA Service) 簽發者,自動管理 Cloud Service Mesh Ingress 閘道的 TLS 憑證。憑證可讓 Ingress 閘道終止來自虛擬私有雲 (VPC) 中用戶端,但位於服務網格外部的 HTTPS 和其他 TLS 與 mTLS 流量。本教學課程假設您已熟悉 Kubernetes 和 TLS 憑證的基本概念。
簡介
Cloud Service Mesh 會為服務網格中的每個工作負載佈建 TLS 憑證。 這些憑證可讓服務網格中的工作負載,透過相互驗證的 TLS (mTLS) 加密通訊。由其中一個支援的 CA 簽發及簽署憑證。
不過,Cloud Service Mesh 不會自動為進入服務網格的流量,向 Ingress 閘道佈建憑證。常見的解決方案是使用開放原始碼 cert-manager 工具,自動管理 Ingress 閘道憑證。
cert-manager 工具會向簽發者要求憑證,而簽發者代表憑證授權單位 (CA)。憑證授權單位服務可讓您建立自己的私人 CA。Google Cloud cert-manager 工具可使用 CA 服務的開放原始碼外部簽發者,向 CA 服務要求憑證。
私人 CA 可以核發 TLS 憑證,驗證及加密內部網路中的流量。Cloud Service Mesh 輸入閘道通常會設定為允許來自 VPC 內部但服務網格外部的用戶端流量。如果是內部網路流量,您可以使用 CA Service 中的私有 CA,為輸入閘道核發憑證。
本教學課程說明如何設定 cert-manager 工具和 CA 服務簽發者,自動為 Ingress 閘道佈建及續訂 TLS 憑證。cert-manager 工具會將憑證佈建為TLS 類型的 Kubernetes Secret 資源。當 cert-manager 工具續購憑證時,會使用新憑證更新 Secret 資源。Ingress 閘道會執行 Envoy Proxy,並支援 Envoy 的密碼探索服務 (SDS)。SDS 可讓 Ingress 閘道開始使用新憑證,管理員不必重新啟動或重新載入程序。
網格中的 Sidecar Proxy 可以從 CA 服務或 Cloud Service Mesh 憑證授權單位取得 TLS 憑證。在本教學課程中,您會使用 CA 服務取得 Sidecar Proxy 和 Ingress Gateway 憑證。這樣一來,您就能為所有 TLS 憑證使用一個根 CA。
下圖顯示您在本教學課程中佈建的資源。您為 Ingress 閘道佈建內部直通式網路負載平衡器。內部直通式網路負載平衡器不是 Proxy,因此不會終止 TCP 連線或執行 TLS 交握。而是將連線轉送至 istio-ingressgateway 部署作業的 Pod。
hello-example-com-credential Secret 包含憑證和私密金鑰。hello 閘道會設定 istio-ingressgateway 部署作業的 Pod,使用這個憑證和私密金鑰,對主機名稱為 hello.example.com 的要求執行 TLS 握手程序。
cert-manager 命名空間中 google-cas-issuer 部署作業的 Pod 會向您在 CA 服務中建立的 CA 要求憑證。您建立 Identity and Access Management 政策繫結,允許 ca-service-isser Pod 使用 Workload Identity Federation for GKE 模擬 Google 服務帳戶。您可以在 CA 集區建立 IAM 政策繫結,授予這個 Google 服務帳戶權限,向 CA 服務中的 CA 要求憑證。
目標
- 設定 CA 服務
- 建立 GKE 叢集
- 安裝 Cloud Service Mesh 控制層
- 安裝 Ingress 閘道
- 安裝 cert-manager 工具
- 安裝 CA 服務簽發者控制器
- 建立憑證頒發機構
- 部署範例應用程式
- 驗證解決方案
- (選用) 將 CA 憑證新增至信任存放區
費用
本教學課程使用下列 Google Cloud計費元件:
如要根據預測用量估算費用,請使用 Pricing Calculator。初次使用 Google Cloud 的使用者可能符合免費試用資格。
完成本教學課程後,您可以刪除自己建立的資源,避免系統繼續計費。詳情請參閱「清理」一節。
事前準備
在 Google Cloud 控制台中,前往專案選擇器頁面,然後選取或建立專案。
請確認您已為專案 Google Cloud 啟用計費功能。
前往 Google Cloud 控制台的 Cloud Shell。
Google Cloud 主控台底部會開啟 Cloud Shell 工作階段,並顯示指令列提示。您將使用 Cloud Shell 來執行本教學課程中的所有指令。
設定要用於本教學課程的 Google Cloud 控制台專案:
gcloud config set core/project PROJECT_ID將 PROJECT_ID 替換為 Cloud 專案的專案 ID。
在「授權 Cloud Shell」對話方塊中,按一下「授權」。按一下「授權」,即可允許您在 Cloud Shell 中執行的
gcloud指令使用您的使用者憑證,向 Google API 進行驗證。啟用 Resource Manager、GKE、GKE Fleet、Cloud Service Mesh 憑證授權單位和 CA Service API:
gcloud services enable \ cloudresourcemanager.googleapis.com \ container.googleapis.com \ gkehub.googleapis.com \ meshca.googleapis.com \ privateca.googleapis.com
設定 CA 服務
在本節中,您將在 CA 服務中建立根 CA 和兩個下層 CA。一個從屬 CA 會將憑證核發給 Ingress 閘道,另一個從屬 CA 則會將憑證核發給網格中的 Sidecar Proxy。
為求簡單起見,在本教學課程中,您會使用同一個專案來建立 GKE 叢集,以及根 CA 和下層 CA。在您自己的環境中,可以為 GKE 叢集和 CA 使用不同的專案。
在 Cloud Shell 中,建立用於根 CA 的 CA 集區:
gcloud privateca pools create ROOT_CA_POOL \ --location CA_LOCATION \ --tier enterprise- ROOT_CA_POOL 是 CA 集區的名稱。例如:
root-ca-pool-tutorial。 - CA_LOCATION 是 CA 集區的位置。例如:
us-central1。
您可以使用下列指令列出可用的 CA 服務位置:
gcloud privateca locations list- ROOT_CA_POOL 是 CA 集區的名稱。例如:
建立並啟用根 CA:
gcloud privateca roots create ROOT_CA \ --auto-enable \ --key-algorithm ec-p384-sha384 \ --location CA_LOCATION \ --pool ROOT_CA_POOL \ --subject "CN=Example Root CA, O=Example Organization" \ --use-preset-profile root_unconstrained- ROOT_CA 是您要用於根 CA 的名稱。例如:
root-ca-tutorial。
- ROOT_CA 是您要用於根 CA 的名稱。例如:
建立 CA 集區,供從屬 CA 使用,以便向 Ingress 閘道核發憑證:
gcloud privateca pools create SUBORDINATE_CA_POOL_GATEWAYS \ --location CA_LOCATION \ --tier devops- SUBORDINATE_CA_POOL_GATEWAYS 是 CA 集區的名稱。例如:
subordinate-ca-mtls-pool-gateways-tutorial。
- SUBORDINATE_CA_POOL_GATEWAYS 是 CA 集區的名稱。例如:
建立並啟用從屬 CA,向 Ingress 閘道核發憑證:
gcloud privateca subordinates create SUBORDINATE_CA_GATEWAYS \ --auto-enable \ --issuer-location CA_LOCATION \ --issuer-pool ROOT_CA_POOL \ --key-algorithm ec-p256-sha256 \ --location CA_LOCATION \ --pool SUBORDINATE_CA_POOL_GATEWAYS \ --subject "CN=Example Gateway mTLS CA, O=Example Organization" \ --use-preset-profile subordinate_mtls_pathlen_0- SUBORDINATE_CA_GATEWAYS 是您要用於下層 CA 的名稱。例如:
subordinate-ca-mtls-gateways-tutorial。 --use-preset-profile標記會將從屬 CA 設定為使用「從屬 mTLS」憑證設定檔。這個設定檔可讓下層 CA 核發用戶端和伺服器 TLS 憑證,用於 mTLS。
如果希望 Ingress 閘道使用簡單的 TLS,而非 mTLS,則下層 CA 只需要核發伺服器 TLS 憑證。在這種情況下,您可以改用「下層伺服器 TLS」(
subordinate_server_tls_pathlen_0) 憑證設定檔。- SUBORDINATE_CA_GATEWAYS 是您要用於下層 CA 的名稱。例如:
建立憑證核發政策:
cat << EOF > policy.yaml baselineValues: keyUsage: baseKeyUsage: digitalSignature: true keyEncipherment: true extendedKeyUsage: serverAuth: true clientAuth: true caOptions: isCa: false identityConstraints: allowSubjectPassthrough: false allowSubjectAltNamesPassthrough: true celExpression: expression: subject_alt_names.all(san, san.type == URI && san.value.startsWith("spiffe://PROJECT_ID.svc.id.goog/ns/") ) EOF這項核發政策會限制 CA,只能為網格中的工作負載核發憑證。
建立 CA 集區,供從屬 CA 使用,向網格中的 Sidecar 代理程式核發憑證。對 CA 集區套用核發政策:
gcloud privateca pools create SUBORDINATE_CA_POOL_SIDECARS \ --issuance-policy policy.yaml \ --location CA_LOCATION \ --tier devops- SUBORDINATE_CA_POOL_SIDECARS 是 CA 集區的名稱。例如:
subordinate-ca-mtls-pool-sidecars-tutorial。
- SUBORDINATE_CA_POOL_SIDECARS 是 CA 集區的名稱。例如:
建立並啟用從屬 CA,向網格中的 Sidecar Proxy 核發憑證:
gcloud privateca subordinates create SUBORDINATE_CA_SIDECARS \ --auto-enable \ --issuer-location CA_LOCATION \ --issuer-pool ROOT_CA_POOL \ --key-algorithm ec-p256-sha256 \ --location CA_LOCATION \ --pool SUBORDINATE_CA_POOL_SIDECARS \ --subject "CN=Example Sidecar mTLS CA, O=Example Organization" \ --use-preset-profile subordinate_mtls_pathlen_0- SUBORDINATE_CA_GATEWAYS 是您要用於下層 CA 的名稱。例如:
subordinate-ca-mtls-sidecars-tutorial。
- SUBORDINATE_CA_GATEWAYS 是您要用於下層 CA 的名稱。例如:
建立 Google Kubernetes Engine 叢集
在 Cloud Shell 中建立 GKE 叢集:
gcloud container clusters create CLUSTER_NAME \ --enable-ip-alias \ --num-nodes 4 \ --release-channel regular \ --scopes cloud-platform \ --workload-pool PROJECT_ID.svc.id.goog \ --zone ZONE將 CLUSTER_NAME 替換為您要使用的叢集名稱。例如:
asm-ingress-cert-manager-ca-service。將 ZONE 替換為叢集要使用的區域。例如:
us-central1-f。請注意下列指令的相關事項:
將叢集管理員權限授予使用者帳戶:
kubectl create clusterrolebinding cluster-admin-binding \ --clusterrole cluster-admin \ --user $(gcloud config get-value core/account)您需要 Kubernetes
cluster-adminClusterRole 提供的權限,才能為 Cloud Service Mesh 建立角色型存取權控管 (RBAC) 規則,以及安裝 cert-manager 工具。
安裝 Anthos 服務網格控制層
在本教學課程中,您將在 Google Cloud的 GKE 叢集上安裝代管 Cloud Service Mesh,所有資源都位於同一個專案中。在您自己的環境中,您可以透過代管 Cloud Service Mesh 或叢集內控制層,套用本文所述的解決方案。
Cloud Service Mesh 提供多種安裝選項,適用於不同情境。完成本教學課程後,建議您參閱安裝指南,選取最適合您環境的選項。
在 Cloud Shell 中,下載
asmcli安裝工具:curl --location --output asmcli https://storage.googleapis.com/csm-artifacts/asm/asmcli_1.28 chmod +x asmcli您可以使用
asmcli安裝 Cloud Service Mesh 控制層。安裝 Cloud Service Mesh 控制層:
./asmcli install \ --ca gcp_cas \ --ca_pool projects/PROJECT_ID/locations/CA_LOCATION/caPools/SUBORDINATE_CA_POOL_SIDECARS \ --cluster_location ZONE \ --cluster_name CLUSTER_NAME \ --enable_all \ --enable_registration \ --fleet_id PROJECT_ID \ --managed \ --output_dir asm-files \ --project_id PROJECT_ID \ --verbose--ca gcp_cas和--ca_pool旗標會設定 Cloud Service Mesh 控制層,使用 CA 服務中的補充 CA 集區,將憑證核發給網格中的補充 Proxy。--enable_registration標記會將 GKE 叢集註冊至 機群,該機群位於--fleet_id標記指定的專案中。在本教學課程中,GKE 叢集和機群使用相同的專案。--managed旗標會設定代管 Cloud Service Mesh 控制層。--output_dir標記會指定asmcli用來下載安裝 Cloud Service Mesh 所需檔案和設定的目錄。您會在教學課程稍後使用這些檔案。
安裝作業需要幾分鐘才能完成。安裝完成後,畫面會顯示以下輸出內容:
asmcli: Successfully installed ASM.
安裝 Ingress 閘道
在 Cloud Shell 中,為 Ingress 閘道建立 Kubernetes 命名空間:
kubectl create namespace GATEWAY_NAMESPACE- GATEWAY_NAMESPACE 是要用於 Ingress 閘道的命名空間名稱。例如:
istio-ingress。
- GATEWAY_NAMESPACE 是要用於 Ingress 閘道的命名空間名稱。例如:
保留靜態內部 IP 位址,供 Ingress 閘道內部直通式網路負載平衡器使用:
LOAD_BALANCER_IP=$(gcloud compute addresses create \ asm-ingress-gateway-ilb \ --region REGION \ --subnet default \ --format 'value(address)')- 將 REGION 替換為包含 GKE 叢集節點所用區域的地區。舉例來說,如果叢集使用
us-central1-f區域,請將 REGION 替換為us-central1。
這個指令會從您指定的區域中,保留預設子網路的 IP 位址。
- 將 REGION 替換為包含 GKE 叢集節點所用區域的地區。舉例來說,如果叢集使用
為 Ingress 閘道建立運算子資訊清單:
cat << EOF > ingressgateway-operator.yaml apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: name: ingressgateway-operator annotations: config.kubernetes.io/local-config: "true" spec: profile: empty revision: asm-managed components: ingressGateways: - name: istio-ingressgateway namespace: GATEWAY_NAMESPACE enabled: true k8s: overlays: - apiVersion: apps/v1 kind: Deployment name: istio-ingressgateway patches: - path: spec.template.metadata.annotations value: inject.istio.io/templates: gateway - path: spec.template.metadata.labels.sidecar\.istio\.io/inject value: "true" - path: spec.template.spec.containers[name:istio-proxy] value: name: istio-proxy image: auto service: loadBalancerIP: $LOAD_BALANCER_IP serviceAnnotations: networking.gke.io/load-balancer-type: Internal networking.gke.io/internal-load-balancer-allow-global-access: "true" EOF請注意下列有關運算子資訊清單的事項:
revision欄位會指定用於資料層的代管 Cloud Service Mesh 發布管道。如果您使用控制層的快速或穩定發布管道,請變更這個欄位的值。overlays部分中指定的annotation、label和image可自動為輸入閘道部署項目注入 Proxy 設定。loadBalancerIP欄位會指定負載平衡器使用的 IP 位址。如果從資訊清單中移除這個欄位,負載平衡器會使用暫時 IP 位址。服務註解
networking.gke.io/load-balancer-type: Internal位於 Ingress 閘道上,表示 GKE 會在 Ingress 閘道 Pod 前方佈建內部直通式網路負載平衡器。如果移除這個註解,GKE 會改為佈建外部直通式網路負載平衡器。選用的服務註解
networking.gke.io/internal-load-balancer-allow-global-access: "true"可讓虛擬私有雲中任何區域的用戶端存取內部直通式網路負載平衡器。如果移除這個註解,內部直通式網路負載平衡器只會接受來自虛擬私有雲中相同區域的用戶端流量。
使用運算子資訊清單和
istioctl工具 (安裝控制層時,asmcli指令碼會下載此工具),建立 Ingress Gateway 安裝資訊清單:./asm-files/istioctl manifest generate \ --filename ingressgateway-operator.yaml \ --output ingressgateway安裝 Ingress 閘道:
kubectl apply --recursive --filename ingressgateway/
安裝 cert-manager 工具
在 Cloud Shell 中,下載並套用 cert-manager 工具安裝資訊清單:
CERT_MANAGER_VERSION=v1.5.4 curl --location --output cert-manager.yaml "https://github.com/jetstack/cert-manager/releases/download/${CERT_MANAGER_VERSION}/cert-manager.yaml" kubectl apply --filename cert-manager.yaml安裝 cert-manager 工具大約需要一分鐘。
安裝 CA 服務簽發者控制器
CA 服務核發者控制器可讓 cert-manager 工具使用 CA 服務要求憑證。控制器會使用 cert-manager 工具的外部簽發者擴充機制。
在 Cloud Shell 中建立 Google 服務帳戶:
gcloud iam service-accounts create CAS_ISSUER_GSA \ --display-name "CA Service issuer for cert-manager"- CAS_ISSUER_GSA 是 Google 服務帳戶的名稱。例如:
cert-manager-ca-service-issuer。
憑證授權單位服務簽發者控制器會使用這個 Google 服務帳戶,向 憑證授權單位服務 API 進行驗證。
- CAS_ISSUER_GSA 是 Google 服務帳戶的名稱。例如:
建立身分與存取權管理政策繫結,允許憑證授權單位服務簽發者控制器 Google 服務帳戶,從包含下層 CA 的 CA 集區要求憑證:
gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \ --location CA_LOCATION \ --member "serviceAccount:CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com" \ --role roles/privateca.certificateRequester下載憑證授權單位服務簽發者控制器安裝資訊清單:
CAS_ISSUER_VERSION=v0.5.3 curl --location --output ca-service-issuer.yaml "https://github.com/jetstack/google-cas-issuer/releases/download/${CAS_ISSUER_VERSION}/google-cas-issuer-${CAS_ISSUER_VERSION}.yaml"建立 IAM 政策繫結,允許
cert-manager命名空間中的ksa-google-cas-issuerKubernetes 服務帳戶使用 Workload Identity Federation for GKE模擬 Google 服務帳戶 (GSA):gcloud iam service-accounts add-iam-policy-binding \ CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com \ --member "serviceAccount:PROJECT_ID.svc.id.goog[cert-manager/ksa-google-cas-issuer]" \ --role roles/iam.workloadIdentityUserCA 服務簽發者控制器 Pod 會使用
ksa-google-cas-issuerKubernetes 服務帳戶。在 GKE 叢集中安裝 CA 服務簽發者控制器:
kubectl apply --filename ca-service-issuer.yaml將 Workload Identity Federation for GKE 註解
iam.gke.io/gcp-service-account新增至 CA 服務簽發者控制器 Pod 使用的 Kubernetes 服務帳戶:kubectl annotate serviceaccount ksa-google-cas-issuer --namespace cert-manager \ "iam.gke.io/gcp-service-account=CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com"這項註解會通知 GKE,Kubernetes 服務帳戶可以模擬 Google 服務帳戶,存取 Google API。
建立憑證頒發機構
在 Cloud Shell 中,建立並套用 GoogleCASIssuer 資訊清單:
cat << EOF > gateway-cas-issuer.yaml apiVersion: cas-issuer.jetstack.io/v1beta1 kind: GoogleCASIssuer metadata: name: gateway-cas-issuer namespace: GATEWAY_NAMESPACE spec: caPoolId: SUBORDINATE_CA_POOL_GATEWAYS location: CA_LOCATION project: PROJECT_ID EOF kubectl apply --filename gateway-cas-issuer.yaml核發者可讓 cert-manager 工具從 Ingress 閘道命名空間中的從屬 CA 集區佈建憑證
部署範例應用程式
在本節中,您將驗證 cert-manager 工具是否可使用 CA 服務簽發者,從 CA 服務取得憑證。如要驗證,請部署範例應用程式,其中包含要求轉送設定和輸入閘道的憑證。
在 Cloud Shell 中,為範例應用程式資源建立命名空間:
cat << EOF > sample-app-namespace.yaml apiVersion: v1 kind: Namespace metadata: name: APP_NAMESPACE annotations: mesh.cloud.google.com/proxy: '{"managed":"true"}' labels: istio.io/rev: asm-managed EOF kubectl apply --filename sample-app-namespace.yaml- APP_NAMESPACE 是範例應用程式的命名空間名稱。例如:
sample-app。
註解
mesh.cloud.google.com/proxy可為命名空間啟用受管理資料平面。標籤
istio.io/rev: asm-managed會在範例應用程式命名空間中,為受管理資料層選取「一般發布管道」。如果您使用快速或穩定版發布管道,請變更這個標籤的值。- APP_NAMESPACE 是範例應用程式的命名空間名稱。例如:
為範例應用程式建立 Deployment 資源:
cat << EOF > deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: hello namespace: APP_NAMESPACE labels: app: hello spec: replicas: 1 selector: matchLabels: app: hello template: metadata: labels: app: hello spec: containers: - image: gcr.io/google-samples/hello-app:1.0 name: hello-app ports: - containerPort: 8080 EOF kubectl apply --filename deployment.yaml為範例應用程式建立 Service 資源:
cat << EOF > service.yaml apiVersion: v1 kind: Service metadata: name: SERVICE_NAME namespace: APP_NAMESPACE spec: ports: - name: http-hello port: 8080 selector: app: hello type: ClusterIP EOF kubectl apply --filename service.yaml- SERVICE_NAME 是服務名稱。例如:
hello。
- SERVICE_NAME 是服務名稱。例如:
使用憑證頒發機構,為網域名稱
hello.example.com建立憑證資源:cat << EOF > certificate.yaml apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: hello-example-com-certificate namespace: GATEWAY_NAMESPACE spec: secretName: hello-example-com-credential commonName: hello.example.com dnsNames: - hello.example.com duration: 24h renewBefore: 8h issuerRef: group: cas-issuer.jetstack.io kind: GoogleCASIssuer name: gateway-cas-issuer EOF kubectl apply --filename certificate.yaml憑證命名空間必須與 Ingress 閘道命名空間相符。 通常只有平台管理員可以變更這個命名空間中的資源,因為變更可能會影響整個服務網格。cert-manager 工具會在同一個命名空間中,為 TLS 憑證建立 Secret 資源。也就是說,應用程式管理員不需要存取 Ingress 閘道命名空間。
您可以在「Certificate」的
dnsNames清單中新增其他主機名稱。 這些主機名稱會以主體別名 (SAN) 形式納入憑證。為範例應用程式建立 Gateway 資源:
cat << EOF > gateway.yaml apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: GATEWAY_NAME namespace: GATEWAY_NAMESPACE spec: selector: istio: ingressgateway servers: - hosts: - APP_NAMESPACE/hello.example.com port: name: https-hello number: 443 protocol: HTTPS tls: credentialName: hello-example-com-credential mode: MUTUAL EOF kubectl apply --filename gateway.yaml- GATEWAY_NAME 是閘道名稱。例如:
hello。 - Gateway 中的
credentialName欄位與憑證中的secretName欄位相符。cert-manager 工具會使用 CA 服務中的 TLS 憑證建立 Kubernetes 密鑰。有了這項憑證,Ingress Gateway 就能終止傳輸層安全標準 (TLS) 流量,並將流量導向hello.example.com。
閘道資訊清單會指定MUTUAL傳輸層安全標準 (mTLS)。如要為一般傳輸層安全標準 (TLS) 設定閘道,請將閘道的傳輸層安全標準 (TLS) 模式設為
SIMPLE。- GATEWAY_NAME 是閘道名稱。例如:
為範例應用程式建立 VirtualService 資源:
cat << EOF > virtual-service.yaml apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: hello namespace: APP_NAMESPACE spec: hosts: - hello.example.com gateways: - GATEWAY_NAMESPACE/GATEWAY_NAME http: - route: - destination: host: SERVICE_NAME port: number: 8080 EOF kubectl apply --filename virtual-service.yamlGateway 和 VirtualService 使用不同的命名空間。這個常見模式會限制 Gateway 中主機型路由的變更,只有具備在 Ingress Gateway 命名空間中變更資源權限的平台管理員,才能進行這類變更。
有權在範例應用程式命名空間中編輯 VirtualService 的應用程式管理員,可以透過其他要求欄位 (例如網址路徑) 變更路由,不必與平台管理員協調。
如要瞭解其他設定選項,請參閱 Certificate、Gateway 和 VirtualService 資源的 API 說明文件。
您可以對透過輸入閘道進入服務網格的流量套用驗證和授權政策。如要這麼做,請參閱 Istio PeerAuthentication 和 AuthorizationPolicy API 的說明文件。
檢查問題是否已經順利解決
在本節中,您將驗證是否能從服務網格外部,使用 mTLS 將 HTTPS 要求傳送至範例應用程式。如要驗證,請建立 Compute Engine VM 執行個體、向 CA 服務要求用戶端 TLS 憑證,並使用這個憑證向範例應用程式驗證要求。
您需要 VM 執行個體的 SSH 存取權。預設網路包含允許 SSH 存取的防火牆規則。如果無法透過 SSH 存取,請參閱防火牆規則說明文件,建立允許通訊埠 22 上連入 TCP 連線的防火牆規則。
在 Cloud Shell 中建立 Google 服務帳戶:
gcloud iam service-accounts create CLIENT_VM_GSA \ --display-name "CA Service tutorial VM instance service account"- CLIENT_VM_GSA 是 Google 服務帳戶的名稱。例如:
cas-tutorial-client。
您會將這個 Google 服務帳戶指派給 Compute Engine VM 執行個體。
- CLIENT_VM_GSA 是 Google 服務帳戶的名稱。例如:
將閘道從屬 CA 集區的 CA Service Certificate Requester 角色指派給 Google 服務帳戶:
gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \ --location CA_LOCATION \ --member "serviceAccount:CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com" \ --role roles/privateca.certificateRequester這個角色提供向 CA 集區要求憑證的權限。
在與 GKE 叢集相同的 VPC 中建立 Compute Engine VM 執行個體:
gcloud compute instances create cas-tutorial-client \ --scopes cloud-platform \ --service-account CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com \ --zone ZONEVM 執行個體需要
cloud-platform範圍,才能存取 CA Service API。將 Ingress 閘道內部直通式網路負載平衡器的 IP 位址儲存至檔案:
kubectl get services istio-ingressgateway \ --namespace GATEWAY_NAMESPACE \ --output jsonpath='{.status.loadBalancer.ingress[0].ip}' > ilb-ip.txt將根 CA 的公用金鑰憑證儲存至檔案:
gcloud privateca roots describe ROOT_CA \ --location CA_LOCATION \ --pool ROOT_CA_POOL \ --format 'value(pemCaCertificates)' > root-ca-cert.pem將根 CA 憑證和包含 Ingress 閘道內部直通網路負載平衡器 IP 位址的檔案複製到 VM 執行個體:
gcloud compute scp root-ca-cert.pem ilb-ip.txt cas-tutorial-client:~ \ --zone ZONE使用 SSH 連線至 VM 執行個體:
gcloud compute ssh cas-tutorial-client --zone ZONE請透過 SSH 工作階段執行本節中的其餘指令。
安裝
ca-certificates和coreutils套件,以及curl、openssl和jq指令列工具:sudo apt-get update --yes sudo apt-get install --yes ca-certificates coreutils curl jq openssl建立用戶端 TLS 憑證的金鑰組:
openssl genrsa -out private-key.pem 2048 openssl rsa -in private-key.pem -pubout -out public-key.pem查詢中繼資料伺服器,取得附加至 VM 執行個體的 Google 服務帳戶身分電子郵件地址:
GSA_EMAIL=$(curl --silent --header "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email)建立 JSON 檔案,在向憑證授權單位服務 API 要求用戶端 TLS 憑證時,將該檔案做為要求主體:
cat << EOF > request.json { "config": { "publicKey": { "format": "PEM", "key": "$(base64 --wrap 0 public-key.pem)" }, "subjectConfig": { "subject": { "commonName": "$(hostname --short)", "organization": "Example Organization" }, "subjectAltName": { "dnsNames": [ "$(hostname --fqdn)" ], "emailAddresses": [ "$GSA_EMAIL" ] } }, "x509Config": { "caOptions": { "isCa": false }, "keyUsage": { "baseKeyUsage": { "digitalSignature": true, "keyEncipherment": true }, "extendedKeyUsage": { "clientAuth": true } } } }, "lifetime": "86400s" } EOF如要進一步瞭解設定部分的欄位,請參閱 CA Service API 說明文件中的
CertificateConfig型別。-
TOKEN=$(curl --silent --header "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token | jq --raw-output ".access_token")這個存取權杖會提供授予 VM 執行個體所連結 Google 服務帳戶的權限。
透過 CA 服務 API 要求用戶端 TLS 憑證,並將回應主體儲存在檔案中:
curl --silent --request POST \ --header "Authorization: Bearer $TOKEN" \ --header "Content-Type: application/json" \ --data @request.json \ --output response.json \ "https://privateca.googleapis.com/v1/projects/PROJECT_ID/locations/CA_LOCATION/caPools/SUBORDINATE_CA_POOL_GATEWAYS/certificates"這項指令會使用存取權杖驗證 API 要求。
將用戶端憑證和憑證鏈結儲存至檔案:
jq --raw-output --join-output ".pemCertificate , .pemCertificateChain[]" response.json > client-cert-chain.pem使用
curl從 VM 執行個體傳送 HTTPS 要求至範例應用程式:curl --cert client-cert-chain.pem --key private-key.pem \ --cacert root-ca-cert.pem \ --resolve hello.example.com:443:$(cat ilb-ip.txt) \ --silent https://hello.example.com | head -n1輸出如下所示:
Hello, world!
這項回應表示
curl已使用 mTLS 成功傳送 HTTPS 要求。範例應用程式會回覆您在終端機輸出內容中看到的訊息。curl指令會執行下列動作:--cert和--key旗標會指示curl使用用戶端 TLS 憑證和私密金鑰驗證要求。用戶端憑證檔案包含完整憑證鏈結,從用戶端憑證到根 CA。--cacert旗標會指示curl驗證伺服器憑證是否由您在本教學課程中建立的根 CA 或其從屬 CA 核發。如果省略這個旗標,
curl會嘗試使用作業系統的預設 CA 組合驗證伺服器憑證,例如 Debian 上的ca-certificates套件。驗證失敗,因為預設的 CA 組合不包含您在本教學課程中建立的根 CA。--resolve旗標會指示curl使用內部直通式網路負載平衡器 IP 位址,做為傳送至主機hello.example.com(位於 443 埠) 的要求目的地。如果省略這個標記,
curl會嘗試使用 DNS 解析hello.example.com主機名稱。由於這個主機名稱沒有 DNS 項目,因此 DNS 解析失敗。在您自己的環境中,建議您建立指向內部直通網路負載平衡器 IP 位址 (
$LOAD_BALANCER_IP) 的 DNS A 記錄。請使用 Cloud DNS 建立這項記錄,並按照管理記錄的說明文件操作。--silent標記會禁止在終端機輸出內容中回報回應下載進度。這個指令會將 curl 輸出內容透過管道傳送至
head -n1。結果是終端機中的輸出內容只會包含回應主體的第一行。
離開 SSH 工作階段:
exit
在本節中,您直接透過 CA 服務 API 要求用戶端 TLS 憑證。如果用戶端是另一個 Kubernetes 叢集中服務網格的出站閘道,您可以使用 cert-manager 工具和憑證授權單位服務簽發者,透過相同的根 CA 為出站閘道提供用戶端憑證。
在其他情況下,您可以使用 Hashicorp Vault、Terraform 或 gcloud 等工具,為服務網格外部的工作負載要求用戶端 TLS 憑證。詳情請參閱 CA Service 範例解決方案說明文件,以及 CA Service 的gcloud說明文件。
(選用) 將 CA 憑證新增至信任存放區
這個選用章節說明如何將 CA 憑證新增至 Debian Linux 發行版本的信任 CA 憑證存放區。這些操作說明也適用於衍生自 Debian 的發行版本,例如 Ubuntu。
將 CA 憑證新增至這個儲存庫後,使用 curl、Python、Go 和 Ruby 傳送 HTTPS 要求時,就不需要指定信任的 CA 憑證位置。
使用 SSH 連線至 VM 執行個體:
gcloud compute ssh cas-tutorial-client --zone ZONE請透過 SSH 工作階段執行本節中的其餘指令。
將根 CA 憑證複製到
/usr/local/share/ca-certificates目錄,並確認檔案的副檔名為.crt:sudo cp root-ca-cert.pem /usr/local/share/ca-certificates/cas-rootca.crt設定檔案權限,讓所有使用者都能讀取根 CA 憑證檔案:
sudo chmod 644 /usr/local/share/ca-certificates/cas-rootca.crt執行
update-ca-certificates指令碼:sudo update-ca-certificates這個指令碼會將憑證新增至
/etc/ssl/certs目錄中的一組信任憑證,以及/etc/ssl/certs/ca-certificates.crt檔案。輸出內容如下:
Updating certificates in /etc/ssl/certs... 1 added, 0 removed; done. Running hooks in /etc/ca-certificates/update.d... done.
使用
curl從 VM 執行個體傳送 HTTPS 要求至範例應用程式:curl --cert client-cert-chain.pem --key private-key.pem \ --resolve hello.example.com:443:$(cat ilb-ip.txt) \ --silent https://hello.example.com | head -n1輸出如下所示:
Hello, world!
這項回應表示
curl成功使用 mTLS 傳送 HTTPS 要求,並使用預設 CA 憑證存放區,驗證來自 Ingress 閘道的伺服器 TLS 憑證。離開 SSH 工作階段:
exit
疑難排解
如果 CA 服務簽發者控制器未建立 TLS 憑證密鑰,請查看 CA 服務簽發者控制器的記錄:
kubectl logs deployment/google-cas-issuer --namespace cert-manager
如果安裝 Cloud Service Mesh 時發生問題,請執行 asmcli 工具來驗證雲端專案和 GKE 叢集。
如果您在使用本教學課程時發生其他問題,建議查看下列文件:
- CA 服務常見問題
- 逐步排解 Cloud Service Mesh 問題
- 解決代管型 Cloud Service Mesh 問題
- Istio 作業常見問題
- GKE 疑難排解
- 排解 Kubernetes 叢集問題
清除所用資源
如要避免系統持續向您的 Google Cloud 帳戶收取本教學課程所用資源的費用,請刪除專案或個別資源。
刪除專案
在 Cloud Shell 中刪除專案:
gcloud projects delete PROJECT_ID
刪除資源
如要保留您在本教學課程中使用的 Google Cloud 專案,請刪除個別的資源:
在 Cloud Shell 中,取消註冊 GKE 叢集與 GKE 機群:
gcloud container hub memberships unregister CLUSTER_NAME \ --gke-cluster ZONE/CLUSTER_NAME刪除 GKE 叢集:
gcloud container clusters delete CLUSTER_NAME \ --zone ZONE --async --quiet刪除下層 CA 集區的身分與存取權管理政策繫結:
gcloud privateca pools remove-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \ --location CA_LOCATION \ --member "serviceAccount:CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com" \ --role roles/privateca.certificateRequester gcloud privateca pools remove-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \ --location CA_LOCATION \ --member "serviceAccount:CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com" \ --role roles/privateca.certificateRequester停用並安排刪除從屬 CA 和根 CA:
gcloud privateca subordinates disable SUBORDINATE_CA_GATEWAYS \ --location CA_LOCATION \ --pool SUBORDINATE_CA_POOL_GATEWAYS \ --quiet gcloud privateca subordinates delete SUBORDINATE_CA_GATEWAYS \ --location CA_LOCATION \ --pool SUBORDINATE_CA_POOL_GATEWAYS \ --ignore-active-certificates \ --quiet gcloud privateca subordinates disable SUBORDINATE_CA_SIDECARS \ --location CA_LOCATION \ --pool SUBORDINATE_CA_POOL_SIDECARS \ --quiet gcloud privateca subordinates delete SUBORDINATE_CA_SIDECARS \ --location CA_LOCATION \ --pool SUBORDINATE_CA_POOL_SIDECARS \ --ignore-active-certificates \ --quiet gcloud privateca roots disable ROOT_CA \ --location CA_LOCATION \ --pool ROOT_CA_POOL \ --quiet gcloud privateca roots delete ROOT_CA \ --location CA_LOCATION \ --pool ROOT_CA_POOL \ --ignore-active-certificates \ --quiet刪除 CA 服務簽發者控制器 Google 服務帳戶的 IAM 政策繫結:
gcloud iam service-accounts remove-iam-policy-binding \ CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com \ --member "serviceAccount:PROJECT_ID.svc.id.goog[cert-manager/ksa-google-cas-issuer]" \ --role roles/iam.workloadIdentityUser刪除 Google 服務帳戶:
gcloud iam service-accounts delete --quiet \ CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com gcloud iam service-accounts delete --quiet \ CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com刪除預留的負載平衡器 IP 位址:
gcloud compute addresses delete asm-ingress-gateway-ilb \ --region REGION --quiet刪除 Compute Engine VM 執行個體:
gcloud compute instances delete cas-tutorial-client \ --zone ZONE --quiet
後續步驟
- 探索其他憑證授權單位服務使用指南。
- 進一步瞭解 Cloud Service Mesh,這是一套以 Istio 為基礎的工具,可協助您監控及管理地端部署和 Google Cloud的可靠服務網格。
- 瀏覽 Cloud Service Mesh 使用指南。