Set up TLS termination in ingress gateway
Overview
This page demonstrates how to set up a TLS termination in ingress gateway in Cloud Service Mesh to manage external HTTPS traffic to your services. For a more basic introduction on how to setup gateways, refer to the gateways guide. You will learn how to configure the gateway for secure communication using TLS, enabling encrypted access to your applications. This process leverages Cloud Service Mesh capabilities to expose services securely.
Before you begin
You need the following resources to complete the steps in this document:
- A Kubernetes cluster with Cloud Service Mesh installed. See the installation guide for details on how to install Cloud Service Mesh.
Set up your environment
Run the following commands from a workstation that can access the cluster you
intend to use. Make sure that the kubectl
tool is configured to use the
cluster context specific to your cluster.
Set the environment variables.
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
Deploy the
foo
application in your cluster. Install it with the following 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
Generate certificates and keys.
To secure your ingress gateway, you will need TLS certificates and keys. You can use any certificate generation tool or follow these steps using openssl to create the necessary credentials.
- Create a root CA certificate and key
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
- Generate a certificate and key for 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
Set up a TLS ingress gateway
The following steps describe how to set up a TLS ingress gateway.
Store the TLS certificate
Create the namespace. This namespace is used to deploy the ingress gateway.
kubectl create namespace ${CSM_INGRESSGATEWAY_NAMESPACE}
Apply the default injection label to the namespace:
kubectl label namespace ${CSM_INGRESSGATEWAY_NAMESPACE} \ istio.io/rev- istio-injection=enabled --overwrite
Store the TLS credentials in a 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
Apply the TLS certificate to gateway
There are two ways to get the gateway to use the newly created TLS certificate.
Deployment with mounted credentials (Preferred)
Copy the default ingress gateway manifest into a local file.
curl https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-service-mesh-samples/main/docs/ingress-gateway-external-lb/ingress-gateway.yaml > ingress-gateway.yaml
Amend the deployment spec in
ingress-gateway.yaml
to mount the TLS secret credential.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
Then create the resources pertaining to the ingress gateway.
kubectl --namespace ${CSM_INGRESSGATEWAY_NAMESPACE} apply --filename ingress-gateway.yaml
Define the ingress gateway.
Create a Gateway resource to handle HTTPS traffic on port 443 that references the mounted secrets:
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
Deployment without mounted credentials
Apply the ingress gateway manifest file.
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
Expected output:
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
Define the ingress gateway.
Create a Gateway resource to handle HTTPS traffic on port 443:
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
Test Traffic
Route traffic to the foo service.
Define a VirtualService to direct traffic to the foo deployment:
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
Set up the external load balancer to connect with the ingress gateway from the cluster.
Test the secure connection.
Use the following curl command to verify the setup:
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"
Replace
EXTERNAL_LB_IP_ADDRESS
with ip of external load balancer.The output is similar to the following:
{ "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" }
What's next
- Read more about Installing and upgrading gateways