Service Mesh (ASM) ingress gateways support dynamic certificate loading through the Secret Discovery Service (SDS). You can add, update, or remove Transport Layer Security (TLS) certificates in real time without restarting the gateway or mounting secret volumes. This eliminates service interruptions during certificate changes and simplifies multi-host HTTPS management.
How it works
The ingress gateway watches for Kubernetes Secrets in the same namespace as the ingress gateway. When a Gateway resource references a Secret by name through its credentialName field, the gateway automatically loads the associated certificate and private key. Changes to the Secret take effect immediately.
Benefits:
No restarts required -- You can dynamically add, delete, and update the server certificate and private key or the root certificate without restarting the ingress gateway.
No secret volume mounts -- The gateway reads the server certificate and private key or the root certificate directly from Kubernetes Secrets.
Multi-host support -- A single gateway can serve HTTPS traffic for multiple domains, each with its own certificate.
Prerequisites
Before you begin, make sure that you have:
Step 1: Create server certificates and private keys
A domain name must have an Internet Content Provider (ICP) filing before it can be accessed. This example uses aliyun.com as the domain.
If you already have a certificate and private key for aliyun.com, rename them to aliyun.com.crt and aliyun.com.key. Otherwise, generate self-signed certificates with OpenSSL:
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.crtGenerate a server certificate and private key for
aliyun.com: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.crtStore the certificate in your ASM instance. The method depends on your ASM version:
ASM versions earlier than 1.17
Connect to the cluster where the ingress gateway pod runs using kubectl, then create a TLS Secret in the
istio-systemnamespace:kubectl create -n istio-system secret tls myexample-credential --key=aliyun.com.key --cert=aliyun.com.crtImportantThe Secret name must not start with
istioorprometheus, and must not contain atokenfield.ASM version 1.17 or later
Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.
On the Mesh Management page, click the name of your ASM instance. In the left-side navigation pane, choose ASM Gateways > Certificate Management.
On the Certificate Management page, click Create. In the Certificate Information panel, configure the following parameters and click OK.
Parameter Value Name myexample-credentialPublic Key Certificate Content of aliyun.com.crtgenerated in substep 2Private Key Content of aliyun.com.keygenerated in substep 2
Step 2: Deploy a backend service for a.aliyun.com
This step deploys an NGINX-based backend service that returns a greeting at the /hello path.
Create an NGINX configuration file named
myexample-nginx.confwith the following content: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; } } }In the cluster where the ingress gateway pod runs, create a ConfigMap to store the NGINX configuration:
kubectl create configmap myexample-nginx-configmap --from-file=nginx.conf=./myexample-nginx.confEnable automatic sidecar proxy injection for the
defaultnamespace. For more information, see Enable automatic sidecar proxy injection.Create a file named
myexampleapp.yamlwith the following content, then deploy it:kubectl apply -f myexampleapp.yaml
Step 3: Deploy a backend service for b.aliyun.com
This step deploys an httpbin-based backend service that provides HTTP testing endpoints.
Create a file named
httpbin.example.yamlwith the following content:Deploy the service:
kubectl apply -f httpbin.example.yaml
Step 4: Create a Gateway resource
Define an Istio Gateway that terminates TLS on port 443 for all *.aliyun.com hosts, using the certificate stored in myexample-credential.
Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.
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.
Select the default namespace, paste the following YAML, and click Create:
The
credentialNamefield must match the Secret or certificate name created in Step 1. The gateway dynamically loads the certificate referenced by this name.
Step 5: Create virtual services
Define a VirtualService for each backend to route HTTPS traffic from the Gateway to the corresponding service.
Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.
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.
Create a VirtualService for
a.aliyun.com:Create a VirtualService for
b.aliyun.com:
Verify the result
Get the ingress gateway IP address
Use either of the following methods:
ASM console: Log on to the ASM console, find your ASM instance, then choose ASM Gateways > Ingress Gateway to view the IP address.
ACK console: See the "View the ingress gateway in the ACK console" section in Create an ingress gateway.
Test HTTPS access
Set the INGRESS_HOST variable to the IP address you obtained, then run the verification commands.
export INGRESS_HOST=<ingress-gateway-ip>Replace <ingress-gateway-ip> with the actual IP address of your ingress gateway.
Access a.aliyun.com:
curl -k -H Host:a.aliyun.com --resolve a.aliyun.com:443:${INGRESS_HOST} https://a.aliyun.com/helloExpected output:
Welcome to aliyun.com!Access b.aliyun.com:
curl -k -H Host:b.aliyun.com --resolve b.aliyun.com:443:${INGRESS_HOST} https://b.aliyun.com/status/418Expected output:
-=[ teapot ]=-
_...._
.' _ _ `.
| ."` ^ `". _,
\_;`"---"`|//
| ;/
\_ _/
`"""`Update a gateway certificate
To rotate the certificate on an ingress gateway, create a new Secret with the updated certificate and update the credentialName in the Gateway resource. The gateway picks up the new certificate automatically -- no restart needed.
The following example creates a new certificate for example.com and updates the gateway.
Create a new certificate
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.crtGenerate a server certificate and private key for
example.com: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.crtObtain the kubeconfig file of the cluster and connect using kubectl. For more information, see Obtain the kubeconfig file of a cluster and use kubectl to connect to the cluster.
Create a new Secret:
kubectl create -n istio-system secret tls new-istio-ingressgateway-certs --key example.com.key --cert example.com.crt
Delete the old Secret
kubectl delete secret istio-ingressgateway-certs -n istio-systemUpdate the Gateway resource
Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.
On the Mesh Management page, click the name of your ASM instance. In the left-side navigation pane, choose ASM Gateways > Gateway.
On the Gateway page, find the target gateway and click YAML in the Actions column.
In the Edit dialog box, change
credentialNametonew-istio-ingressgateway-certs, then click OK.
Verify the certificate update
Dump the Envoy configuration from the ingress gateway pod:
kubectl exec <ingress-gateway-pod> -n istio-system -- curl localhost:15000/config_dump > ingressgateway_dump.yamlReplace
<ingress-gateway-pod>with the actual pod name, such asistio-ingressgateway-xxxx.Search for the new certificate in the dump:
grep new-istio-ingressgateway-certs -A 3 ingressgateway_dump.yamlThe output contains the
new-istio-ingressgateway-certsentry with Base64-encodedinline_bytesvalues.Copy the value of the
inline_bytesfield from the output. This is the Base64-encoded certificate.Decode the certificate and save it to a file:
echo <base64-encoded-certificate> | base64 --decode > test.com.crtReplace
<base64-encoded-certificate>with the actual value from the previous step.Check the certificate issuer:
openssl x509 -in test.com.crt -text -nooutIf the
Organizationfield showsmyexample, the certificate was updated successfully.