Chemin de livraisonLes deux chemins prouvés

Un commit jusqu'à l'edge.

Mon lab prouve les contrôles canary et la promotion, mais la page qu'un visiteur peut ouvrir était livrée sans eux. Voici comment j'ai placé le même contrôle devant les deux : un commit, deux modes de livraison, une règle.

Architecture

Deux modes, un seul job qui porte le contrôle et le token d'API Cloudflare.

Faites glisser le dessin pour voir GitHub et l'edge Cloudflare. →

Deux modes, un seul job qui porte le contrôle et le token d'API Cloudflare.Un commit sur l'application de démo lance les deux modes. Un push sur main lance les tests dans GitHub Actions. Il ne déploie pas : quand le lab est arrêté, je déclenche la livraison à l'edge à la main depuis main. Autogéré : le lab teste, construit et pousse une image, puis Kargo la promeut en dev, puis en staging derrière un canary à 5 % sur le mesh, avec analyse. Seule une version vérifiée atteint l'étape de prod Kargo. Quand je la promeus, l'étape appelle l'API GitHub pour lancer la même livraison à l'edge avec cette version. Le lab détient un token GitHub limité à cela, jamais le token d'API Cloudflare. Le job Actions publie la nouvelle version à côté de la précédente sur une petite part du trafic, la mesure, puis la promeut ou l'annule. La page de statut montre aux visiteurs la version en service, sa part du trafic et le dernier résultat du contrôle.Mon lab Kubernetes · kind sur un portableGitHubEdge Cloudflare · offre gratuiteévénement Gitpush : testsimagefreightvérifiéeworkflow_dispatchdéploie + contrôlesertouvrentArgo Events + Workflowstest, build sans socket Docker, pushRegistre dans le labl'image exécute le code du Worker sur workerdKargo : dev, puis stagingdev : un pod. staging : canary Rollouts à 5 % surLinkerd, analyse de SLI dans PrometheusÉtape de prod Kargoversions vérifiées, promues à la mainToken GitHubactions: write, un seul dépôtCommit sur demo-appun dépôt, un WorkerActions : demo-app.ymlpush : tests seulement.Déclenchement : livraison par lecontrôleToken d'API Cloudflareuniquement iciWorkerversion précédente + nouvelleversion sur 10 %Page de statutversion, part du trafic, derniercontrôleVisiteursdemo.infrabio.dev123456

Dessinée par moi, pas une capture d'écran. Chaque trait a tourné dans un essai enregistré, et les points rouges rejouent une livraison sur chaque chemin. Les deux chemins aboutissent au même job GitHub Actions : le contrôle est écrit une seule fois et le token d'API Cloudflare n'entre jamais dans le cluster.

  1. 1Un commit sur l'application de démo lance les deux modes.
  2. 2Un push sur main lance les tests dans GitHub Actions. Il ne déploie pas : quand le lab est arrêté, je déclenche la livraison à l'edge à la main depuis main.
  3. 3Autogéré : le lab teste, construit et pousse une image, puis Kargo la promeut en dev, puis en staging derrière un canary à 5 % sur le mesh, avec analyse.
  4. 4Seule une version vérifiée atteint l'étape de prod Kargo. Quand je la promeus, l'étape appelle l'API GitHub pour lancer la même livraison à l'edge avec cette version. Le lab détient un token GitHub limité à cela, jamais le token d'API Cloudflare.
  5. 5Le job Actions publie la nouvelle version à côté de la précédente sur une petite part du trafic, la mesure, puis la promeut ou l'annule.
  6. 6La page de statut montre aux visiteurs la version en service, sa part du trafic et le dernier résultat du contrôle.
Problème

Les contrôles que j'ai prouvés ne touchaient jamais la seule chose qu'un visiteur peut ouvrir.

Dans le lab, une version passe par des canaries Argo Rollouts, une analyse de SLI sur le service mesh et la promotion Kargo, et une mauvaise version est annulée toute seule. Mais le lab faisait tourner une image d'exemple, et sa CI ne faisait que valider des manifestes.

La démo publique est mon propre Worker Cloudflare. GitHub Actions le testait, puis un script l'envoyait à l'edge avec une part du trafic saisie à la main. Rien ne mesurait la nouvelle version avant que tout le monde la reçoive.

Approche

Deux modes de livraison, un contrôle.

Mode cloud : un push sur main ne lance que les tests. La livraison à l'edge est un déclenchement du même workflow, qui publie la nouvelle version à côté de l'ancienne avec une petite part du trafic, la mesure, puis la promeut ou l'annule. Déclenché à la main depuis main, il ne demande aucun lab : c'est la solution de repli quand le lab est arrêté.

Mode autogéré : Argo Workflows teste, construit et pousse l'image dans le lab. Kargo la promeut en dev puis en staging sous Rollouts et l'analyse du mesh, et seule une version vérifiée atteint l'étape de prod, qui déclenche la même livraison à l'edge. Le token d'API Cloudflare reste dans GitHub.

La règle est la même sur les deux chemins : promouvoir quand le taux de succès mesuré de la nouvelle version atteint l'objectif, annuler sinon, et pas de données signifie pas de promotion.

Le contrôle

Une règle, écrite une fois, utilisée par les deux modes.

  1. 01

    La nouvelle version reçoit 10 % du trafic. La version précédente garde le reste.

  2. 02

    Le job envoie un nombre fixe de requêtes et ne compte que les réponses de la nouvelle version.

  3. 03

    Il compare le taux de succès de la nouvelle version à l'objectif, le même que celui de l'analyse du lab.

  • Pas de données

    Pas de promotion. La version précédente garde tout le trafic.

  • Sous l'objectif

    Annulation. Tout le trafic revient à la version précédente.

  • À l'objectif ou au-dessus

    Promotion. La nouvelle version reçoit tout le trafic.

