Tous les produits
Search
Centre de documentation

Alibaba Cloud Service Mesh:Enable zone-aware routing

Dernière mise à jour :Aug 11, 2026

Le trafic interzones engendre une latence accrue et des coûts de transfert de données supplémentaires. Le routage tenant compte des zones maintient les requêtes au sein de la même zone de disponibilité tant que des endpoints sains y sont disponibles, ce qui réduit ces deux impacts. Lorsque les endpoints de la même zone ne sont plus accessibles, le trafic bascule automatiquement vers la zone la plus proche suivante.

Service Mesh (ASM) prend en charge le routage tenant compte des zones (également appelé routage intra-zone) via l'équilibrage de charge par localité d'Istio. Aucune modification du code de l'application n'est nécessaire. Cette rubrique explique comment activer le routage tenant compte des zones pour un exemple de service déployé sur deux zones. Dans l'exemple suivant, une passerelle d'entrée est utilisée pour permettre l'accès à une application HTTPBin.

Fonctionnement

Lorsqu'un client initie une requête pour accéder à un service, celle-ci est acheminée vers le service situé sur le même nœud ou dans la même zone que le client, en fonction des informations topologiques concernant la région et la zone où réside le client. Chaque endpoint hérite de la région, de la zone et de la sous-zone de son nœud. Lorsque vous activez l'équilibrage de charge par localité via une DestinationRule, le proxy sidecar attribue des niveaux de priorité aux endpoints :

Priorité Signification
0 Même zone que l'appelant (priorité la plus élevée)
1 Zone différente, même région

Le trafic est d'abord dirigé vers les endpoints de priorité 0. Si ceux-ci deviennent indisponibles (détectés via la détection d'anomalies), le proxy effectue un basculement vers le niveau de priorité suivant.

Prérequis

Avant de commencer, assurez-vous d'avoir :

Étape 1 : Déployer les exemples d'applications

Cette procédure utilise deux applications :

  • sleep -- un client basé sur curl, déployé dans cn-hongkong-b

  • helloworld -- le service cible, avec v1 dans cn-hongkong-b et v2 dans cn-hongkong-c

Remarque

Remplacez cn-hongkong-b et cn-hongkong-c par les zones où résident les nœuds de votre cluster.

Déployer le client sleep

  1. Créez le fichier sleep.yaml :

    Afficher sleep.yaml

    # Copyright Istio Authors
    #
    #   Licensed under the Apache License, Version 2.0 (the "License");
    #   you may not use this file except in compliance with the License.
    #   You may obtain a copy of the License at
    #
    #       http://www.apache.org/licenses/LICENSE-2.0
    #
    #   Unless required by applicable law or agreed to in writing, software
    #   distributed under the License is distributed on an "AS IS" BASIS,
    #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    #   See the License for the specific language governing permissions and
    #   limitations under the License.
    
    ##################################################################################################
    # Sleep service
    ##################################################################################################
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: sleep
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: sleep
      labels:
        app: sleep
        service: 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:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: failure-domain.beta.kubernetes.io/zone
                    operator: In
                    values:
                      - 'cn-hongkong-b'
          terminationGracePeriodSeconds: 0
          serviceAccountName: sleep
          containers:
          - name: sleep
            image: curlimages/curl
            command: ["/bin/sleep", "3650d"]
            imagePullPolicy: IfNotPresent
            volumeMounts:
            - mountPath: /etc/sleep/tls
              name: secret-volume
          volumes:
          - name: secret-volume
            secret:
              secretName: sleep-secret
              optional: true
  2. Appliquez le manifeste :

    kubectl apply -f sleep.yaml

Déployer le service helloworld

  1. Créez le fichier helloworld.yaml :

    Afficher helloworld.yaml

    apiVersion: v1
    kind: Service
    metadata:
      name: helloworld
      labels:
        app: helloworld
        service: helloworld
    spec:
      ports:
      - port: 5000
        name: http
      selector:
        app: helloworld
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: helloworld-v1
      labels:
        app: helloworld
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: helloworld
          version: v1
      template:
        metadata:
          labels:
            app: helloworld
            version: v1
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: failure-domain.beta.kubernetes.io/zone
                    operator: In
                    values:
                      - 'cn-hongkong-b'
          containers:
          - name: helloworld
            image: docker.io/istio/examples-helloworld-v1
            resources:
              requests:
                cpu: "100m"
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 5000
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: helloworld-v2
      labels:
        app: helloworld
        version: v2
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: helloworld
          version: v2
      template:
        metadata:
          labels:
            app: helloworld
            version: v2
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: failure-domain.beta.kubernetes.io/zone
                    operator: In
                    values:
                      - 'cn-hongkong-c'
          containers:
          - name: helloworld
            image: docker.io/istio/examples-helloworld-v2
            resources:
              requests:
                cpu: "100m"
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 5000
  2. Appliquez le manifeste :

    kubectl apply -f helloworld.yaml

Vérifier l'enregistrement des endpoints

Interrogez les informations du cluster Envoy depuis le pod sleep pour confirmer que les deux endpoints helloworld sont enregistrés avec les métadonnées de zone :

kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" \
  -c sleep -- curl -s localhost:15000/clusters | grep helloworld

