在入站流量网关中设置 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
- 为入站流量生成证书和密钥
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 Secret 中:
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 证书。
使用已挂载凭据进行部署(首选)
将默认入站流量网关清单复制到本地文件中。
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
定义入站网关。
创建一个 Gateway 资源,用于处理引用已挂载 Secret 的端口 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
定义入站网关。
创建 Gateway 资源以处理端口 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" }
后续步骤
- 详细了解安装和升级网关