All Products
Search
Document Center

Alibaba Cloud Service Mesh:Use service discovery selectors to reduce control plane push overhead

Last Updated:Mar 10, 2026

By default, the Alibaba Cloud Service Mesh (ASM) control plane monitors services across every namespace in a cluster and pushes configuration changes to all sidecar proxies on the data plane -- even for namespaces without sidecar proxy injection. In large clusters with many namespaces, this creates unnecessary load on the control plane and slows configuration synchronization.

Service discovery selectors filter which namespaces the control plane watches. After you configure a selector, the control plane discovers and processes only services in namespaces that match the selector's label criteria. Sidecar proxies receive a smaller, targeted configuration set, which accelerates push times and reduces resource consumption.

Note In this topic, *sidecar proxy configurations* refers to the configurations that a sidecar proxy receives from the ASM control plane.

How it works

Without a service discovery selector, every sidecar proxy stores the configuration of all services across all namespaces, including those the proxy never communicates with. When any service changes in any namespace, the control plane triggers a full push to every sidecar proxy.

With a service discovery selector, the control plane only watches namespaces whose labels match the selector criteria. Service changes in unmatched namespaces are ignored, and sidecar proxies store only the configurations they need.

Label selector matching rules

Label selectors support two matching modes:

Exact match

Specify a label key and value. A namespace is selected only when both the key and value match exactly.

Expression-based match

Specify a label key, an operator, and optionally a set of values:

OperatorBehaviorExample use case
InSelects namespaces where the label value is in the specified setInclude only production and staging namespaces
NotInSelects namespaces where the label value is not in the specified setExclude kube-system and monitoring namespaces
ExistsSelects namespaces where the label key exists, regardless of valueSelect all namespaces labeled with asm-discovery
DoesNotExistSelects namespaces where the label key does not existExclude namespaces without explicit mesh opt-in

Configure a service discovery selector

To configure a selector, your ASM instance must meet these requirements:

Choose one of the following methods.

Method 1: Select namespaces in the console

  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 Instance > Service Discovery Selectors.

  3. Set Mesh Discovery Mode to Automatically Discover Services in the Selected Namespace of a Kubernetes Cluster on the Data Plane.

  4. On the Select Namespaces tab, select the cluster, then click unselect next to every namespace that should be excluded from discovery. Keep only the namespaces whose services need to be pushed to sidecar proxies. Click OK, then click OK in the Submit dialog.

  5. Verify the configuration:

    1. In the left-side navigation pane, choose ASM Instance > Base Information.

    2. Confirm that Status shows Running.

Method 2: Use a label selector expression

This method is better for environments managed through infrastructure as code. Label each namespace that should be included, then define a label selector in the console.

  1. Label each target namespace:

    kubectl label namespace <namespace-name> asm-discovery=enabled
  2. Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.

  3. On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose ASM Instance > Service Discovery Selectors.

  4. Set Mesh Discovery Mode to Automatically Discover Services in the Selected Namespace of a Kubernetes Cluster on the Data Plane, then click Edit Discovery Selectors Directly.

  5. Define the label selector. For example, to select all namespaces that carry the asm-discovery label regardless of value, set Key to asm-discovery and Operator to Exists. Click OK, then click OK in the Submit dialog.

  6. Verify the configuration:

    1. In the left-side navigation pane, choose ASM Instance > Base Information.

    2. Confirm that Status shows Running.

Verify that the selector takes effect

After configuring the selector, confirm that sidecar proxies no longer receive configurations from excluded namespaces.

Check the sidecar proxy configuration

  1. Get the pod name of a workload in a selected namespace:

    kubectl get pods -n <selected-namespace>
    NAME                       READY   STATUS    RESTARTS   AGE
    httpbin-6fcb98998c-46qhr   2/2     Running   0          22m
  2. Dump the sidecar proxy configuration:

    kubectl exec -it <pod-name> -c istio-proxy -n <selected-namespace> -- curl -s localhost:15000/config_dump > config_dump.json
  3. Search the config_dump.json file for a service in an excluded namespace. For example, search for httpbin.ns-not-in-mesh. If no match is found, the selector is working correctly -- sidecar proxies no longer store configurations from that namespace.

Check control plane logs

Trigger a service change in an excluded namespace (for example, create or delete a deployment), then verify that no corresponding push logs appear in the control plane logs.

For ASM instances earlier than 1.17.2.35

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

  2. On the Mesh Management page, find the ASM instance and click its name or click Manage in the Actions column.

  3. In the left-side navigation pane, choose ASM Instance > Base Information.

  4. Click View log next to Control-plane log collection.

  5. Set Time Range to 15 Minutes and check the Raw Logs tab. If no push logs appear for the excluded namespace, the selector is working correctly.

For ASM instances 1.17.2.35 or later

  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 Observability Management Center > Log Center.

  3. Click the Control-Plane Logs tab and set Time Range to 15 Minutes. If no push logs appear on the Raw Logs tab for the excluded namespace, the selector is working correctly.

