使用憑證授權單位服務,為 Cloud Service Mesh 入口閘道自動管理 TLS 憑證
本教學課程將向平台操作人員說明如何使用 cert-manager 工具的憑證管理機構服務 (CA 服務) 核發者,為 Cloud Service Mesh 入口閘道自動化 TLS 憑證管理作業。憑證可讓入口閘道終止來自虛擬私有雲 (VPC) 中服務中介網外客戶的 HTTPS 和其他 TLS 和 mTLS 流量。本教學課程假設您對 Kubernetes 和 TLS 憑證有基本的瞭解。
簡介
Cloud Service Mesh 會為服務網格中的每個工作負載提供 TLS 憑證。這些憑證可在服務網格中,讓工作負載之間的通訊進行加密和雙向驗證 TLS (mTLS) 通訊。由其中一個支援的 CA 核發並簽署憑證。
不過,Cloud Service Mesh 不會自動為進入服務網格的流量,將憑證佈建至入口閘道。常見的解決方案是使用開放原始碼 cert-manager 工具,自動管理入口網站閘道憑證。
cert-manager 工具會向發證者 (代表憑證授權單位 (CA)) 要求憑證。CA 服務是Google Cloud 服務,可讓您自行建立私人 CA。cert-manager 工具可使用開源 CA 服務的外部核發者,向 CA 服務要求憑證。
私人 CA 可以核發 TLS 憑證,驗證並加密內部網路中的流量。Cloud Service Mesh 輸入閘道通常會設為允許來自虛擬私人雲端網路內部 (但位於服務網格外) 的用戶端傳入流量。針對內部網路流量,您可以使用 CA 服務中的私人 CA 核發輸入網關的憑證。
本教學課程說明如何設定 cert-manager 工具和 CA 服務核發者,以便自動為入口網關提供和更新 TLS 憑證。cert-manager 工具會將憑證設為 類型為 TLS 的 Kubernetes 密鑰資源。當 cert-manager 工具續購憑證時,會使用新憑證更新密鑰資源。入口閘道會執行 Envoy Proxy,並支援 Envoy 的機密探索服務 (SDS)。SDS 可讓入口網關開始使用新的憑證,而不需要管理員重新啟動或重新載入程序。
屬於網格一部分的 Sidecar 代理程式可以從 CA 服務或 Cloud Service Mesh 憑證授權單位取得 TLS 憑證。在本教學課程中,您會使用 CA 服務為側邊車 Proxy 和 ingress 閘道憑證建立憑證。這樣一來,您就能為所有 TLS 憑證使用一個根 CA。
下圖顯示您在本教學課程中佈建的資源。您為入站網關配置內部直通式網路負載平衡器。內部直通式網路負載平衡器不是 Proxy,因此不會終止 TCP 連線或執行 TLS 握手。而是將連線轉送至 istio-ingressgateway
部署作業的 Pod。
hello-example-com-credential
密鑰包含憑證和私密金鑰。hello
閘道會設定 istio-ingressgateway
部署的 Pod,以便使用這組憑證和私密金鑰,針對主機名稱為 hello.example.com
的請求執行 TLS 握手程序。
cert-manager
命名空間中 google-cas-issuer
部署的 Pod 會向您在 CA 服務中建立的 CA 要求憑證。您可以建立 Identity and Access Management 政策繫結,讓 ca-service-isser
容器可以使用 Workload Identity Federation for GKE 模擬 Google 服務帳戶。您可以為 CA 集區建立 IAM 政策繫結,授予此 Google 服務帳戶權限,以便在 CA 服務中向 CA 要求憑證。
目標
- 設定 CA 服務
- 建立 GKE 叢集
- 安裝 Cloud Service Mesh 控制層
- 安裝入口閘道
- 安裝 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」對話方塊中,按一下「授權」。按一下「Authorize」(授權),即可允許您在 Cloud Shell 中執行的
gcloud
指令使用您的使用者憑證,向 Google API 驗證。啟用 Resource Manager、GKE、GKE Hub、Cloud Service Mesh 憑證授權單位和 CA 服務 API:
gcloud services enable \ cloudresourcemanager.googleapis.com \ container.googleapis.com \ gkehub.googleapis.com \ meshca.googleapis.com \ privateca.googleapis.com
設定 CA 服務
在本節中,您將在 CA 服務中建立根 CA 和兩個子 CA。一個從屬 CA 會向入口閘道核發憑證,另一個從屬 CA 則會向網狀結構中的側載代理程式核發憑證。
為簡化操作,本教學課程中的 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 使用:
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 集區的名稱。例如:
建立並啟用向 ingress 閘道核發憑證的從屬 CA:
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 為 mTLS 核發用戶端和伺服器 TLS 憑證。
如果您希望入口網關使用簡易 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,為網格中的側載 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-admin
ClusterRole 提供的權限,才能為 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.25 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 服務中的 sidecar CA 集區,為網格中的 sidecar Proxy 核發憑證。--enable_registration
標記會將 GKE 叢集註冊至--fleet_id
標記指定的專案機群。在本教學課程中,GKE 叢集和機群會使用相同的專案。--managed
標記可設定代管的 Cloud Service Mesh 控制層。--output_dir
標記會指定asmcli
用來下載安裝 Cloud Service Mesh 所需檔案和設定的資料夾。您稍後會在教學課程中使用這些檔案。
安裝作業需要幾分鐘的時間。安裝完成後,您會看到以下輸出內容:
asmcli: Successfully installed ASM.
安裝入口閘道
在 Cloud Shell 中,為 ingress 閘道建立 Kubernetes 命名空間:
kubectl create namespace GATEWAY_NAMESPACE
- GATEWAY_NAMESPACE 是您要用於入口閘道的命名空間名稱。例如:
istio-ingress
。
- GATEWAY_NAMESPACE 是您要用於入口閘道的命名空間名稱。例如:
保留靜態內部 IP 位址,用於入口網關內部直通式網路負載平衡器:
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
表示 GKE 會在入口網關 Pod 前方佈建內部直通式網路負載平衡器。如果您移除這項註解,GKE 會改為佈建外部直通式網路負載平衡器。選用的服務註解
networking.gke.io/internal-load-balancer-allow-global-access: "true"
可讓虛擬私有雲中任何區域的用戶端存取內部直通式網路負載平衡器。如果移除這項註解,內部直通式網路負載平衡器只會接受來自虛擬私人雲端網路同一個區域的用戶端流量。
使用操作員資訊清單和
asmcli
指令碼在安裝控制層時下載的istioctl
工具,建立入口網站閘道安裝資訊清單:./asm-files/istioctl manifest generate \ --filename ingressgateway-operator.yaml \ --output ingressgateway
安裝入口閘道:
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 服務帳戶的名稱。例如:
建立 Identity and Access Management 政策繫結,允許憑證授權單位服務核發者控制器 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-issuer
Kubernetes 服務帳戶使用 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.workloadIdentityUser
CA 服務核發者控管員 Pod 會使用
ksa-google-cas-issuer
Kubernetes 服務帳戶。在 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 是範例應用程式的命名空間名稱。例如:
為範例應用程式建立部署資源:
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
為範例應用程式建立服務資源:
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
憑證命名空間必須與入口網頁閘道命名空間相符。通常只有平台管理員可以變更這個命名空間中的資源,因為變更可能會影響整個服務中介網。cert-manager 工具會在相同命名空間中為傳輸層安全標準憑證建立 Secret 資源。也就是說,應用程式管理員不需要擁有入口網關命名空間的存取權。
您可以在憑證的
dnsNames
清單中新增其他主機名稱。這些主機名稱會以主體別名 (SAN) 的形式加入憑證。為範例應用程式建立閘道資源:
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 閘道終止前往hello.example.com
的 TLS 流量。
閘道資訊清單會指定相互傳輸層安全標準 (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.yaml
Gateway 和 VirtualService 使用不同的命名空間。這個常見模式會限制閘道中以主機為基礎的路由變更,只有具備變更入口閘道命名空間資源權限的平台管理員才能變更。
應用程式管理員如果有權編輯範例應用程式命名空間中的 VirtualService,就能透過其他要求欄位 (例如網址路徑) 變更路由,而無須與平台管理員協調。
如要瞭解其他設定選項,請參閱 憑證、Gateway 和 VirtualService 資源的 API 說明文件。
您可以將驗證和授權政策套用至透過輸入網關進入服務網格的流量。如要這麼做,請參閱 Istio PeerAuthentication 和 AuthorizationPolicy API 的說明文件。
驗證解決方案
在本節中,您將驗證是否可以從服務中介網外部傳送使用 mTLS 的 HTTPS 要求至範例應用程式。如要驗證,您需要建立 Compute Engine VM 執行個體,向 CA 服務要求用戶端 TLS 憑證,然後使用這張憑證驗證對範例應用程式提出的要求。
您需要透過 SSH 存取 VM 執行個體。預設網路包含允許 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 服務帳戶的名稱。例如:
將 Google 服務帳戶的 CA 服務憑證要求者角色指派給閘道子 CA 集區:
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 ZONE
VM 執行個體需要
cloud-platform
範圍才能存取 CA Service API。將入口閘道內部直通式網路負載平衡器的 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 憑證和包含內部直通式網路負載平衡器 IP 位址的 ingress 閘道檔案複製到 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
將 HTTPS 要求從 VM 執行個體傳送至範例應用程式: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 位址,做為通訊埠 443 上主機hello.example.com
要求的目的。如果您省略這個標記,
curl
會嘗試使用 DNS 解析hello.example.com
主機名稱。由於這個主機名稱沒有 DNS 項目,因此 DNS 解析失敗。在您自己的環境中,建議您建立指向內部轉送 Network Load Balancer 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 憑證新增至 Linux Debian 發行版的信任 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
將 HTTPS 要求從 VM 執行個體傳送至範例應用程式: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 憑證存放區驗證入口網關的伺服器 TLS 憑證。離開 SSH 工作階段:
exit
疑難排解
如果 CA 服務發證機構控制器未建立 TLS 憑證密鑰,請查看 CA 服務發證機構控制器的記錄:
kubectl logs deployment/google-cas-issuer --namespace cert-manager
如果在安裝 Cloud Service Mesh 時發生問題,請執行 asmcli
工具來驗證 Cloud 專案和 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 Hub 取消註冊 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 集區中的 IAM 政策繫結:
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 使用指南。