Tous les produits
Search
Centre de documentation

Alibaba Cloud Service Mesh:Use traffic labels to implement an end-to-end canary release

Dernière mise à jour :Sep 29, 2026

Les déploiements canaris classiques répartissent le trafic vers différentes versions d'un même service selon des ratios de pondération. Cette approche fonctionne pour des services isolés, mais montre ses limites lorsqu'une requête traverse plusieurs services au sein d'une chaîne d'appels. Par exemple, si le trafic canari atteint le service A puis est acheminé de manière aléatoire vers la version de base du service B, les résultats des tests perdent toute fiabilité.

Le déploiement canari de bout en bout résout ce problème en marquant le trafic entrant au niveau de la passerelle, puis en propageant cette marque sur l'ensemble de la chaîne d'appels. Chaque service lit la marque et dirige la requête vers la version correspondante. Ainsi, le trafic canari emprunte exclusivement les versions canaris, tandis que le trafic de base reste sur les versions de base.

Service Mesh (ASM) s'appuie sur deux fonctionnalités pour mettre en œuvre ce mécanisme :

  • Marquage du trafic : une CustomResourceDefinition (CRD) TrafficLabel qui extrait les libellés des en-têtes de requête et les associe aux flux de trafic.

  • Routage basé sur les libellés : des règles VirtualService qui orientent le trafic vers les sous-ensembles correspondant à la valeur du libellé.

Fonctionnement

Le schéma suivant illustre la chaîne d'appels utilisée dans ce tutoriel. Le service A (mocka) reçoit le trafic entrant et appelle le service B (mockb) :

Application service call chain

Ces deux services sont déployés en deux versions : base et canary. Sans libellés de trafic, les requêtes sont réparties entre les versions par un équilibrage de charge de type round-robin.

Une fois les libellés de trafic configurés, le système procède comme suit :

  1. Il lit l'en-tête my-asm-prefer-tag des requêtes entrantes au niveau de la passerelle afin de classer le trafic comme version-base ou version-canary.

  2. Il achemine ensuite la requête vers la version correspondante du service A.

  3. Enfin, il propage la marque vers le service B via l'en-tête my-trace-id, ce qui permet au service B de router lui aussi la requête vers la bonne version.

Remarque

Vos applications doivent propager l'en-tête HTTP tout au long de la chaîne d'appels. Les services d'exemple de ce tutoriel intègrent déjà cette logique. Pour vos propres applications, implémentez la propagation de l'en-tête utilisé pour le marquage du trafic. Consultez le fichier src/mock-abc/go/main.go du code source d'exemple pour découvrir une implémentation de référence.

Prérequis

Avant de commencer, vérifiez que vous disposez des éléments suivants :

