All Products
Search
Document Center

Alibaba Cloud Service Mesh:Route gRPC traffic through an ASM ingress gateway

Last Updated:Mar 10, 2026

When your microservices communicate over gRPC, you need a way to expose them to external clients while retaining fine-grained traffic control. An Alibaba Cloud Service Mesh (ASM) ingress gateway accepts inbound gRPC connections at the mesh edge and routes them to backend services based on Istio routing rules. This allows you to implement accurate access control on gRPC services, improve service governance, and ensure the security of service-to-service communication. You can also use weighted traffic splitting between service versions -- useful for canary deployments, A/B testing, and progressive rollouts.

This tutorial walks through deploying two versions of a gRPC service, routing all traffic to version 1, and then shifting a percentage of traffic to version 2.

How it works

Three Istio resources work together to route gRPC traffic from outside the mesh to backend pods:

ResourceRole
GatewayListens on port 8080 with the GRPC protocol and accepts inbound connections at the mesh edge.
DestinationRuleGroups backend pods into subsets (v1, v2) based on version labels and defines the load-balancing policy.
VirtualServiceBinds to the Gateway and forwards matched traffic to a specific subset with a configurable weight.

External gRPC requests reach the ingress gateway on port 8080. The VirtualService then forwards them to the target subset on backend service port 50051.

Prerequisites

Before you begin, make sure you have:

Deploy sample gRPC services

Deploy version 1 and version 2 of a Python-based gRPC hello-world service.

  1. Create a file named app.yaml with the following content:

    View app.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: grpc-helloworld-py-v1
      labels:
        app: grpc-helloworld-py
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: grpc-helloworld-py
          version: v1
      template:
        metadata:
          labels:
            app: grpc-helloworld-py
            version: v1
        spec:
          containers:
            - name: grpc-helloworld-py
              image: registry.cn-hangzhou.aliyuncs.com/aliacs-app-catalog/istio-grpc-server:grpc-helloworld-py-v1.0
              imagePullPolicy: Always
              env:
                - name: podname
                  valueFrom:
                    fieldRef:
                      apiVersion: v1
                      fieldPath: metadata.name
              ports:
                - containerPort: 50051
                  name: grpc-port
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: grpc-helloworld-py-v2
      labels:
        app: grpc-helloworld-py
        version: v2
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: grpc-helloworld-py
          version: v2
      template:
        metadata:
          labels:
            app: grpc-helloworld-py
            version: v2
        spec:
          containers:
            - name: grpc-helloworld-py
              image: registry.cn-hangzhou.aliyuncs.com/aliacs-app-catalog/istio-grpc-server:grpc-helloworld-py-v1.0
              imagePullPolicy: Always
              env:
                - name: podname
                  valueFrom:
                    fieldRef:
                      apiVersion: v1
                      fieldPath: metadata.name
              ports:
                - containerPort: 50051
                  name: grpc-port
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: grpc-helloworld-py
      labels:
        app: grpc-helloworld-py
    spec:
      ports:
        - port: 50051
          name: grpc-port
      selector:
        app: grpc-helloworld-py

    This file defines:

    • Two Deployments (grpc-helloworld-py-v1 and grpc-helloworld-py-v2), each with one replica. Both share the app: grpc-helloworld-py label but differ by the version label.

    • A Service (grpc-helloworld-py) that selects all pods with app: grpc-helloworld-py and exposes port 50051.

  2. Apply the file:

    kubectl apply -f app.yaml

Configure routing rules

Create an Istio Gateway, a DestinationRule, and a VirtualService to route all inbound gRPC traffic to version 1.

  1. Create a file named rules.yaml with the following content:

    apiVersion: networking.istio.io/v1beta1
    kind: Gateway
    metadata:
      name: grpc-gateway
    spec:
      selector:
        istio: ingressgateway
      servers:
      - port:
          number: 8080
          name: grpc
          protocol: GRPC
        hosts:
        - "*"
    ---
    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"
    ---
    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
    ConfigurationDetails
    Gateway port8080, protocol set to GRPC
    DestinationRule subsetsv1 and v2, with ROUND_ROBIN load balancing
    VirtualService weights100% to v1, 0% to v2
  2. Apply the file:

    kubectl apply -f rules.yaml

Set up the ingress gateway port

The ingress gateway must listen on port 8080 to match the Gateway resource. Either create a new ingress gateway or add port 8080 to an existing one.

Option A: Create an ingress gateway

Create an ingress gateway and set Service Port to 8080.

Option B: Add port 8080 to an existing ingress gateway

  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 the ASM instance. In the left-side navigation pane, choose ASM Gateways > Ingress Gateway.

  3. On the Ingress Gateway page, click the name of the target gateway.

  4. In the Basic options section of the Gateway Details page, click the edit icon next to Port.

  5. In the Port Mapping dialog box, click Add Port, set Protocol to TCP, set Service Port to 8080, and then click Submit.

Verify gRPC connectivity

Send a gRPC request through the ingress gateway to confirm that all traffic reaches version 1.

Run the following command:

grpcurl -d '{"name": "Jack"}' -plaintext {IP address of the ingress gateway}:8080 helloworld.Greeter/SayHello

Expected output -- every response identifies a v1 pod:

{
  "message": "Hello, Jack! I'm from grpc-helloworld-py-v1-79b5dc9654-cg4dq!"
}

Run the command several times to confirm that no responses come from v2 pods.

Shift traffic to version 2

After you verify that version 1 works, update the VirtualService to split traffic between versions -- for example, 60% to v1 and 40% to v2.

  1. Edit the VirtualService:

    kubectl edit VirtualService grpc-vs
  2. Update the route section with the following weights and save the file:

    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
  3. Send gRPC requests again to verify the traffic split:

    grpcurl -d '{"name": "Jack"}' -plaintext {IP address of the ingress gateway}:8080 helloworld.Greeter/SayHello

    Run the command multiple times. Responses now come from both v1 and v2 pods:

    "message": "Hello, Jack! I'm from grpc-helloworld-py-v1-79b5dc9654-cg4dq!"
    "message": "Hello, Jack! I'm from grpc-helloworld-py-v2-7f56b49b7f-9vvr7!"
    Note

    Individual requests may not match the exact 60:40 ratio. Over a sufficient number of requests, the distribution converges to the configured weights.

Clean up

Remove the sample resources created in this tutorial:

kubectl delete -f rules.yaml
kubectl delete -f app.yaml