Real-time applications such as live dashboards, chat systems, and collaborative editors require persistent, full-duplex connections between clients and servers. Standard HTTP request-response cycles cannot deliver this. WebSocket solves this by upgrading an HTTP connection to a persistent, bidirectional channel over a single TCP connection. Alibaba Cloud Service Mesh (ASM) natively supports WebSocket -- because WebSocket connections start as HTTP upgrade requests, an ingress gateway configured with the HTTP protocol handles WebSocket traffic without any extra protocol settings.
This topic walks through deploying a sample WebSocket application, routing traffic through the ingress gateway, and optionally enabling WebSocket Secure (wss) with TLS.
Prerequisites
Before you begin, make sure that you have:
kubectl configured to connect to your Container Service for Kubernetes (ACK) cluster. For more information, see Obtain the kubeconfig file of a cluster and use kubectl to connect to the cluster
Step 1: Deploy the sample WebSocket application
Run the following command to deploy a Tornado-based WebSocket service in your ACK cluster:
kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
name: tornado
labels:
app: tornado
service: tornado
spec:
ports:
- port: 8888
name: http # Tells Istio to treat traffic as HTTP and handle WebSocket upgrades
selector:
app: tornado
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tornado
spec:
replicas: 1
selector:
matchLabels:
app: tornado
version: v1
template:
metadata:
labels:
app: tornado
version: v1
spec:
containers:
- name: tornado
image: registry.cn-beijing.aliyuncs.com/aliacs-app-catalog/tornado:lastest
imagePullPolicy: Always
ports:
- containerPort: 8888
EOFThis creates a Deployment and a Service, both named tornado. The Service listens on port 8888 with the port name http, which tells Istio to treat traffic as HTTP and automatically handle WebSocket upgrades.
Step 2: Create a gateway and VirtualService
Create an Istio gateway
Log on to the ASM console.
In the left-side navigation pane, choose Service Mesh > Mesh Management.
On the Mesh Management page, find the target ASM instance and click its name or click Manage in the Actions column.
In the left-side navigation pane, choose ASM Gateways > Gateway. On the page that appears, click Create from YAML.
Select default from the Namespace drop-down list, paste the following YAML, and click Create.
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: tornado-gateway
spec:
# Matches the default ingress gateway installed by ASM
selector:
istio: ingressgateway
servers:
- port:
number: 80 # Accepts HTTP and WebSocket traffic on port 80
name: http
protocol: HTTP
hosts:
- "*" # Accepts requests from all hostsSetting port 80 allows the WebSocket service to receive inbound or outbound HTTP and TCP traffic over port 80.
Create a VirtualService
In the left-side navigation pane, choose Traffic Management Center > VirtualService. On the page that appears, click Create from YAML.
Select default from the Namespace drop-down list, paste the following YAML, and click Create.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: tornado
spec:
hosts:
- "*"
gateways:
- tornado-gateway
http:
- match:
- uri:
prefix: /
route:
- destination:
host: tornado # Routes all traffic to the tornado Service
weight: 100Step 3: Get the ingress gateway IP address
Retrieve the external IP address of the ingress gateway using either method below.
Option A: ASM console
Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.
Click the name of the ASM instance. In the left-side navigation pane, choose ASM Gateways > Ingress Gateway.
On the Ingress Gateway page, copy the Service address.
Option B: ACK console
Log on to the ACK console. In the left-side navigation pane, click Clusters.
On the Clusters page, click the cluster name. In the left-side navigation pane, choose Network > Services.
On the Services page, select istio-system from the Namespace drop-down list. In the External IP column, find the IP address for the istio-ingressgateway service on port 80.
Set the environment variable
After you get the IP address, export it as an environment variable so that later commands work without manual substitution:
export INGRESS_IP=<your-ingress-gateway-ip>Replace <your-ingress-gateway-ip> with the actual IP address.
Step 4: Verify WebSocket connectivity
Open
http://$INGRESS_IPin four separate browser windows. Each browser establishes a WebSocket connection to the Tornado service.
Send data through the API to verify real-time synchronization across all connected clients:
curl "http://${INGRESS_IP}/api?id=8&value=300" curl "http://${INGRESS_IP}/api?id=5&value=600" curl "http://${INGRESS_IP}/api?id=1&value=200" curl "http://${INGRESS_IP}/api?id=3&value=290"All four browsers update simultaneously with the same data, confirming that the WebSocket service works correctly through the ingress gateway.
Step 5 (optional): Enable WebSocket Secure (wss) with TLS
To encrypt WebSocket traffic with TLS, add an HTTPS listener to the Gateway.
Prepare the TLS certificate
Create a server certificate and private key for the ingress gateway. For detailed instructions, see Prepare server certificates and private keys for multiple servers.
Create a Kubernetes Secret named
myexample-credentialin theistio-systemnamespace of your ACK cluster. The Secret must contain the server certificate and private key.
Update the gateway
Modify the Gateway created in Step 2 to add an HTTPS server block on port 443:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: tornado-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
- port:
number: 443 # HTTPS port for wss connections
name: https
protocol: HTTPS
tls:
mode: SIMPLE # One-way TLS
credentialName: myexample-credential # Must match the Secret name
hosts:
- "*"The credentialName field references the Secret that contains your TLS certificate. The value must match the Secret name exactly.
Step 6: Verify wss connectivity
Configure the hosts file on your local machine to resolve the domain name in your certificate (for example,
a.aliyun.com) to the ingress gateway IP address. This makes sure that the certificate's common name matches the request hostname.Open
https://a.aliyun.comin four separate browser windows.
Send data through the API over HTTPS:
curl -k "https://${INGRESS_IP}/api?id=8&value=300" curl -k "https://${INGRESS_IP}/api?id=5&value=600" curl -k "https://${INGRESS_IP}/api?id=1&value=200" curl -k "https://${INGRESS_IP}/api?id=3&value=290"Note: The
-kflag skips certificate verification because the certificate is self-signed. Do not use-kin production.All four browsers update simultaneously, confirming that the wss connection works correctly.
Clean up
If you deployed these resources for testing, delete them to avoid unnecessary resource usage:
kubectl delete gateway tornado-gateway
kubectl delete virtualservice tornado
kubectl delete service tornado
kubectl delete deployment tornado