Instructions

  1. Lisez attentivement la documentation anglaise afin de comprendre précisément les informations à transmettre.

  2. Rédigez la version française intégralement depuis zéro, sans conserver la structure des phrases anglaises.

  3. Conservez à l'identique toute la mise en forme Markdown, les blocs de code, les liens et les images.

  4. Pour les balises xref (<a data-tag="xref" ...>texte</a>), conservez la balise entière avec tous ses attributs, dans leur ordre et leur casse d'origine ; traduisez uniquement le texte visible entre > et .

  5. Appliquez rigoureusement l'ensemble des règles linguistiques spécifiques.

  6. Respectez les règles relatives aux stopwords avec une tolérance zéro.

  7. Utilisez le mode impératif dans les étapes numérotées et les listes à puces procédurales.

  8. Garantissez la cohérence terminologique : un même terme doit toujours être traduit de la même manière.

  9. Variez les formulations d'introduction dans les listes et les tableaux afin qu'aucune ne se répète plus de trois fois.

  10. Retournez uniquement le document Markdown en français, sans aucune explication.

    Fichiers de configuration d'exemple

    Téléchargez les fichiers de configuration d'exemple utilisés dans ce tutoriel. L'archive contient les fichiers suivants :

    Fichier Objectif
    application-base.yaml Déploie les versions de base du service A (mocka) et du service B (mockb)
    application-canary.yaml Déploie les versions canary des deux services
    routing.yaml Définit la Gateway, les DestinationRules et les VirtualServices pour le routage initial
    trafficlabel.yaml Configure les CRD TrafficLabel pour l'étiquetage du trafic
    vs-tf-mockb.yaml Applique un routage basé sur les libellés au service B
    vs-tf-mocka.yaml Applique un routage basé sur les libellés au service A au niveau de la passerelle
    vs-tf-mocka-90-10.yaml Ajoute une répartition pondérée (90 % vers la version de base, 10 % selon les libellés) au service A

    application-base.yaml -- Déploiements des versions de base

    apiVersion: v1
    kind: Service
    metadata:
      name: mocka
      labels:
        app: mocka
        service: mocka
    spec:
      ports:
      - port: 8000
        name: http
      selector:
        app: mocka
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mocka-base
      labels:
        app: mocka
        version: base
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mocka
          version: base
      template:
        metadata:
          labels:
            app: mocka
            version: base
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/go-http-sample:tracing
            imagePullPolicy: Always
            env:
            - name: version
              value: base
            - name: app
              value: mocka
            - name: upstream_url
              value: "http://mockb:8000/"
            ports:
            - containerPort: 8000
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: mockb
      labels:
        app: mockb
        service: mockb
    spec:
      ports:
      - port: 8000
        name: http
      selector:
        app: mockb
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mockb-base
      labels:
        app: mockb
        version: base
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mockb
          version: base
      template:
        metadata:
          labels:
            app: mockb
            version: base
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/go-http-sample:tracing
            imagePullPolicy: Always
            env:
            - name: version
              value: base
            - name: app
              value: mockb
            ports:
            - containerPort: 8000

    application-canary.yaml -- Déploiements des versions canary

    apiVersion: v1
    kind: Service
    metadata:
      name: mocka
      labels:
        app: mocka
        service: mocka
    spec:
      ports:
      - port: 8000
        name: http
      selector:
        app: mocka
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mocka-canary
      labels:
        app: mocka
        version: canary
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mocka
          version: canary
      template:
        metadata:
          labels:
            app: mocka
            version: canary
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/go-http-sample:tracing
            imagePullPolicy: Always
            env:
            - name: version
              value: canary
            - name: app
              value: mocka
            - name: upstream_url
              value: "http://mockb:8000/"
            ports:
            - containerPort: 8000
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: mockb
      labels:
        app: mockb
        service: mockb
    spec:
      ports:
      - port: 8000
        name: http
      selector:
        app: mockb
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mockb-canary
      labels:
        app: mockb
        version: canary
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mockb
          version: canary
      template:
        metadata:
          labels:
            app: mockb
            version: canary
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/go-http-sample:tracing
            imagePullPolicy: Always
            env:
            - name: version
              value: canary
            - name: app
              value: mockb
            ports:
            - containerPort: 8000

    Étape 1 : Déployer les services d'exemple

    1. Activez l'injection automatique du proxy sidecar pour le namespace cible (default dans cet exemple). Consultez la rubrique Activer l'injection automatique du proxy sidecar.

    2. Connectez-vous au cluster Container Service for Kubernetes (ACK) avec kubectl, puis déployez les services d'exemple :

      kubectl apply -n default -f application-base.yaml
      kubectl apply -n default -f application-canary.yaml

    Étape 2 : Configurer les règles de routage initiales

    Configurez la Gateway, les DestinationRules et les VirtualServices afin d'établir un routage de base sans libellés de trafic.

    1. Créez un fichier nommé routing.yaml contenant les éléments suivants :

      Contenu du fichier routing.yaml

      apiVersion: networking.istio.io/v1beta1
      kind: Gateway
      metadata:
        name: simple-gateway
      spec:
        selector:
          istio: ingressgateway
        servers:
          - hosts:
              - "*"
            port:
              name: http
              number: 80
              protocol: HTTP
      ---
      apiVersion: networking.istio.io/v1beta1
      kind: DestinationRule
      metadata:
        name: dr-mocka
      spec:
        host: mocka
        trafficPolicy:
          loadBalancer:
            simple: ROUND_ROBIN
        subsets:
          - labels:
              version: base
            name: version-base
          - labels:
              version: canary
            name: version-canary
      ---
      apiVersion: networking.istio.io/v1beta1
      kind: DestinationRule
      metadata:
        name: dr-mockb
      spec:
        host: mockb
        trafficPolicy:
          loadBalancer:
            simple: ROUND_ROBIN
        subsets:
          - labels:
              version: base
            name: version-base
          - labels:
              version: canary
            name: version-canary
      ---
      apiVersion: networking.istio.io/v1beta1
      kind: VirtualService
      metadata:
        name: vs-gateway-mocka
      spec:
        gateways:
        - simple-gateway
        hosts:
          - "*"
        http:
        - route:
            - destination:
                host: mocka
      ---
      apiVersion: networking.istio.io/v1beta1
      kind: VirtualService
      metadata:
        name: vs-mockb
      spec:
        hosts:
          - mockb
        http:
          - route:
              - destination:
                  host: mockb

      Cette configuration produit les effets suivants :

      • Une Gateway (simple-gateway) est créée pour accepter tout le trafic HTTP sur le port 80.

      • Des DestinationRules sont définies pour les deux services, avec les sous-ensembles version-base et version-canary.

      • Les VirtualServices créées acheminent le trafic sans logique basée sur des libellés.

    2. Connectez-vous à l'instance ASM avec kubectl, puis appliquez les règles de routage :

      kubectl apply -n default -f routing.yaml
    3. Vérifiez que les deux versions des services sont joignables.

      1. Récupérez l'adresse IP publique de la passerelle d'entrée depuis la console ASM. Pour plus d'informations, consultez la rubrique Obtenir l'adresse IP de la passerelle d'entrée ASM.

      2. Définissez l'adresse IP de la passerelle comme variable d'environnement. Remplacez <gateway-ip> par l'adresse IP réelle :

        export ASM_GATEWAY_IP=<gateway-ip>
      3. Envoyez des requêtes de test :

        for i in {1..200};  do curl   -H'my-asm-prefer-tag: version-base'  -H'my-trace-id: x000'$i  http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;

      Résultat attendu : le trafic est réparti aléatoirement entre toutes les versions des deux services.

      -> mocka(version: canary, ip: 172.17.0.129)-> mockb(version: base, ip: 172.17.0.70)
      -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: base, ip: 172.17.0.70)
      -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: canary, ip: 172.17.0.54)
      -> mocka(version: canary, ip: 172.17.0.129)-> mockb(version: canary, ip: 172.17.0.54)

      À ce stade, l'en-tête my-asm-prefer-tag n'a aucun effet sur le routage. Les requêtes suivent un équilibrage de charge en round-robin, quelle que soit la valeur de cet en-tête.

