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 :
Un cluster ACK ajouté à votre instance ASM. Pour plus d'informations, consultez Ajouter un cluster à une instance ASM
Des nœuds de cluster répartis sur au moins deux zones de disponibilité. Pour vérifier, consultez la zone de chaque instance Elastic Compute Service (ECS) dans la Container Service Management Console. Pour plus d'informations, voir Régions et zones
É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-bhelloworld -- le service cible, avec v1 dans
cn-hongkong-bet v2 danscn-hongkong-c
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
-
Créez le fichier
sleep.yaml: -
Appliquez le manifeste :
kubectl apply -f sleep.yaml
Déployer le service helloworld
-
Créez le fichier
helloworld.yaml: -
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.
-
Créez le fichier
helloworld-failover.yaml: Champs clés :Champ Objectif localityLbSetting.enabledActive le routage tenant compte des zones outlierDetectionDétecte les endpoints indisponibles et déclenche le basculement vers la zone suivante consecutive5xxErrors: 1Exclut un endpoint après une seule erreur 5xx (agressif, uniquement pour la démonstration) baseEjectionTime: 1mMaintient les endpoints exclus hors circuit pendant 1 minute interval: 1sVérifie l'état de santé de l'endpoint chaque seconde maxRequestsPerConnection: 1Force 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 -
Appliquez la DestinationRule :
kubectl apply -f helloworld-failover.yaml -
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 helloworldoutbound|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
-
Mettez à l'échelle helloworld-v1 à zéro réplica pour simuler une panne dans
cn-hongkong-b:kubectl scale deploy helloworld-v1 --replicas=0 -
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/helloHello version: v2, instance: helloworld-v2-75db5f978d-s7v4k
Restaurer l'endpoint de la même zone
-
Rétablissez helloworld-v1 à un réplica :
kubectl scale deploy helloworld-v1 --replicas=1 -
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/helloHello version: v1, instance: helloworld-v1-6f88967849-sq2h2