Dans la sortie, recherchez les champs zone et priority. Avant l'activation du routage tenant compte des zones, les deux endpoints partagent la même priorité (priority::0) :

outbound|5000||helloworld.default.svc.cluster.local::172.28.32.49:5000::zone::cn-hongkong-b
outbound|5000||helloworld.default.svc.cluster.local::172.28.32.49:5000::priority::0
...
outbound|5000||helloworld.default.svc.cluster.local::172.28.33.155:5000::zone::cn-hongkong-c
outbound|5000||helloworld.default.svc.cluster.local::172.28.33.155:5000::priority::0

Des priorités égales signifient que le proxy distribue le trafic entre les deux endpoints sans préférence de zone.

Étape 2 : Activer le routage tenant compte des zones avec une DestinationRule

Créez une DestinationRule qui active l'équilibrage de charge par localité et configure la détection d'anomalies pour le service helloworld. La détection d'anomalies est requise pour le basculement ; sans elle, le proxy ne peut pas détecter les endpoints indisponibles ni rediriger le trafic vers une autre zone.

  1. Créez le fichier helloworld-failover.yaml : Champs clés :

    Champ Objectif
    localityLbSetting.enabled Active le routage tenant compte des zones
    outlierDetection Détecte les endpoints indisponibles et déclenche le basculement vers la zone suivante
    consecutive5xxErrors: 1 Exclut un endpoint après une seule erreur 5xx (agressif, uniquement pour la démonstration)
    baseEjectionTime: 1m Maintient les endpoints exclus hors circuit pendant 1 minute
    interval: 1s Vérifie l'état de santé de l'endpoint chaque seconde
    maxRequestsPerConnection: 1 Force une nouvelle connexion par requête (uniquement pour la démonstration)
    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: helloworld-failover
      namespace: default
    spec:
      host: helloworld.default.svc.cluster.local
      trafficPolicy:
        connectionPool:
          http:
            maxRequestsPerConnection: 1
        loadBalancer:
          localityLbSetting:
            enabled: true
          simple: ROUND_ROBIN
        outlierDetection:
          baseEjectionTime: 1m
          consecutive5xxErrors: 1
          interval: 1s
  2. Appliquez la DestinationRule :

    kubectl apply -f helloworld-failover.yaml
  3. Vérifiez que les priorités des endpoints ont changé : L'endpoint de la même zone (cn-hongkong-b) possède désormais la priorité priority::0, tandis que l'endpoint interzones (cn-hongkong-c) a la priorité priority::1 : Des priorités différentes confirment que le routage tenant compte des zones est actif. Le proxy envoie tout le trafic d'abord vers l'endpoint de priorité 0 (même zone).

    kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" \
      -c sleep -- curl -s localhost:15000/clusters | grep helloworld
    outbound|5000||helloworld.default.svc.cluster.local::172.28.32.49:5000::zone::cn-hongkong-b
    outbound|5000||helloworld.default.svc.cluster.local::172.28.32.49:5000::priority::0
    ...
    outbound|5000||helloworld.default.svc.cluster.local::172.28.33.155:5000::zone::cn-hongkong-c
    outbound|5000||helloworld.default.svc.cluster.local::172.28.33.155:5000::priority::1

Étape 3 : Vérifier le comportement du routage

Avec le routage tenant compte des zones activé, toutes les requêtes provenant du pod sleep (cn-hongkong-b) sont acheminées vers helloworld-v1 dans la même zone. Les étapes suivantes confirment ce comportement et testent le basculement lorsque l'endpoint de la même zone devient indisponible.

Confirmer le routage intra-zone

Exécutez la commande suivante plusieurs fois :

kubectl exec -c sleep \
  "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" \
  -- curl -sSL helloworld:5000/hello

Sortie attendue :

Hello version: v1, instance: helloworld-v1-6f88967849-sq2h2

Chaque réponse provient de v1 (l'endpoint de la même zone dans cn-hongkong-b).

Tester le basculement interzones

  1. Mettez à l'échelle helloworld-v1 à zéro réplica pour simuler une panne dans cn-hongkong-b :

    kubectl scale deploy helloworld-v1 --replicas=0
  2. Attendez quelques secondes, puis envoyez à nouveau des requêtes : Sortie attendue : Le trafic est maintenant acheminé vers v2 dans cn-hongkong-c, ce qui confirme que le basculement interzones fonctionne lorsque les endpoints de la même zone sont indisponibles.

    kubectl exec -c sleep \
      "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" \
      -- curl -sSL helloworld:5000/hello
    Hello version: v2, instance: helloworld-v2-75db5f978d-s7v4k

Restaurer l'endpoint de la même zone

  1. Rétablissez helloworld-v1 à un réplica :

    kubectl scale deploy helloworld-v1 --replicas=1
  2. Attendez quelques secondes, puis vérifiez que le trafic revient vers v1 : Sortie attendue : Le trafic est de nouveau acheminé vers l'endpoint de la même zone après sa récupération.

    kubectl exec -c sleep \
      "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" \
      -- curl -sSL helloworld:5000/hello
    Hello version: v1, instance: helloworld-v1-6f88967849-sq2h2