Instructions

  1. Lisez le texte anglais pour comprendre CE qui doit être communiqué.

  2. Rédigez le français À PARTIR DE ZÉRO — oubliez la structure des phrases anglaises.

  3. Conservez exactement toute la mise en forme markdown, les blocs de code, les liens et les images.

  4. Balises xref (<a data-tag="xref" ...>texte</a>) — conservez LA BALISE ENTIÈRE avec tous ses attributs dans l'ordre et la casse d'origine, traduisez UNIQUEMENT le texte visible entre > et .

  5. Appliquez strictement toutes les règles spécifiques à la langue.

  6. Appliquez les règles relatives aux stopwords avec une tolérance zéro.

  7. Utilisez le mode impératif dans les étapes numérotées et les listes à puces procédurales.

  8. Garantissez la cohérence terminologique — un même terme doit toujours avoir la même traduction.

  9. Variez les débuts de phrase dans les listes et les tableaux — aucune formulation introductive ne doit apparaître plus de trois fois.

  10. Retournez UNIQUEMENT le document markdown en français, sans aucune explication.

    Étape 3 : configurer les libellés de trafic

    Créez des resources TrafficLabel afin d'extraire les libellés de routage depuis les en-têtes des requêtes. ASM s'appuie sur ces libellés pour déterminer si le trafic correspond à version-base ou à version-canary. Pour plus d'informations sur le marquage du trafic, consultez la rubrique Marquer le trafic.

    1. Créez un fichier nommé trafficlabel.yaml contenant les éléments suivants :

      Contenu du fichier trafficlabel.yaml

      apiVersion: istio.alibabacloud.com/v1
      kind: TrafficLabel
      metadata:
        name: trafficlabel-ns
        namespace: default
      spec:
        rules:
        - labels:
          - name: asm-labels-sample
            valueFrom:
            - $getExternalInboundRequestHeader(my-asm-prefer-tag, my-trace-id)
      ---
      apiVersion: istio.alibabacloud.com/v1
      kind: TrafficLabel
      metadata:
        name: ingressgateway
        namespace: istio-system
      spec:
        rules:
        - labels:
          - name: asm-labels-sample
            valueFrom:
            - $getInboundRequestHeader(my-asm-prefer-tag)
        workloadSelector:
          labels:
            istio: ingressgateway

      Ce fichier définit deux resources TrafficLabel :

      Resource Périmètre Comportement
      trafficlabel-ns Tous les services du namespace default (mocka, mockb) Utilise $getExternalInboundRequestHeader pour extraire le tag de version depuis l'en-tête my-asm-prefer-tag. Le second paramètre, my-trace-id, indique l'en-tête de trace que l'application doit propager entre les services.
      ingressgateway Uniquement la passerelle d'entrée (namespace istio-system) Lit le tag de version dans l'en-tête my-asm-prefer-tag de la requête client entrante.
      Remarque

      Cet exemple utilise les noms d'en-tête my-asm-prefer-tag et my-trace-id. Remplacez-les par les en-têtes correspondant à votre application.

    2. Connectez-vous à l'instance ASM avec kubectl, puis appliquez les libellés de trafic :

      kubectl apply -f trafficlabel.yaml

    Étape 4 : appliquer le routage basé sur les libellés et vérifier

    Cette étape valide progressivement le déploiement canari de bout en bout en trois phases :

    1. Routage à un seul saut -- Appliquez le routage basé sur les libellés au service B et confirmez que le tag de trafic dirige correctement les requêtes vers la version correspondante.

    2. Routage sur toute la chaîne -- Configurez ce même type de routage pour le service A au niveau de la passerelle afin que le trafic canari traverse toutes les versions canaris des services, de bout en bout.

    3. Routage pondéré -- Combinez une distribution basée sur les poids avec le routage par libellés pour maîtriser le pourcentage de déploiement canari.

    Vérifier le routage basé sur les libellés pour le service B

    Commencez par appliquer le routage basé sur les libellés au service B. Cette opération permet de vérifier que le tag de trafic provenant du service A achemine bien les requêtes vers la version correspondante du service B.

    Service provider side canary release verification

    1. Créez un fichier nommé vs-tf-mockb.yaml contenant le code suivant :

      apiVersion: networking.istio.io/v1beta1
      kind: VirtualService
      metadata:
        name: vs-mockb
      spec:
        hosts:
          - mockb
        http:
          - route:
              - destination:
                  host: mockb
                  subset: $asm-labels-sample

      Le sous-ensemble $asm-labels-sample se résout dynamiquement selon la valeur du libellé de trafic, c'est-à-dire version-base ou version-canary.

    2. Appliquez la règle de routage :

      kubectl apply -n default -f vs-tf-mockb.yaml
    3. Envoyez du trafic canari et vérifiez que le service B le reçoit bien sur sa version canari :

      for i in {1..200}; do curl -H'my-asm-prefer-tag: version-canary' -H'my-trace-id: x000'$i http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;

      Résultat attendu : le service A continue de recevoir un trafic aléatoire, mais le service B est systématiquement dirigé vers la version canari :

      -> mocka(version: canary, ip: 172.17.0.129)-> mockb(version: canary, ip: 172.17.0.54)
      -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: canary, ip: 172.17.0.54)
      -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: canary, ip: 172.17.0.54)
    4. Générez ensuite du trafic de base et assurez-vous que le service B l'achemine vers la version de base :

      for i in {1..200}; do curl -H'my-asm-prefer-tag: version-base' -H'my-trace-id: x000'$i http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;

      Résultat attendu : le service B redirige constamment les requêtes vers la version de base :

      -> mocka(version: canary, ip: 172.17.0.129)-> mockb(version: base, ip: 172.17.0.70)
      -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: base, ip: 172.17.0.70)
      -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: base, ip: 172.17.0.70)

    Le routage du service B fonctionne désormais comme prévu. Le service A reçoit toujours le trafic de manière aléatoire, car aucune règle de routage basée sur les libellés n'a encore été appliquée à la passerelle.

    Vérifier le routage canary de bout en bout

    Appliquez un routage basé sur les libellés au service A au niveau de la passerelle afin que l'ensemble de la chaîne d'appels respecte le tag de trafic.

    End-to-end canary release verification

    1. Créez un fichier nommé vs-tf-mocka.yaml contenant le code suivant :

      apiVersion: networking.istio.io/v1beta1
      kind: VirtualService
      metadata:
        name: vs-gateway-mocka
      spec:
        gateways:
        - simple-gateway
        hosts:
          - "*"
        http:
        - route:
            - destination:
                host: mocka
                subset: $asm-labels-sample
    2. Appliquez la règle de routage à la passerelle d'entrée (ingress gateway) :

      kubectl apply -n default -f vs-tf-mocka.yaml
    3. Envoyez du trafic canary et vérifiez que les deux services sont bien dirigés vers leurs versions canary :

      for i in {1..200}; do curl -H'my-asm-prefer-tag: version-canary' -H'my-trace-id: x000'$i http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;

      Résultat attendu : tout le trafic traverse les versions canary de bout en bout.

      -> mocka(version: canary, ip: 172.17.0.69)-> mockb(version: canary, ip: 172.17.0.130)
      -> mocka(version: canary, ip: 172.17.0.69)-> mockb(version: canary, ip: 172.17.0.130)
      -> mocka(version: canary, ip: 172.17.0.69)-> mockb(version: canary, ip: 172.17.0.130)
    4. Générez ensuite du trafic de base pour vous assurer que les deux services pointent vers les versions de base :

      for i in {1..200}; do curl -H'my-asm-prefer-tag: version-base' -H'my-trace-id: x000'$i http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;

      Résultat attendu : l'intégralité du trafic emprunte les versions de base de bout en bout.

      -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93)
      -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93)
      -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93)

    Le routage canary de bout en bout est désormais opérationnel. Le trafic canary atteint systématiquement les versions canary de tous les services, tandis que le trafic de base reste orienté vers les versions de base.

    Vérifier la distribution pondérée du trafic avec des libellés

    En production, il est courant de commencer par diriger un faible pourcentage du trafic vers la version canary. Associez une distribution basée sur les poids à un routage fondé sur les libellés afin de maîtriser le déploiement.

    Weight-based and label-based routing verification

    1. Créez un fichier nommé vs-tf-mocka-90-10.yaml contenant les éléments suivants :

      apiVersion: networking.istio.io/v1beta1
      kind: VirtualService
      metadata:
        name: vs-gateway-mocka
      spec:
        gateways:
        - simple-gateway
        hosts:
          - "*"
        http:
        - route:
            - destination:
                host: mocka
                subset: version-base
              weight: 90
            - destination:
                host: mocka
                subset: $asm-labels-sample
              weight: 10

      Cette configuration envoie 90 % du trafic vers la version de base du service A. Les 10 % restants sont routés selon le libellé de trafic : si l'en-tête my-asm-prefer-tag prend la valeur version-canary, ces 10 % sont dirigés vers la version canary.

    2. Appliquez la règle de routage pondéré :

      kubectl apply -n default -f vs-tf-mocka-90-10.yaml
    3. Envoyez du trafic canary et vérifiez sa répartition :

      for i in {1..200}; do curl -H'my-asm-prefer-tag: version-canary' -H'my-trace-id: x000'$i http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;

      Résultat attendu : environ 90 % des requêtes atteignent la version de base du service A, tandis que 10 % rejoignent la version canary. Le service B dirige systématiquement le trafic vers la version canary, car le libellé se propage tout au long de la chaîne d'appels :

      -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: canary, ip: 172.17.0.130)
      -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: canary, ip: 172.17.0.130)
      -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: canary, ip: 172.17.0.130)
      ...
      -> mocka(version: canary, ip: 172.17.0.69)-> mockb(version: canary, ip: 172.17.0.130)

      Près de neuf requêtes sur dix atteignent mocka(version: base), contre environ une sur dix pour mocka(version: canary). Dans les deux cas, mockb route le trafic vers la version canary.

    4. Envoyez du trafic de base et vérifiez que toutes les requêtes atteignent les versions de base :

      for i in {1..200}; do curl -H'my-asm-prefer-tag: version-base' -H'my-trace-id: x000'$i http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;

      Résultat attendu : 90 % du trafic rejoint directement la version de base. Les 10 % restants y sont également dirigés, puisque le libellé correspond à version-base :

      -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93)
      -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93)
      -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93)
      -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93)

      Lorsque my-asm-prefer-tag vaut version-base, 90 % du trafic atteint la version de base grâce au poids fixe, et les 10 % restants y sont aussi acheminés via le libellé. L'intégralité du trafic cible donc la version de base.

    Étapes suivantes