When your applications communicate over gRPC, you need a way to route, load-balance, and split traffic across gRPC service versions at the mesh edge. An Alibaba Cloud Service Mesh (ASM) ingress gateway serves as the entry point for external gRPC traffic into your service mesh, allowing you to implement accurate access control on gRPC services, improve service governance, and ensure the security of service-to-service communication. Because gRPC runs over HTTP/2, the ingress gateway handles gRPC traffic the same way it handles HTTP services -- enabling weighted routing, canary releases, and version-based traffic splitting.
This topic walks through deploying two versions of a gRPC service, configuring Istio routing resources to direct traffic through the ingress gateway, and shifting traffic between the two versions by weight.
How the routing resources work together
Routing gRPC traffic through an ASM ingress gateway requires three Istio resources:
| Resource | Role |
|---|---|
| Gateway | Binds to the ingress gateway pod and opens a port with the GRPC protocol. Handles L4-L6 concerns (port, protocol, TLS). |
| DestinationRule | Defines subsets (v1, v2) based on pod labels and sets the load-balancing policy. |
| VirtualService | Binds to the Gateway and contains the routing logic: which subset receives traffic and at what weight. |
Traffic flows as follows: external client -> Gateway (port 8080, GRPC) -> VirtualService (routing rules) -> DestinationRule (subset selection) -> pods.
Istio treats gRPC the same as HTTP/2 for routing purposes. The VirtualService uses http match rules even though the Gateway declares protocol GRPC.
Prerequisites
Before you begin, make sure that you have:
An ASM instance of the latest version (Enterprise or Ultimate edition)
A Container Service for Kubernetes (ACK) cluster added to the ASM instance, with an application deployed. For more information, see Deploy an application in a cluster that is associated with an ASM instance
An ingress gateway deployed in the ASM instance. For more information, see Create an ingress gateway
Step 1: Deploy two versions of a gRPC service
Deploy version 1 (istio-grpc-server-v1) and version 2 (istio-grpc-server-v2) of the gRPC service to your ACK cluster. Both deployments use the same container image but carry different version labels so that the DestinationRule can distinguish them.
Log on to the ACK console. In the left-side navigation pane, click Clusters.
On the Clusters page, click the name of the target cluster. In the left-side navigation pane, choose Workloads > Deployments.
In the upper part of the Deployments page, select a namespace from the Namespace drop-down list and click Create from YAML.
ImportantThe namespace must have the
istio-injection=enabledlabel so that sidecar proxies are injected automatically. For more information, see Enable automatic sidecar proxy injection.On the Create page, set Sample Template to Custom, paste the following YAML into the editor, and click Create. The YAML creates two Deployments (v1 and v2) and one Service. Both Deployments listen on container port
50051.
Step 2: Configure routing rules for the ASM instance
Create a Gateway, a DestinationRule, and a VirtualService. Together, these resources route all inbound gRPC traffic through the ingress gateway to istio-grpc-server-v1.
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 the target ASM instance or click Manage in the Actions column.
Create a Gateway
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, select a template from the Template drop-down list, paste the following YAML, and click Create. This Gateway listens on port
8080with the GRPC protocol and matches all hosts.apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: grpc-gateway spec: selector: istio: ingressgateway servers: - port: number: 8080 name: grpc protocol: GRPC hosts: - "*"
Create a DestinationRule
In the left-side navigation pane, choose Traffic Management Center > DestinationRule. On the page that appears, click Create from YAML.
Select default from the Namespace drop-down list, select a template from the Template drop-down list, paste the following YAML, and click Create. This DestinationRule defines two subsets (v1 and v2) based on the
versionlabel and uses ROUND_ROBIN load balancing.apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: dr-istio-grpc-server spec: host: grpc-helloworld-py trafficPolicy: loadBalancer: simple: ROUND_ROBIN subsets: - name: v1 labels: version: "v1" - name: v2 labels: version: "v2"
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, select a template from the Template drop-down list, paste the following YAML, and click Create. This VirtualService sends 100% of traffic on port
8080to the v1 subset. The v2 subset receives 0% and serves as a placeholder for later traffic shifting.apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: grpc-vs spec: hosts: - "*" gateways: - grpc-gateway http: - match: - port: 8080 route: - destination: host: grpc-helloworld-py port: number: 50051 subset: v1 weight: 100 - destination: host: grpc-helloworld-py port: number: 50051 subset: v2 weight: 0
Step 3: Open port 8080 on the ingress gateway
The ingress gateway must expose port 8080 so that external gRPC clients can connect. Create a new ingress gateway with port 8080, or add the port to an existing gateway.
Option A: Create an ingress gateway
In the ASM console, navigate to the target ASM instance. In the left-side navigation pane, choose ASM Gateways > Ingress Gateway.
On the Ingress Gateway page, click Create and configure the following parameters. For more information about parameters, see Ingress gateway parameters. Click Create to finish.
NoteEach ingress gateway Service should use its own CLB instance. Sharing a CLB instance across multiple Services can cause the following issues:
Existing listeners may be overwritten, which interrupts other Services.
Only CLB instances created in the CLB console or through API operations can be shared. CLB instances created automatically during Service creation cannot be shared.
Services sharing a CLB instance must use different frontend listening ports.
Listener and vServer group names serve as unique identifiers. Do not rename them.
CLB instances cannot be shared across clusters.
Parameter Value Cluster The ACK cluster in which to deploy the ingress gateway CLB Instance Type Internet Access Create a CLB Instance or Use Existing CLB Instance Choose based on your environment. See the note below for Classic Load Balancer (CLB) sharing considerations Port Mapping Protocol: TCP, Service Port: 8080
Option B: Add port 8080 to an existing ingress gateway
In the ASM console, navigate to the target ASM instance. In the left-side navigation pane, choose ASM Gateways > Ingress Gateway.
Click the name of the target gateway. In the Basic options section of the Gateway Details page, click the edit icon next to Port.
In the Port Mapping dialog box, click Add Port. Set Protocol to TCP, set Service Port to
8080, and click Submit.
Step 4: Verify the setup with a gRPC client
gRPCurl is a command-line tool that you can use to interact with gRPC services. It allows you to test and debug a gRPC service, as well as view the definition and metadata of the service. To download and install gRPCurl, visit github.com/fullstorydev/grpcurl.
Run the following command to send a gRPC request through the ingress gateway:
grpcurl -d '{"name": "Jack"}' -plaintext {IP address of the ingress gateway}:8080 helloworld.Greeter/SayHelloVerify the output. All responses should come from istio-grpc-server-v1: Run the command several times to confirm that every response identifies an istio-grpc-server-v1 pod.
"message": "Hello, Jack! I'm from grpc-helloworld-py-v1-79b5dc9654-cg4dq!" "message": "Hello, Jack! I'm from grpc-helloworld-py-v1-79b5dc9654-cg4dq!" "message": "Hello, Jack! I'm from grpc-helloworld-py-v1-79b5dc9654-cg4dq!" "message": "Hello, Jack! I'm from grpc-helloworld-py-v1-79b5dc9654-cg4dq!" "message": "Hello, Jack! I'm from grpc-helloworld-py-v1-79b5dc9654-cg4dq!"
Step 5: Route traffic to the two versions of the gRPC service based on a specific ratio
Route 40% of the traffic to istio-grpc-server-v2 and 60% of the traffic to istio-grpc-server-v1. With both versions running and all traffic initially directed to v1, you can shift traffic to v2 using weighted routing.
Update the VirtualService weights
In the ASM console, navigate to the target ASM instance. In the left-side navigation pane, choose Traffic Management Center > VirtualService.
On the VirtualService page, find grpc-vs and click YAML in the Actions column.
In the Edit dialog box, update the
weightvalues in theroutesection. The following example sends 60% of traffic to v1 and 40% to v2: Click OK to apply the change.route: - destination: host: grpc-helloworld-py port: number: 50051 subset: v1 weight: 60 - destination: host: grpc-helloworld-py port: number: 50051 subset: v2 weight: 40
Verify the traffic split
Send multiple gRPC requests:
grpcurl -d '{"name": "Jack"}' -plaintext {IP address of the ingress gateway}:8080 helloworld.Greeter/SayHelloCheck the output. Responses should come from both istio-grpc-server-v1 and istio-grpc-server-v2 pods at approximately the configured ratio:
NoteIndividual request batches may not reflect an exact 60:40 ratio. Over a larger sample, the distribution converges to the configured weights.
"message": "Hello, Jack! I'm from grpc-helloworld-py-v1-79b5dc9654-cg4dq!" "message": "Hello, Jack! I'm from grpc-helloworld-py-v1-79b5dc9654-cg4dq!" "message": "Hello, Jack! I'm from grpc-helloworld-py-v2-7f56b49b7f-9vvr7!" "message": "Hello, Jack! I'm from grpc-helloworld-py-v1-79b5dc9654-cg4dq!" "message": "Hello, Jack! I'm from grpc-helloworld-py-v2-7f56b49b7f-9vvr7!" "message": "Hello, Jack! I'm from grpc-helloworld-py-v1-79b5dc9654-cg4dq!" "message": "Hello, Jack! I'm from grpc-helloworld-py-v2-7f56b49b7f-9vvr7!" "message": "Hello, Jack! I'm from grpc-helloworld-py-v1-79b5dc9654-cg4dq!" "message": "Hello, Jack! I'm from grpc-helloworld-py-v2-7f56b49b7f-9vvr7!" "message": "Hello, Jack! I'm from grpc-helloworld-py-v1-79b5dc9654-cg4dq!"