All Products
Search
Document Center

Alibaba Cloud Service Mesh:Enable HTTPS on an ASM ingress gateway

Last Updated:Mar 11, 2026

Service Mesh (ASM) ingress gateways support dynamic certificate loading through Istio's Secret Discovery Service (SDS). You can dynamically configure private keys, server certificates, and root certificates without restarting the gateway or mounting secret volumes. A single gateway can serve multiple certificates for different hosts, so you can manage HTTPS across all your domains from one entry point.

How it works

When you create a Kubernetes secret containing a TLS certificate and private key, the ingress gateway detects it and loads the certificate automatically. The gateway watches for secrets in the same namespace as the ingress gateway and dynamically loads them through the credentialName field in the Gateway resource.

  • Zero-downtime certificate updates -- Add, replace, or remove certificates without restarting the ingress gateway.

  • No volume mounts required -- The gateway reads certificates directly from Kubernetes secrets.

  • Multi-host support -- Create separate secrets for each domain and reference them in a single Gateway resource.

Prerequisites

Step 1: Generate TLS certificates

Note

A domain name must have an Internet Content Provider (ICP) filing before it can serve traffic in China.

Create a self-signed certificate and private key for the aliyun.com domain. If you already have a certificate and private key for this domain, rename them to aliyun.com.crt and aliyun.com.key, then skip to Step 2.

  1. Generate a root certificate and private key:

       openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 \
         -subj '/O=myexample Inc./CN=aliyun.com' \
         -keyout aliyun.root.key -out aliyun.root.crt
  2. Generate a server certificate and private key signed by the root certificate:

       openssl req -out aliyun.com.csr -newkey rsa:2048 -nodes \
         -keyout aliyun.com.key -subj "/CN=aliyun.com/O=myexample organization"
    
       openssl x509 -req -days 365 -CA aliyun.root.crt -CAkey aliyun.root.key \
         -set_serial 0 -in aliyun.com.csr -out aliyun.com.crt

Step 2: Store the certificate

Choose one of the following methods based on your ASM instance version.

ASM versions earlier than 1.17

Use kubectl to create a TLS secret in the istio-system namespace:

kubectl create -n istio-system secret tls myexample-credential \
  --key=aliyun.com.key --cert=aliyun.com.crt
Important

The secret name must not start with istio or prometheus, and must not contain the token field.

ASM 1.17 or later (recommended)

Use the ASM console to upload the certificate:

  1. Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.

  2. On the Mesh Management page, click the name of your ASM instance. In the left-side navigation pane, choose ASM Gateways > Certificate Management.

  3. Click Create. In the Certificate Information panel, configure the following parameters and click OK.

    ParameterDescription
    NameEnter myexample-credential.
    Public Key CertificatePaste the contents of aliyun.com.crt generated in Step 1.
    Private KeyPaste the contents of aliyun.com.key generated in Step 1.

Step 3: Deploy sample backend services

This step deploys two sample services behind the ingress gateway. If you already have backend services running in the cluster, skip to Step 4.

Service A: NGINX (for a.aliyun.com)

  1. Create an NGINX configuration file named myexample-nginx.conf:

       events {
       }
       http {
         log_format main '$remote_addr - $remote_user [$time_local]  $status '
         '"$request" $body_bytes_sent "$http_referer" '
         '"$http_user_agent" "$http_x_forwarded_for"';
         access_log /var/log/nginx/access.log main;
         error_log  /var/log/nginx/error.log;
         server {
           listen 80;
           location /hello {
               return 200 'Welcome to a.aliyun.com!';
               add_header Content-Type text/plain;
           }
         }
       }
  2. Create a ConfigMap from the configuration file:

       kubectl create configmap myexample-nginx-configmap \
         --from-file=nginx.conf=./myexample-nginx.conf
  3. Enable automatic sidecar proxy injection for the default namespace.

  4. Create a file named myexampleapp.yaml with the following content, then deploy it:

       kubectl apply -f myexampleapp.yaml

    myexampleapp.yaml

       apiVersion: v1
       kind: Service
       metadata:
         name: myexampleapp
         labels:
           app: myexampleapp
       spec:
         ports:
         - port: 80
           protocol: TCP
         selector:
           app: myexampleapp
       ---
       apiVersion: apps/v1
       kind: Deployment
       metadata:
         name: myexampleapp
       spec:
         selector:
           matchLabels:
             app: myexampleapp
         replicas: 1
         template:
           metadata:
             labels:
               app: myexampleapp
           spec:
             containers:
             - name: nginx
               image: nginx
               ports:
               - containerPort: 80
               volumeMounts:
               - name: nginx-config
                 mountPath: /etc/nginx
                 readOnly: true
             volumes:
             - name: nginx-config
               configMap:
                 name: myexample-nginx-configmap

Service B: HTTPBin (for b.aliyun.com)

  1. Create a file named httpbin.example.yaml with the following content, then deploy it:

       kubectl apply -f httpbin.example.yaml

    httpbin.example.yaml

       apiVersion: v1
       kind: Service
       metadata:
         name: httpbin
         labels:
           app: httpbin
       spec:
         ports:
         - name: http
           port: 8000
         selector:
           app: httpbin
       ---
       apiVersion: apps/v1
       kind: Deployment
       metadata:
         name: httpbin
       spec:
         replicas: 1
         selector:
           matchLabels:
             app: httpbin
             version: v1
         template:
           metadata:
             labels:
               app: httpbin
               version: v1
           spec:
             containers:
             - image: docker.io/citizenstig/httpbin
               imagePullPolicy: IfNotPresent
               name: httpbin
               ports:
               - containerPort: 80

Step 4: Create a Gateway resource

