在 Ingress 閘道中設定 TLS 終止
總覽
本頁面說明如何在 Cloud Service Mesh 的輸入閘道中設定 TLS 終止,以便管理服務的 HTTPS 外部流量。如要進一步瞭解如何設定閘道,請參閱閘道指南。您將瞭解如何使用 TLS 設定閘道,以便進行安全通訊,並啟用應用程式的加密存取權。這個程序會運用 Cloud Service Mesh 功能,安全地公開服務。
事前準備
您需要以下資源才能完成本文件中的步驟:
- 已安裝 Cloud Service Mesh 的 Kubernetes 叢集。如要進一步瞭解如何安裝 Cloud Service Mesh,請參閱安裝指南。
設定環境
請在可存取您要使用的叢集的工作站上執行下列指令。請確認 kubectl
工具已設定為使用叢集專屬的叢集背景資訊。
設定環境變數。
export CSM_INGRESSGATEWAY_NAMESPACE=CSM_INGRESSGATEWAY_NAMESPACE export CSM_INGRESSGATEWAY_DEPLOYMENT_NAME=CSM_INGRESSGATEWAY_DEPLOYMENT_NAME export CSM_INGRESSGATEWAY_SERVICE_NAME=CSM_INGRESSGATEWAY_SERVICE_NAME
在叢集中部署
foo
應用程式。請使用下列 yaml 安裝:apiVersion: v1 kind: Service metadata: name: foo namespace: foo spec: selector: app: test-backend ports: - port: 8080 targetPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: foo namespace: foo spec: replicas: 2 selector: matchLabels: app: test-backend template: metadata: labels: app: test-backend spec: containers: - name: whereami image: gcr.io/google-samples/whereami:v1.2.23 ports: - containerPort: 8080 EOF
產生憑證和金鑰。
如要保護入口網關,您需要 TLS 憑證和金鑰。您可以使用任何憑證產生工具,或按照下列步驟使用 openssl 建立必要的憑證。
- 建立根 CA 憑證和金鑰
mkdir example_certs openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=Example Corp/CN=example.com' \ -keyout example.com.key -out example.com.crt
- 產生 ingress 的憑證和金鑰
openssl req -out foo.example.com.csr -newkey rsa:2048 -nodes \ -keyout foo.example.com.key -subj "/CN=foo.example.com/O=Foo Org" openssl x509 -req -sha256 -days 365 -CA example.com.crt \ -CAkey example.com.key -set_serial 0 \ -in foo.example.com.csr -out foo.example.com.crt
儲存 TLS 憑證
將 TLS 憑證儲存為 Secret
。
建立命名空間。這個命名空間用於部署入口網關。
kubectl create namespace ${CSM_INGRESSGATEWAY_NAMESPACE}
將預設的注入標籤套用至命名空間:
kubectl label namespace ${CSM_INGRESSGATEWAY_NAMESPACE} \ istio.io/rev- istio-injection=enabled --overwrite
將 TLS 憑證儲存在 Kubernetes 密鑰中:
kubectl create -n ${CSM_INGRESSGATEWAY_NAMESPACE} secret tls foo-credential \ --key=example_certs/foo.example.com.key \ --cert=example_certs/foo.example.com.crt
將 TLS 憑證套用至閘道
有兩種方法可讓閘道使用新建立的 TLS 憑證。
使用已掛載憑證的部署作業 (建議做法)
將預設 Ingress 網關資訊清單複製到本機檔案中。
curl https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-service-mesh-samples/main/docs/ingress-gateway-external-lb/ingress-gateway.yaml > ingress-gateway.yaml
修正
ingress-gateway.yaml
中的部署規格,以掛載 TLS 密鑰憑證。apiVersion: apps/v1 kind: Deployment ... spec: ... spec: ... volumeMounts: - name: foo-credential # Add new volume mount specifying mount path. mountPath: /etc/secrets/foo-credential readOnly: true volumes: - name: foo-credential # Point volume mount to the Kubernetes secret holding the TLS certificate and keys. secret: secretName: foo-credential
接著,建立與入口網關相關的資源。
kubectl --namespace ${CSM_INGRESSGATEWAY_NAMESPACE} apply --filename ingress-gateway.yaml
定義輸入閘道。
建立閘道資源,以便處理參照已掛載機密金鑰的通訊埠 443 上的 HTTPS 流量:
cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1 kind: Gateway metadata: name: secure-gateway namespace: ${CSM_INGRESSGATEWAY_NAMESPACE} spec: selector: app: asm-ingressgateway istio: ingressgateway servers: - port: number: 443 name: https protocol: HTTPS tls: mode: SIMPLE serverCertificate: /etc/secrets/foo-credential/foo.example.com.crt privateKey: /etc/secrets/foo-credential/foo.example.com.key hosts: - "foo.example.com" EOF
未掛載憑證的部署作業
-
kubectl --namespace ${CSM_INGRESSGATEWAY_NAMESPACE} apply --filename https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-service-mesh-samples/main/docs/ingress-gateway-external-lb/ingress-gateway.yaml
預期輸出內容:
serviceaccount/asm-ingressgateway created role.rbac.authorization.k8s.io/asm-ingressgateway created rolebinding.rbac.authorization.k8s.io/asm-ingressgateway created deployment.apps/asm-ingressgateway created service/asm-ingressgateway created poddisruptionbudget.policy/asm-ingressgateway created horizontalpodautoscaler.autoscaling/asm-ingressgateway created
定義輸入閘道。
建立閘道資源,以便處理通訊埠 443 上的 HTTPS 流量:
cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1 kind: Gateway metadata: name: secure-gateway namespace: ${CSM_INGRESSGATEWAY_NAMESPACE} spec: selector: app: asm-ingressgateway istio: ingressgateway servers: - port: number: 443 name: https protocol: HTTPS tls: mode: SIMPLE credentialName: foo-credential hosts: - "foo.example.com" EOF
最佳化部署作業
如果您使用部署作業而未掛載憑證,入口網站閘道 Pod 會定期檢查憑證是否已更新。根據預設,這項作業最多需要 60 分鐘。如要變更輪詢頻率,請為入口網關 Pod 部署設定 CSM_MIN_K8S_SECRET_REFRESH_INTERVAL
和 CSM_MAX_K8S_SECRET_REFRESH_INTERVAL
環境變數。
apiVersion: apps/v1
kind: Deployment
metadata:
name: asm-ingressgateway
...
spec:
...
template:
...
spec:
containers:
- name: istio-proxy
image: auto
env:
- name: CSM_MIN_K8S_SECRET_REFRESH_INTERVAL
value: "15m" # Half of the default minimum interval
- name: CSM_MAX_K8S_SECRET_REFRESH_INTERVAL
value: "30m" # Half of the default maximum interval
...
測試流量
將流量轉送至 foo 服務。
定義 VirtualService,將流量導向至 foo 部署:
cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1 kind: VirtualService metadata: name: foo-routing namespace: ${CSM_INGRESSGATEWAY_NAMESPACE} spec: hosts: - "foo.example.com" gateways: - secure-gateway http: - match: - uri: prefix: /status - uri: prefix: /delay route: - destination: host: foo port: number: 8080 EOF
設定外部負載平衡器,以便從叢集連線至入口閘道。
測試安全連線。
使用下列 curl 指令驗證設定:
export EXTERNAL_LB_IP_ADDRESS=EXTERNAL_LB_IP_ADDRESS curl -v -H "Host: foo.example.com" --resolve "foo.example.com:443:$EXTERNAL_LB_IP_ADDRESS" \ --cacert example_certs/example.com.crt "https://foo.example.com:443/ping"
將
EXTERNAL_LB_IP_ADDRESS
替換為外部負載平衡器的 IP。輸出結果會與下列內容相似:
{ "cluster_name": "gke-us", "host_header": "34.120.175.141", "pod_name": "whereami-deployment-954cbf78-mtlpf", "pod_name_emoji": "😎", "project_id": "my-project", "timestamp": "2021-11-29T17:01:59", "zone": "us-central1-b" }
後續步驟
- 進一步瞭解安裝及升級閘道