Chaque étapeP12 → P14

L'état de chaque étape. Les chiffres apparaissent quand l'essai qui les mesure existe.

Les deux chemins ont tourné de bout en bout, l'autogéré sur mon lab existant, pas sur une reconstruction à neuf.

Autogéré

Dans mon lab Kubernetes, avec Argo Workflows et Kargo.

  1. P13Prouvé

    Commit sur l'application de démo

    Un événement Git lance le pipeline du lab. Envoyé à la main pour l'instant : pas de webhook public.

  2. P13Prouvé

    Argo Workflows : test, build, push

    Un test en échec a bloqué le push : aucune image. BuildKit sans root, sans socket Docker.

    2 min 33 s de l'événement à l'image

  3. P13Prouvé

    Registre dans le lab

    L'image exécute le même code que l'edge, sur workerd.

  4. P14Prouvé

    Freight Kargo

    Kargo transforme la nouvelle image du registre du lab en freight, une version candidate.

  5. P14Prouvé

    dev : premier déploiement

    Un pod, sans analyse. Une freight qui tourne ici passe en staging.

  6. P14Prouvé

    staging : canary à 5 % sur le mesh

    Argo Rollouts envoie 5 % du trafic à la nouvelle version par Linkerd, et l'analyse de SLI la mesure. Une version qui renvoie des 500 a mesuré 0 et a été arrêtée.

    6 min 15 s de l'événement à la vérification en staging

  7. P14Prouvé

    Étape de prod Kargo

    Je promeus à la main, et seulement une version vérifiée. La version arrêtée a été refusée : « Freight is not available to this Stage ». L'étape déclenche la livraison à l'edge avec cette version.

    1 min 35 s de la promotion à 100 % à l'edge

Cloud

GitHub Actions seulement, sans lab. La solution de repli quand le lab est arrêté.

  1. P12Prouvé

    Commit sur l'application de démo

    Un push sur main lance le workflow.

  2. P12Prouvé

    GitHub Actions : test

    Vérification des types et tests. Un push sur main s'arrête ici.

  3. P12Prouvé

    Déclenchement à la main depuis main

    Livre la tête de main à l'edge, par le même contrôle.

Les deux chemins

  1. P12Prouvé

    Edge : canary, contrôle, promotion ou annulation

    La nouvelle version reçoit 10 % du trafic. Le contrôle la mesure et décide.

    49 sur 49 bonnes : promue en 10 s · 0 sur 50 bonnes : annulée en 9 s

  2. P12Prouvé

    Page de statut

    Affiche la version en service, sa part du trafic et le dernier résultat du contrôle.

Tiré des essais

Deux versions cassées, arrêtées par le contrôle.

Rendu à partir des sorties enregistrées des essais, pas des captures d'écran : le journal GitHub Actions de l'essai à l'edge et le relevé du runbook pour l'essai du lab. Chaque valeur affichée vient de ces relevés. Le texte des vidéos est en anglais.

À l'edge : une version qui renvoie des 500, annulée en 9 s
Dans le lab : la même panne, arrêtée en staging et refusée en prod
Chiffres

Mesurés, ou pas affichés.

Un commit d'un événement push dans mon lab à 100 % à l'edge, sans compter mon approbation
7 min 50 sUn commit d'un événement push dans mon lab à 100 % à l'edge, sans compter mon approbation
D'un événement push à l'arrêt, par le canary de staging, d'une version qui renvoie des 500. Kargo l'a ensuite refusée en prod
4 min 4 sD'un événement push à l'arrêt, par le canary de staging, d'une version qui renvoie des 500. Kargo l'a ensuite refusée en prod
Une version qui renvoie des 500 annulée à l'edge : 0 sur 50 bonnes, 10 % du trafic exposé
9 sUne version qui renvoie des 500 annulée à l'edge : 0 sur 50 bonnes, 10 % du trafic exposé
Une bonne version promue à tout le trafic : 49 sur 49 bonnes
10 sUne bonne version promue à tout le trafic : 49 sur 49 bonnes

Les essais à l'edge sont passés par GitHub Actions depuis main sur le Worker en ligne, sans étape manuelle. L'essai du lab est parti d'un événement push envoyé à la main, et j'ai approuvé la promotion en prod ; cette attente n'est pas comptée. Le refus de la version cassée était un essai à blanc côté serveur : rien n'a été déclenché.

Périmètre
  • Dans le lab, l'application de démo tourne sur workerd dans un conteneur avec un stockage local. C'est le même code, pas l'edge Cloudflare.
  • Une livraison par le chemin autogéré demande que mon lab sur portable soit démarré. Quand il est arrêté, je déclenche la même livraison à l'edge à la main.
  • Les durées du lab partent d'un événement push envoyé à la main : le lab n'est pas joignable depuis internet. Elles viennent de mon lab existant, pas d'une reconstruction à neuf.
  • Aucun token d'API Cloudflare n'est dans le cluster. L'étape de prod ne détient qu'un token GitHub limité à Actions sur un seul dépôt.
  • Le contrôle mesure ses propres requêtes, dirigées vers la nouvelle version, pas le trafic des visiteurs.
  • La démo tourne sur l'offre gratuite de Cloudflare, donc le contrôle n'ajoute aucune écriture en stockage.
En direct sur la démo