Define an Istio Gateway that terminates TLS on port 443 using the certificate stored in myexample-credential. The wildcard host *.aliyun.com allows this single gateway to handle HTTPS traffic for all subdomains.

  1. Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.

  2. On the Mesh Management page, click the name of your ASM instance. In the left-side navigation pane, choose ASM Gateways > Gateway. Click Create from YAML.

  3. Select the default namespace, paste the following YAML, and click Create:

    Show the YAML file

       apiVersion: networking.istio.io/v1alpha3
       kind: Gateway
       metadata:
         name: mysdsgateway
       spec:
         selector:
           istio: ingressgateway
         servers:
         - port:
             number: 443
             name: https
             protocol: HTTPS
           tls:
             mode: SIMPLE
             credentialName: myexample-credential  # Must match the secret or certificate name
           hosts:
           - '*.aliyun.com'

The gateway appears on the Gateway page after creation.

Step 5: Create virtual services

Create VirtualService resources to route traffic from the gateway to backend services.

  1. Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.

  2. On the Mesh Management page, click the name of your ASM instance. In the left-side navigation pane, choose Traffic Management Center > VirtualService. Click Create from YAML.

  3. Create a VirtualService for a.aliyun.com:

    Show the YAML file

       apiVersion: networking.istio.io/v1alpha3
       kind: VirtualService
       metadata:
         name: mysdsgateway-myexamplevs
       spec:
         hosts:
         - "a.aliyun.com"
         gateways:
         - mysdsgateway
         http:
         - match:
           - uri:
               exact: /hello
           route:
           - destination:
               host: myexampleapp.default.svc.cluster.local
               port:
                 number: 80
  4. Create another VirtualService for b.aliyun.com:

    Show the YAML file

       apiVersion: networking.istio.io/v1alpha3
       kind: VirtualService
       metadata:
         name: mysdsgateway-httpbinvs
       spec:
         hosts:
         - "b.aliyun.com"
         gateways:
         - mysdsgateway
         http:
         - match:
           - uri:
               prefix: /status
           - uri:
               prefix: /delay
           route:
           - destination:
               port:
                 number: 8000
               host: httpbin.default.svc.cluster.local

Both virtual services appear on the VirtualService page after creation.

Step 6: Verify the setup

Get the ingress gateway IP address

Retrieve the IP address using one of the following methods:

  • ASM console: Log on to the ASM console, navigate to the ASM instance, then choose ASM Gateways > Ingress Gateway to find the IP address.

  • ACK console: View the ingress gateway in the ACK console. For details, see the "View the ingress gateway in the ACK console" section of Create an ingress gateway.

Store the IP address in an environment variable so you can reuse it in the verification commands:

export INGRESS_HOST=<ingress-gateway-ip>

Replace <ingress-gateway-ip> with the actual IP address of your ingress gateway.

Test HTTPS access

Send a request to a.aliyun.com:

curl -k -HHost:a.aliyun.com \
  --resolve "a.aliyun.com:443:${INGRESS_HOST}" \
  https://a.aliyun.com/hello

Expected output:

Welcome to aliyun.com!

Send a request to b.aliyun.com:

curl -k -HHost:b.aliyun.com \
  --resolve "b.aliyun.com:443:${INGRESS_HOST}" \
  https://b.aliyun.com/status/418

Expected output:

-=[ teapot ]=-

       _...._
     .'  _ _ `.
    | ."` ^ `". _,
    \_;`"---"`|//
      |       ;/
      \_     _/
        `"""`

Update a gateway certificate

To rotate or replace a certificate, create a new secret and update the credentialName in the Gateway resource. The ingress gateway picks up the new certificate automatically -- no restart required.

The following example replaces the certificate with a new one for example.com.

Create a new certificate

  1. Generate a root certificate and private key:

       openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 \
         -subj '/O=myexample Inc./CN=example.com' \
         -keyout example.root.key -out example.root.crt
  2. Generate a server certificate and private key:

       openssl req -out example.com.csr -newkey rsa:2048 -nodes \
         -keyout example.com.key -subj "/CN=example.com/O=myexample organization"
    
       openssl x509 -req -days 365 -CA example.root.crt -CAkey example.root.key \
         -set_serial 0 -in example.com.csr -out example.com.crt
  3. Obtain the kubeconfig file and connect kubectl to the cluster.

  4. Create a new secret:

       kubectl create -n istio-system secret tls new-istio-ingressgateway-certs \
         --key example.com.key --cert example.com.crt
  5. Delete the old secret:

       kubectl delete secret istio-ingressgateway-certs -n istio-system

Update the Gateway resource

  1. Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.

  2. On the Mesh Management page, click the name of your ASM instance. In the left-side navigation pane, choose ASM Gateways > Gateway.

  3. Find the target gateway and click YAML in the Actions column.

  4. In the Edit dialog box, change credentialName to new-istio-ingressgateway-certs and click OK.

Verify the certificate update

  1. Dump the ingress gateway configuration: Replace <ingress-gateway-pod> with the actual pod name (for example, istio-ingressgateway-xxxx).

       kubectl exec <ingress-gateway-pod> -n istio-system -- \
         curl localhost:15000/config_dump > ingressgateway_dump.yaml
  2. Search for the new certificate name in the dump:

       grep new-istio-ingressgateway-certs -A 3 ingressgateway_dump.yaml
  3. Copy the value of the inline_bytes field from the output. This is the Base64-encoded certificate.

  4. Decode the certificate and save it to a file: Replace <base64-encoded-certificate> with the actual value from the previous step.

       echo <base64-encoded-certificate> | base64 --decode > test.com.crt
  5. Verify the certificate issuer: If the Organization field shows myexample, the certificate update was successful.

       openssl x509 -in test.com.crt -text -noout