Exclude specific pods from service discovery

Note This feature requires ASM version 1.20 or later.

By default, ASM discovers all services and pods in a data-plane Kubernetes cluster. With pod-level label selectors, you can exclude specific pods from ASM service discovery entirely. The control plane does not discover excluded pods, and no sidecar proxy routes traffic to them. This is useful for quickly draining traffic from a specific pod.

  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 Instance > Service Discovery Selectors.

  3. Click Show Advanced Settings, then click Logs with specific labels are not selected. Enter the Key and Value of the label to exclude matching pods from ASM service discovery. Common use cases:

    • Exclude pods in a specific region: use topology.kubernetes.io/region as the key.

    • Exclude pods in a specific zone: use topology.kubernetes.io/zone as the key.

  4. Click Ok, then click Ok in the confirmation dialog.

Walkthrough: set up and test a service discovery selector

This walkthrough demonstrates the end-to-end process using two namespaces: one inside the mesh (ns-in-mesh) and one outside (ns-not-in-mesh).

Step 1: Create namespaces

  1. Create two namespaces: ns-in-mesh and ns-not-in-mesh. For more information, see Create a namespace.

  2. Enable automatic sidecar proxy injection for the ns-in-mesh namespace. For more information, see Enable automatic sidecar proxy injection.

  3. Add the asm-discovery=enabled label to the ns-in-mesh namespace:

    kubectl label namespace ns-in-mesh asm-discovery=enabled

Step 2: Deploy a sample application

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

    Show the httpbin.yaml file

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: httpbin
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: httpbin
      labels:
        app: httpbin
        service: httpbin
    spec:
      ports:
      - name: http
        port: 8000
        targetPort: 80
      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:
          serviceAccountName: httpbin
          containers:
          - image: docker.io/kennethreitz/httpbin
            imagePullPolicy: IfNotPresent
            name: httpbin
            ports:
            - containerPort: 80
  2. Deploy the HTTPBin application in both namespaces:

    kubectl apply -f httpbin.yaml -n ns-in-mesh
    kubectl apply -f httpbin.yaml -n ns-not-in-mesh

Step 3: Observe default push behavior

Before configuring a selector, verify that sidecar proxies receive configurations from all namespaces, including ns-not-in-mesh.

  1. Get the pod name:

    kubectl get pods -n ns-in-mesh

    Example output:

    NAME                       READY   STATUS    RESTARTS   AGE
    httpbin-6fcb98998c-46qhr   2/2     Running   0          22m
  2. Dump the sidecar proxy configuration:

    Replace httpbin-6fcb98998c-46qhr with the actual pod name from the previous step.

    kubectl exec -it httpbin-6fcb98998c-46qhr -c istio-proxy -n ns-in-mesh -- curl -s localhost:15000/config_dump > config_dump.json
  3. Search for httpbin.ns-not-in-mesh in config_dump.json. If found, this confirms that sidecar proxies store service configurations from ns-not-in-mesh even though automatic sidecar proxy injection is not enabled for that namespace.

  4. (Optional) Verify through control plane logs:

    1. Enable control plane log collection. For ASM versions earlier than 1.17.2.35, see Enable control-plane log collection and log-based alerting. For ASM versions 1.17.2.35 or later, see Use Log Center.

    2. Deploy the sleep application in the ns-not-in-mesh namespace to trigger a push event:

      Show the sleep.yaml file

      apiVersion: v1
      kind: Service
      metadata:
        name: sleep
        labels:
          app: sleep
      spec:
        ports:
        - port: 80
          name: http
        selector:
          app: sleep
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: sleep
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: sleep
        template:
          metadata:
            labels:
              app: sleep
          spec:
            containers:
            - name: sleep
              image: pstauffer/curl
              command: ["/bin/sleep", "3650d"]
              imagePullPolicy: IfNotPresent
      kubectl apply -f sleep.yaml -n ns-not-in-mesh
    3. Open the control plane logs (set Time Range to 5 Minutes). Log entries similar to the following confirm that the control plane pushes configurations for the ns-not-in-mesh namespace:

      Full push, new service ns-not-in-mesh/sleep.ns-not-in-mesh.svc.cluster.local

Step 4: Apply the service discovery selector

Follow the steps in Configure a service discovery selector to configure a selector that includes only the ns-in-mesh namespace.

Step 5: Confirm the selector works

  1. Dump the sidecar proxy configuration again:

    kubectl exec -it <pod-name> -c istio-proxy -n ns-in-mesh -- curl -s localhost:15000/config_dump > config_dump.json

    Search for httpbin.ns-not-in-mesh. If no match is found, sidecar proxies no longer store configurations from the excluded namespace.

  2. Delete the sleep application from ns-not-in-mesh to trigger a service change:

    kubectl delete -f sleep.yaml -n ns-not-in-mesh

    Check the control plane logs (set Time Range to 15 Minutes). If no push logs appear for the ns-not-in-mesh namespace, the selector is working as expected. The control plane ignores service changes in namespaces that fall outside the selector criteria.