為 Cloud Service Mesh 設定傳統版應用程式負載平衡器
總覽
如果您是現有的 Cloud Service Mesh 使用者,且擁有 Istiod 代管控制層,並想將傳統型應用程式負載平衡器設定為 Ingress 閘道,請參閱本文。傳統版應用程式負載平衡器也稱為傳統版外部應用程式負載平衡器。
如果您是 Cloud Service Mesh 新手,請勿使用這份文件。新使用者會自動設定為使用 Cloud Service Mesh 代管控制層。您無法將本文所述設定用於 Cloud Service Mesh 代管控制層
Cloud Load Balancing 提供許多雲端管理的邊緣功能,包括全域任播負載平衡、Google 管理的憑證、Identity and Access Management、Cloud Next Generation Firewall 和 Cloud Intrusion Detection System。Cloud Service Mesh 可在下列網格進入模型中,順暢整合這些邊緣功能。服務網格雲端閘道提供統一方式,可透過 Kubernetes Gateway API 同時設定 Cloud Service Mesh Ingress 閘道和 Cloud Load Balancing。
相較於先前的使用者指南「從邊緣到網格:透過 GKE Ingress 開放服務網格應用程式」,使用服務網格雲端閘道時,現在只要透過一個 Kubernetes Gateway 資源即可部署此模型,簡化雲端和叢集代管負載平衡的部署程序。
試閱限制
這項功能的預覽版有下列限制:
- 不支援多叢集閘道。
- 不支援 Autopilot 叢集。
- 系統僅支援傳統版應用程式負載平衡器。全域外部應用程式負載平衡器 (有時稱為進階負載平衡器) 和內部應用程式負載平衡器不支援這項功能。
- 傳統應用程式負載平衡器與 Cloud Service Mesh 進入閘道之間的流量會使用 TLS 加密。不過,傳統版應用程式負載平衡器不會驗證 Cloud Service Mesh 進入閘道提供的憑證。這項限制適用於 Google Cloud HTTP(S) 負載平衡器的所有使用者。
- 如果從叢集中刪除 Cloud Service Mesh
GatewayClasses
,系統不會自動重新安裝。不過,這不會影響功能的使用性。 - 路徑比對邏輯不符合 Gateway API 規格,而是按照
HTTPRoute
的順序比對。日後版本會根據 Gateway API 規格進行變更。
需求條件
- 代管式 Cloud Service Mesh 安裝在執行 1.24 以上版本的 Google Kubernetes Engine (GKE) 叢集上。不支援其他 GKE Enterprise 叢集。
- 僅限 Kubernetes Gateway API v1beta1 版。
必要條件
在專案中啟用下列 API:
- compute.googleapis.com
- container.googleapis.com
- certificatemanager.googleapis.com
- serviceusage.googleapis.com
gcloud services enable \ compute.googleapis.com \ container.googleapis.com \ certificatemanager.googleapis.com \ serviceusage.googleapis.com
為單一叢集網格部署服務網格雲端閘道
本節說明如何部署 Kubernetes Gateway 資源,該資源會部署傳統型應用程式負載平衡器和 Cloud Service Mesh Ingress 閘道。
透過代管 Cloud Service Mesh 啟用 Gateway API
在叢集中啟用 Gateway API。GKE 叢集必須為 1.24 以上版本。
以
rapid
或regular
做為發布管道,安裝受管理 Cloud Service Mesh。
部署閘道資源
部署服務網格雲端閘道時,Kubernetes Gateway 資源會用於部署 Cloud Load Balancing 和 Cloud Service Mesh 進入閘道,只需一個步驟即可完成。請注意,Kubernetes Gateway 資源與 Istio Gateway 資源不同。
如要進一步瞭解兩者的差異,請參閱「Kubernetes Gateways 和 Istio Gateways」。每個 Kubernetes Gateway 都有一個 GatewayClass,可指出其類型和固有功能。服務網格雲端閘道具有 GatewayClass,可部署 Cloud Load Balancing 和 Cloud Service Mesh 入口閘道。
將下列 GatewayClass 資訊清單儲存至名為
l7-gateway-class.yaml
的檔案:apiVersion: gateway.networking.k8s.io/v1beta1 kind: GatewayClass metadata: name: asm-l7-gxlb spec: controllerName: mesh.cloud.google.com/gateway
在叢集中部署 GatewayClass:
kubectl apply -f l7-gateway-class.yaml
確認安裝後是否出現 GatewayClass:
kubectl get gatewayclasses.gateway.networking.k8s.io
輸出內容類似如下:
NAME CONTROLLER asm-l7-gxlb mesh.cloud.google.com/gateway gke-l7-rilb networking.gke.io/gateway gke-l7-gxlb networking.gke.io/gateway
部署所有資源可能需要幾分鐘的時間。如果沒有看到預期輸出內容,請確認您已正確滿足必要條件。
您也會看到下列 GatewayClass:
gke-l7-gxlb networking.gke.io/gateway
這項設定用於部署基礎 Google Cloud 傳統版應用程式負載平衡器。
為服務網格雲端閘道建立專屬命名空間:
kubectl create namespace istio-ingress
將下列 Gateway 資訊清單儲存至名為
gateway.yaml
的檔案:kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: servicemesh-cloud-gw namespace: istio-ingress spec: gatewayClassName: asm-l7-gxlb listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All
在叢集的 istio-ingress 命名空間中部署 Gateway:
kubectl apply -f gateway.yaml
確認已建立 Kubernetes Gateway API 物件:
kubectl get gateways.gateway.networking.k8s.io -n istio-ingress
輸出內容類似如下:
NAME CLASS ADDRESS READY AGE asm-gw-gke-servicemesh-cloud-gw gke-l7-gxlb 34.111.114.64 True 9m40s asm-gw-istio-servicemesh-cloud-gw istio 9m44s servicemesh-cloud-gw asm-l7-gxlb 9m44s
部署這個 Kubernetes Gateway API 物件時,會發生下列情況:
- 已部署及設定外部 HTTP(S) 負載平衡器。這項作業可能需要幾分鐘的時間,但完成後,閘道會顯示 IP 位址,並註解已建立的 Compute Engine 負載平衡器資源名稱。
- 系統會在 istio-ingress 命名空間中建立 Cloud Service Mesh Ingress 閘道 Deployment。這會建立 Envoy Proxy 執行個體,接收來自負載平衡器的流量。
- 負載平衡器會加密所有流量,並將流量轉送至 Cloud Service Mesh Ingress 閘道。
您現在已具備完整基礎架構,可接受網格中的網際網路流量。請注意,這是最簡單的閘道部署方式。在接下來的幾節中,您會新增其他政策和功能,讓應用程式準備好投入正式環境。
應用程式和路由部署
為充分展示功能,您將應用程式部署至 Cloud Service Mesh,並透過閘道接收網際網路流量,以供範例用途。
為
default
命名空間加上標籤,啟用補充資訊植入功能。kubectl label namespace default istio-injection=enabled istio.io/rev- --overwrite
將下列 Gateway 資訊清單儲存至名為
whereami.yaml
的檔案:apiVersion: apps/v1 kind: Deployment metadata: name: whereami-v1 spec: replicas: 2 selector: matchLabels: app: whereami-v1 template: metadata: labels: app: whereami-v1 spec: containers: - name: whereami image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1 ports: - containerPort: 8080 env: - name: METADATA value: "whereami-v1" --- apiVersion: v1 kind: Service metadata: name: whereami-v1 spec: selector: app: whereami-v1 ports: - port: 8080 targetPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: whereami-v2 spec: replicas: 2 selector: matchLabels: app: whereami-v2 template: metadata: labels: app: whereami-v2 spec: containers: - name: whereami image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1 ports: - containerPort: 8080 env: - name: METADATA value: "whereami-v2" --- apiVersion: v1 kind: Service metadata: name: whereami-v2 spec: selector: app: whereami-v2 ports: - port: 8080 targetPort: 8080
這份資訊清單會為 whereami 建立
Service/whereami-v1
、Service/whereami-v2
、Deployment/whereami-v1
和Deployment/whereami-v2
,這是一個簡單的應用程式,會輸出 JSON 來指出自己的身分和位置。您將部署兩個不同版本。建立服務和部署作業:
kubectl apply -f whereami.yaml
啟動並執行後,叢集中就會有四個 whereami Pod。
確認四個 Pod 皆為正在執行的狀態:
kubectl get pods
輸出內容類似如下:
whereami-v1-7c76d89d55-qg6vs 2/2 Running 0 28s whereami-v1-7c76d89d55-vx9nm 2/2 Running 0 28s whereami-v2-67f6b9c987-p9kqm 2/2 Running 0 27s whereami-v2-67f6b9c987-qhj76 2/2 Running 0 27s
將下列 HTTPRoute 資訊清單儲存到名為
http-route.yaml
的檔案:kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: where-route spec: parentRefs: - kind: Gateway name: servicemesh-cloud-gw namespace: istio-ingress hostnames: - "where.example.com" rules: - matches: - headers: - name: version value: v2 backendRefs: - name: whereami-v2 port: 8080 - backendRefs: - name: whereami-v1 port: 8080
將
http-route.yaml
部署至叢集:kubectl apply -f http-route.yaml
這個 HTTPRoute 會參照
servicemesh-cloud-gw
,也就是說,它會設定服務網格雲端閘道,以便使用這些路由規則設定基礎 Cloud Service Mesh 輸入閘道。HTTPRoute 的功能與 Istio VirtualService 相同,但會使用 Kubernetes Gateway API 執行這項功能。由於 Gateway API 是 OSS 規格,且有許多基礎實作項目,因此最適合用來定義不同負載平衡器 (例如 Cloud Service Mesh 代理程式和負載平衡器) 的路由。從閘道擷取 IP 位址,以便將流量傳送至應用程式:
VIP=$(kubectl get gateways.gateway.networking.k8s.io asm-gw-gke-servicemesh-cloud-gw -o=jsonpath="{.status.addresses[0].value}" -n istio-ingress)
輸出內容為 IP 位址。
echo $VIP 34.111.61.135
將流量傳送至閘道 IP 位址,驗證這項設定是否正常運作。傳送一個含有
version: v2
標頭的要求,以及一個不含該標頭的要求,確認這兩個應用程式版本都能正確完成路由。curl ${VIP} -H "host: where.example.com" { "cluster_name": "gke1", "host_header": "where.example.com", "metadata": "whereami-v1", "node_name": "gke-gke1-default-pool-9b3b5b18-hw5z.c.church-243723.internal", "pod_name": "whereami-v1-67d9c5d48b-zhr4l", "pod_name_emoji": "⚒", "project_id": "church-243723", "timestamp": "2021-02-08T18:55:01", "zone": "us-central1-a" } curl ${VIP} -H "host: where.example.com" -H "version: v2" { "cluster_name": "gke1", "host_header": "where.example.com", "metadata": "whereami-v2", "node_name": "gke-gke1-default-pool-9b3b5b18-hw5z.c.church-243723.internal", "pod_name": "whereami-v2-67d9c5d48b-zhr4l", "pod_name_emoji": "⚒", "project_id": "church-243723", "timestamp": "2021-02-08T18:55:01", "zone": "us-central1-a" }
部署正式版閘道
上一節介紹了服務網格雲端閘道的簡單範例。以下步驟會以簡單的範例為基礎,說明如何設定適用於正式環境的設定,並展示將部分 Ingress 路由功能委派給負載平衡器的優點。
在下列範例中,您將採用上一節的 servicemesh-cloud-gw
,並新增下列功能,建立更安全且易於管理的閘道:
- 部署閘道時使用靜態 IP 位址,即使基礎架構變更,該位址也會保留。
- 轉換 Gateway,透過自行簽署的憑證接收 HTTPS 流量。
建立靜態外部 IP 位址。靜態 IP 很實用,因為基礎架構日後可能會變更,但 IP 位址可以保留。
gcloud compute addresses create whereami-ip \ --global \ --project PROJECT_ID
為
where-example-com
網域建立自行簽署的憑證:openssl genrsa -out key.pem 2048 cat <<EOF >ca.conf [req] default_bits = 2048 req_extensions = extension_requirements distinguished_name = dn_requirements prompt = no [extension_requirements] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @sans_list [dn_requirements] 0.organizationName = example commonName = where.example.com [sans_list] DNS.1 = where.example.com EOF
openssl req -new -key key.pem \ -out csr.pem \ -config ca.conf
openssl x509 -req \ -signkey key.pem \ -in csr.pem \ -out cert.pem \ -extfile ca.conf \ -extensions extension_requirements \ -days 365
gcloud compute ssl-certificates create where-example-com \ --certificate=cert.pem \ --private-key=key.pem \ --global \ --project PROJECT_ID
產生 TLS 憑證的方法有很多種。您可以在指令列上手動產生憑證,也可以使用 Google 管理的憑證產生憑證,或由貴公司的公用金鑰基礎架構 (PKI) 系統在內部產生憑證。在本範例中,您會手動產生自行簽署的憑證。雖然自行簽署的憑證通常不會用於公開服務,但可更輕鬆地說明這些概念。
如要進一步瞭解如何透過 Kubernetes Secret 建立自我簽署憑證,請參閱「保護閘道安全」。
使用下列資訊清單更新
gateway.yaml
:kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: servicemesh-cloud-gw namespace: istio-ingress spec: gatewayClassName: asm-l7-gxlb listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All - name: https protocol: HTTPS port: 443 allowedRoutes: namespaces: from: All tls: mode: Terminate options: networking.gke.io/pre-shared-certs: where-example-com addresses: - type: NamedAddress value: whereami-ip
在叢集中重新部署 Gateway:
kubectl apply -f gateway.yaml
取得靜態 IP 的 IP 位址:
VIP=$(gcloud compute addresses describe whereami-ip --global --format="value(address)")
使用
curl
存取閘道的網域。由於未設定這個網域的 DNS,請使用 --resolve 選項,告知 curl 將網域名稱解析為 Gateway 的 IP 位址:curl https://where.example.com --resolve where.example.com:443:${VIP} --cacert cert.pem -v
完成後,輸出內容會類似如下:
... * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305 * ALPN, server accepted to use h2 * Server certificate: * subject: O=example; CN=where.example.com * start date: Apr 19 15:54:50 2021 GMT * expire date: Apr 19 15:54:50 2022 GMT * common name: where.example.com (matched) * issuer: O=example; CN=where.example.com * SSL certificate verify ok. ... { "cluster_name": "gke1", "host_header": "where.example.com", "metadata": "where-v1", "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal", "pod_name": "where-v1-84b47c7f58-tj5mn", "pod_name_emoji": "😍", "project_id": "agmsb-k8s", "timestamp": "2021-04-19T16:30:08", "zone": "us-west1-a" }
詳細輸出內容會包含成功的 TLS 握手,以及應用程式的回應,如下列輸出內容所示。這證明 TLS 在閘道正確終止,且應用程式安全地回應用戶端。
您已成功部署下列架構:
servicemesh-cloud-gw
和其 asm-l7-gxlb
GatewayClass 已抽象化部分內部基礎架構元件,以簡化使用者體驗。Cloud Load Balancing 會使用內部憑證終止 TLS 流量,並檢查 Cloud Service Mesh Ingress 閘道 Proxy 層的健康狀態。whereami-route
部署在「應用程式和轉送部署」中的設定,會設定 Cloud Service Mesh Ingress 閘道 Proxy,將流量轉送至正確的網格代管服務。
在下列範例中,您將採用上一節的 servicemesh-cloud-gw
,並新增下列功能,建立更安全且易於管理的閘道:
- 部署閘道時使用靜態 IP 位址,即使基礎架構變更,該位址也會保留。
- 轉換 Gateway,透過自行簽署的憑證接收 HTTPS 流量。
建立靜態外部 IP 位址。靜態 IP 很實用,因為基礎架構日後可能會變更,但 IP 位址可以保留。
gcloud compute addresses create whereami-ip \ --global \ --project PROJECT_ID
為
where-example-com
網域建立自行簽署的憑證:openssl genrsa -out key.pem 2048 cat <<EOF >ca.conf [req] default_bits = 2048 req_extensions = extension_requirements distinguished_name = dn_requirements prompt = no [extension_requirements] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @sans_list [dn_requirements] 0.organizationName = example commonName = where.example.com [sans_list] DNS.1 = where.example.com EOF
openssl req -new -key key.pem \ -out csr.pem \ -config ca.conf
openssl x509 -req \ -signkey key.pem \ -in csr.pem \ -out cert.pem \ -extfile ca.conf \ -extensions extension_requirements \ -days 365
gcloud compute ssl-certificates create where-example-com \ --certificate=cert.pem \ --private-key=key.pem \ --global \ --project PROJECT_ID
產生 TLS 憑證的方法有很多種。您可以在指令列上手動產生憑證,也可以使用 Google 管理的憑證產生憑證,或由貴公司的公用金鑰基礎架構 (PKI) 系統在內部產生憑證。在本範例中,您會手動產生自行簽署的憑證。雖然自行簽署的憑證通常不會用於公開服務,但可更輕鬆地說明這些概念。
如要進一步瞭解如何透過 Kubernetes Secret 建立自我簽署憑證,請參閱「保護閘道安全」。
使用下列資訊清單更新
gateway.yaml
:kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: servicemesh-cloud-gw namespace: istio-ingress spec: gatewayClassName: asm-l7-gxlb listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All - name: https protocol: HTTPS port: 443 allowedRoutes: namespaces: from: All tls: mode: Terminate options: networking.gke.io/pre-shared-certs: where-example-com addresses: - type: NamedAddress value: whereami-ip
在叢集中重新部署 Gateway:
kubectl apply -f gateway.yaml
取得靜態 IP 的 IP 位址:
VIP=$(gcloud compute addresses describe whereami-ip --global --format="value(address)")
使用
curl
存取閘道的網域。由於未設定這個網域的 DNS,請使用 --resolve 選項,告知 curl 將網域名稱解析為 Gateway 的 IP 位址:curl https://where.example.com --resolve where.example.com:443:${VIP} --cacert cert.pem -v
完成後,輸出內容會類似如下:
... * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305 * ALPN, server accepted to use h2 * Server certificate: * subject: O=example; CN=where.example.com * start date: Apr 19 15:54:50 2021 GMT * expire date: Apr 19 15:54:50 2022 GMT * common name: where.example.com (matched) * issuer: O=example; CN=where.example.com * SSL certificate verify ok. ... { "cluster_name": "gke1", "host_header": "where.example.com", "metadata": "where-v1", "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal", "pod_name": "where-v1-84b47c7f58-tj5mn", "pod_name_emoji": "😍", "project_id": "agmsb-k8s", "timestamp": "2021-04-19T16:30:08", "zone": "us-west1-a" }
詳細輸出內容會包含成功的 TLS 握手,以及應用程式的回應,如下列輸出內容所示。這證明 TLS 在閘道正確終止,且應用程式安全地回應用戶端。
您已成功部署下列架構:
servicemesh-cloud-gw
和其 asm-l7-gxlb
GatewayClass 已抽象化部分內部基礎架構元件,以簡化使用者體驗。Cloud Load Balancing 會使用內部憑證終止 TLS 流量,並檢查 Cloud Service Mesh Ingress 閘道 Proxy 層的健康狀態。whereami-route
部署在「應用程式和轉送部署」中的設定,會設定 Cloud Service Mesh Ingress 閘道 Proxy,將流量轉送至正確的網格代管服務。
後續步驟
- 進一步瞭解 Kubernetes Gateway API 的 Google Kubernetes Engine (GKE) 實作方式。
- 瞭解如何啟用選用的代管型 Cloud Service Mesh 功能。