Trois façons de décharger un navire

Sur Le Port, une cargaison descend à terre de trois manières.

Tu amènes tes propres dockers et ton propre engin de levage. Tu décides de la cadence, de l'ordre de déchargement, du calage. Tu payes aussi la maintenance, les pannes et les absences.

Tu loues un portique avec son grutier. L'exploitant garantit que la machine tourne, tu lui dis quoi soulever et où le poser. Tu perds la main sur le modèle de portique et sur ses fenêtres d'entretien.

Ou tu confies la cargaison au terminal automatisé. Tu déposes des conteneurs normalisés à l'entrée, ils ressortent rangés. Tu ne sais pas comment, tu ne veux pas le savoir, et tu payes au conteneur traité.

Aucune des trois n'est meilleure. Elles conviennent à des cargaisons différentes, à des volumes différents, et surtout à des équipes différentes.

La question n'est pas quelle machine exécute le code. C'est qui se lève la nuit quand elle s'arrête.

Sept services couvrent l'essentiel de ce qu'on exécute sur Azure, et le premier réflexe de beaucoup d'équipes reste la machine virtuelle parce que c'est celle qu'elles connaissent. Ce billet parcourt les options du plus manuel au plus abstrait, puis pose les questions qui tranchent réellement. Le dimensionnement des machines virtuelles, lui, fait l'objet du billet suivant.


Vue d'ensemble : un seul axe, et son prix

Le quai nu et le terminal clés en main sont les deux bouts d'un même axe. Plus tu montes vers l'automatisé, moins tu exploites, et plus tu acceptes les contraintes de l'exploitant : ses horaires, ses formats de conteneur, sa façon de facturer.

C'est exactement la ligne de responsabilité partagée posée au début de la série, appliquée au calcul. Elle ne disparaît jamais, elle se déplace.

Ce que tu exploites, du plus manuel au plus abstrait
Machines virtuelles
Système, correctifs, agents, images, sauvegardes. Contrôle total, exploitation totale.
AKS
Le plan de contrôle est managé. Les nœuds, les versions et le réseau du cluster restent à toi.
Container Apps
Une image, des révisions, des règles de montée en charge. Aucun cluster à tenir.
App Service
Un artefact applicatif, un plan, des emplacements de déploiement et un certificat.
Azure Functions
Une fonction et son déclencheur. Rien à allumer, rien à éteindre, rien à corriger.
Vers la droite : moins d'exploitation quotidienne, mais les limites du service deviennent tes limites.

Deux options sortent de cet axe parce qu'elles répondent à un besoin différent : Azure Batch, pour les traitements finis et massivement parallèles, et Azure Virtual Desktop, pour des postes de travail plutôt que pour du code applicatif.

Voici l'arbre que j'utilise pour dégrossir. Il ne remplace pas l'analyse, il évite de perdre trois réunions sur une option déjà éliminée par une contrainte connue.

flowchart TD A["Du code à exécuter"] --> B{"Des postes de travail
pour des utilisateurs ?"} B -- oui --> AVD["Azure Virtual Desktop"] B -- non --> C{"Un traitement fini,
massivement parallèle ?"} C -- oui --> BAT["Azure Batch"] C -- non --> D{"Dépendance au système
ou à un logiciel tiers ?"} D -- oui --> VM["Machines virtuelles
et groupes identiques"] D -- non --> E{"Le code est-il
déjà conteneurisé ?"} E -- non --> F{"Déclenché par un événement,
charge sporadique ?"} F -- oui --> FN["Azure Functions"] F -- non --> APP["App Service"] E -- oui --> G{"Besoin de l'API Kubernetes
et de son écosystème ?"} G -- oui --> AKS["AKS"] G -- non --> CA["Container Apps"] classDef start fill:#2c3338,stroke:#5f5e5a,color:#f5f2ec classDef q fill:#f5f2ec,stroke:#8a4d16,color:#1a1a1a classDef svc fill:#b5651d,stroke:#5f5e5a,color:#f5f2ec class A start class B,C,D,E,F,G q class AVD,BAT,VM,FN,APP,AKS,CA svc
Un arbre de décision sert à éliminer, pas à désigner. Ce qui reste au bout se départage sur le coût et sur les compétences de l'équipe.

Les sept services, un par un

L'exploitant du port ne loue pas le même équipement à un céréalier et à un armateur de porte-conteneurs. Chaque service ci-dessous a un profil de cargaison qui le rend évident, et un autre qui le rend absurde.

Machines virtuelles et groupes identiques

Tu obtiens un système d'exploitation, et rien de plus. Les correctifs, les agents, le durcissement, l'image de référence, la sauvegarde : tout t'appartient.

Le groupe de machines virtuelles identiques ajoute la mise à l'échelle horizontale et l'auto-réparation d'un parc homogène, avec deux modes d'orchestration, uniforme et flexible.

Évident quand un progiciel tiers impose sa procédure d'installation, quand une licence est attachée à la machine, quand la charge est continue et prévisible, ou quand on reprend telle quelle une application venue d'une salle serveur.

Absurde pour une API sans état au trafic irrégulier : tu payes environ 730 heures par mois pour du code qui travaille quelques heures.

App Service

Tu déposes une application web, une API ou une image de conteneur. La plateforme fournit le système, le moteur d'exécution, le domaine, le certificat et la mise à l'échelle.

Les emplacements de déploiement méritent qu'on s'y arrête : tu déploies sur un emplacement de préproduction, tu le chauffes, puis tu l'échanges avec la production. C'est un déploiement sans coupure obtenu sans construire quoi que ce soit.

Le niveau de service décide de presque tout. Les niveaux d'entrée ne donnent ni mise à l'échelle automatique ni intégration réseau complète ; les niveaux supérieurs les débloquent, et le niveau isolé place l'ensemble dans ton propre réseau virtuel.

Absurde dès qu'il faut un agent système, un pilote particulier, ou qu'une requête HTTP doit tenir plusieurs heures. Les traitements longs partent dans une file et se traitent ailleurs.

Azure Functions et le modèle événementiel

Le code est découpé en fonctions, chacune attachée à un déclencheur : requête HTTP, message arrivé dans une file, minuterie, fichier déposé, événement de flux. Les liaisons d'entrée et de sortie évitent d'écrire le code de connexion aux services.

Le plan d'hébergement change tout. Le plan de consommation facture à l'exécution, descend à zéro instance et borne la durée d'une exécution à quelques minutes, au prix d'un démarrage à froid. Les plans premium et dédié gardent des instances préchauffées, ouvrent l'intégration au réseau virtuel et repoussent largement la limite de durée.

Pour un enchaînement d'étapes longues, l'extension Durable Functions gère l'état de l'orchestration à ta place plutôt que de laisser une fonction attendre.

Évident pour la colle entre services, les tâches courtes, le trafic sporadique. Absurde pour une charge forte et continue : chaque exécution est facturée, et le prix unitaire intègre justement l'inactivité que tu ne payes pas.

Container Apps

L'exécution de conteneurs sans cluster à exploiter. Mise à l'échelle jusqu'à zéro, montée en charge pilotée par le trafic HTTP ou par une source d'événements, révisions avec répartition du trafic en pourcentage, entrée HTTP managée, et des travaux pour les traitements finis.

# Règle de montée en charge d'une application conteneurisée
scale:
  minReplicas: 0
  maxReplicas: 30
  rules:
    - name: http-rule
      http:
        metadata:
          concurrentRequests: "50"

Le minReplicas: 0 est la ligne intéressante : hors trafic, tu ne payes rien, et la première requête paye le réveil. Mets 1 si cette latence n'est pas acceptable.

Évident pour des services conteneurisés, des consommateurs de files, des API, quand l'équipe veut le modèle conteneur sans l'API Kubernetes. Absurde dès qu'il faut des opérateurs, des contrôleurs personnalisés ou un pilotage fin des nœuds.

AKS

Kubernetes managé : Azure exploite le plan de contrôle, les nœuds restent les tiens. Pools système et pool utilisateur, modèle réseau, mises à niveau, extensions, politiques.

Ce que le service managé ne prend pas en charge se dit franchement : le rythme des montées de version, la capacité et le calibre des nœuds, le plan d'adressage, les politiques réseau, la gestion des secrets, l'observabilité du cluster. Un pool utilisateur peut descendre à zéro nœud, mais le cluster, lui, ne s'éteint pas.

Évident quand le parc de services est important, quand l'équipe maîtrise déjà l'écosystème, ou quand une contrainte impose des composants Kubernetes précis. Absurde pour trois conteneurs et personne pour tenir le cluster.

Azure Batch

La planification de traitements massivement parallèles. Tu décris un travail et ses tâches, le service monte un pool de machines, exécute, puis le fait redescendre. Les nœuds interruptibles à prix réduit y sont à leur place, puisqu'une tâche perdue se rejoue.

Évident pour le rendu d'images, la simulation, l'encodage, le calcul scientifique, tout traitement fini découpable en unités indépendantes. Absurde pour un service en ligne qui doit répondre en permanence.

Azure Virtual Desktop

La virtualisation de postes et d'applications. Le courtier de connexion, la passerelle et les diagnostics sont managés ; les hôtes de session sont des machines virtuelles que tu exploites, dans ton abonnement et dans ton réseau.

Deux modèles de pool : partagé, où plusieurs utilisateurs se répartissent les hôtes, et personnel, où chacun retrouve le sien. Windows 365 répond au même besoin avec un poste facturé à l'utilisateur et beaucoup moins de réglages.

Évident pour des prestataires externes, des postes qui doivent rester près de la donnée, des applications lourdes. Absurde pour héberger un service applicatif.

Service Ce que tu exploites Profil de charge évident Signe que c'est le mauvais choix
Machines virtuelles Système, correctifs, agents, images Continue, prévisible, ou dépendante du système Le serveur passe ses nuits à ne rien faire
App Service L'artefact applicatif et son plan Application web ou API à trafic régulier Il faut installer un agent ou un pilote
Azure Functions Le code de la fonction Sporadique, événementielle, courte La charge ne redescend jamais
Container Apps L'image et les règles de montée Services conteneurisés, files, API Il faut des opérateurs Kubernetes
AKS Les nœuds, les versions, le réseau Parc conteneurisé, équipe outillée Personne ne tient le cluster à plein temps
Azure Batch La définition des travaux Traitement fini, parallélisable Il faut répondre à une requête en ligne
Azure Virtual Desktop Les hôtes de session Postes de travail distants Ce n'est pas un poste, c'est un service

Les six questions qui tranchent

Avant de signer une concession, l'exploitant du port pose toujours les mêmes questions : ce que tu transportes, à quelle fréquence, et qui manœuvre. Les tiennes sont au nombre de six.

La dépendance au système. Un logiciel tiers qui exige une version de noyau précise, un agent de sécurité imposé, un pilote, une licence liée au matériel : la question est réglée, ce sera une machine virtuelle. Pose-la en premier, elle élimine plus vite que toutes les autres.

Le profil de charge. Continu, en pointe régulière, ou sporadique. Une charge continue rentabilise de la capacité réservée. Une charge sporadique paye de l'inactivité si elle tourne sur une machine allumée en permanence.

Le démarrage à froid. Descendre à zéro ne coûte rien tant que la première requête peut attendre le réveil. Pour un traitement d'arrière-plan, personne ne le remarque. Pour une page vue par un client, c'est une réclamation.

La durée maximale d'exécution. Chaque plateforme abstraite impose une borne, et cette borne se découvre en production si on ne l'a pas lue. Un traitement long se découpe, s'orchestre, ou change de service.

L'exigence réseau. Adresse privée, sortie maîtrisée, accès à un point de terminaison privé, absence d'exposition publique : tous les plans d'hébergement n'offrent pas l'intégration au réseau virtuel. C'est très souvent ce point, et non un besoin de puissance, qui fait monter d'un niveau de service.

Les compétences de l'équipe. La plus déterminante, et la plus escamotée. Un cluster mal exploité est moins disponible qu'une plateforme managée acceptée avec ses contraintes.

La question Ce qu'elle élimine Ce qu'elle désigne
Dépendance système ou logiciel tiers Toutes les plateformes managées Machines virtuelles, groupes identiques
Charge continue et forte Le sans serveur facturé à l'exécution Machine virtuelle réservée, plan dédié
Charge sporadique La machine allumée en permanence Functions, Container Apps à zéro réplica
Démarrage à froid inacceptable La mise à l'échelle jusqu'à zéro Instances préchauffées, réplica minimal à 1
Traitement de plusieurs heures Le plan de consommation, la requête HTTP Batch, travail conteneurisé, orchestration
Réseau privé obligatoire Les niveaux d'entrée Niveaux supérieurs, isolé, cluster privé
Équipe sans culture Kubernetes AKS Container Apps, App Service
Six questions, et la seule qu'on n'ose pas poser à voix haute est la dernière. Elle décide pourtant du taux de disponibilité réel.

Le coût du choix

Sur Le Port, deux façons de payer coexistent : le tarif au conteneur manutentionné, et la concession annuelle du quai. Le premier ne coûte rien les jours sans navire. Le second devient imbattable dès qu'il y a un navire tous les jours.

L'arbitrage est identique du côté des services de calcul, et il tient en deux calculs.

Une charge continue en sans serveur. Cent requêtes par seconde, deux cents millisecondes de traitement chacune. Sur un mois de trente jours, cela fait 100 × 2 592 000, soit 259,2 millions d'exécutions facturées. En parallélisme moyen, 100 × 0,2 = 20 exécutions simultanées en permanence. Si chacune mobilise un cœur, cela revient à une vingtaine de cœurs occupés en continu, que trois machines de huit cœurs couvrent. Tu payes 259 millions d'événements de facturation pour un travail que trois machines réservées absorbent à tarif plat.

Une charge sporadique sur machine allumée. Cinq mille exécutions par jour, trois cents millisecondes chacune. Cela représente 1 500 secondes de calcul utile par jour, soit 12,5 heures sur le mois. La machine, elle, est facturée environ 730 heures. Le taux d'utilisation tourne autour de 1,7 %, et l'essentiel de la facture paye du silence.

Profil de charge Facturé à l'exécution Facturé au temps allumé Ce qui décide
Continue et stable Chaque requête compte, sans plancher ni plafond Capacité fixe, éligible aux réservations Le temps allumé gagne, et l'écart grandit avec le volume
Pointes régulières Suit la courbe sans réglage Capacité dimensionnée sur la pointe, payée hors pointe Mise à l'échelle automatique des deux côtés, comparaison au cas par cas
Sporadique Proche de zéro entre deux appels Payé en totalité L'exécution à la demande gagne largement
Traitement de nuit Nombreuses petites unités Pool monté puis démonté Un pool éphémère avec nœuds interruptibles

Deux réflexes pèsent plus lourd que le choix du service lui-même. Éteindre ce qui n'est pas utilisé, à commencer par les environnements hors production le soir et le week-end. Et couvrir par une réservation ou un plan d'économies uniquement la capacité dont tu es certain qu'elle tournera pendant toute la durée d'engagement.

Le sans serveur n'est pas moins cher. Il facture ce que tu consommes, ce qui est une bonne affaire exactement tant que tu consommes peu.

Les combinaisons qui existent vraiment

Un port sérieux ne choisit pas entre les dockers, le portique et le terminal automatisé. Il a les trois, affectés à des trafics différents.

Un système réel mélange toujours plusieurs services de calcul. Une API sur App Service ou sur Container Apps, des fonctions pour l'événementiel et les traitements planifiés, un pool Batch pour la reprise nocturne, et une machine virtuelle qui porte le progiciel tiers dont personne n'a le code source.

Cette hétérogénéité est saine tant qu'elle est décidée. Elle devient un problème quand elle est subie : chaque service supplémentaire ajoute un mode de déploiement, un mode de supervision, un modèle d'identité et un jeu de limites à connaître.

La règle que j'applique tient en une phrase : un service de calcul de plus doit apporter une capacité qu'aucun de ceux déjà en place ne couvre. Sinon, c'est de la dette d'exploitation payée en heures d'équipe.

# La même API, du plus manuel au plus abstrait
az vm create --resource-group rg-calcul --name vm-api \
  --image Ubuntu2204 --admin-username azureuser --generate-ssh-keys
az webapp up --resource-group rg-calcul --name app-api --runtime "NODE:20-lts"
az containerapp up --resource-group rg-calcul --name ca-api --source .

Trois commandes, trois contrats d'exploitation très différents. La première te laisse un système entier sur les bras, la troisième te laisse une image et des règles de montée en charge.


Scénario B : Segment, une centaine de services ramenés à un

En 2018, l'équipe d'ingénierie de Segment publie « Goodbye Microservices: From 100s of Problem Children to 1 Superstar », signé Alexandra Noonan. Le billet raconte un chemin aller et retour, et il est rare parce qu'il assume le retour.

Le produit de Segment reçoit des données d'événements de ses clients et les redistribue vers des destinations tierces : outils d'analyse, CRM, plateformes publicitaires. À l'origine, un service unique fait ce travail. Le problème apparaît vite : quand l'API d'une destination ralentit ou tombe, la file partagée se remplit et retarde toutes les autres.

La réponse est logique, et elle a marché. Un service par destination, avec sa propre file. Une destination en panne n'affecte plus ses voisines.

Le coût arrive avec le nombre. Les destinations dépassent la centaine. Chacune a son dépôt, sa file, sa configuration de capacité à entretenir, et sa copie de la bibliothèque partagée qui fait le travail commun. Les versions divergent. Un correctif dans cette bibliothèque doit être répercuté dépôt par dépôt, et testé autant de fois. Le billet est explicite sur ce point : ce qui devient intenable, c'est le coût d'exploitation et de mise à jour des dépendances, pas la performance.

L'équipe regroupe alors les destinations dans un dépôt unique et un service unique, avec une seule version de la bibliothèque partagée. Le billet expose aussi ce que ce regroupement leur a coûté : l'isolation des pannes entre destinations, précisément ce qu'ils étaient allés chercher au départ. Ils l'acceptent sciemment, et traitent le sujet autrement.

Le choix de granularité d'exécution ne se juge pas le jour de la mise en production. Il se juge au bout de deux ans, quand il faut appliquer un correctif partout en même temps.

La transposition côté Azure est directe. Quarante applications de fonctions, c'est quarante configurations d'hébergement, quarante identités managées, quarante pipelines et quarante jeux de règles d'alerte. Deux applications conteneurisées avec des révisions, c'est deux. Le service de calcul détermine ce que tu déploies, mais surtout ce que tu maintiens.


Points clés

  • Choisir un service de calcul revient à choisir qui exploite quoi : ce que tu gagnes en contrôle, tu le payes en travail quotidien.
  • La dépendance au système ou à un logiciel tiers est la première question à poser : elle tranche immédiatement en faveur de la machine virtuelle.
  • Le profil de charge décide du modèle de facturation : continu et stable pour de la capacité réservée, sporadique pour une exécution à la demande, avec le calcul posé plutôt que l'intuition.
  • Les contraintes qui font vraiment basculer un choix sont le démarrage à froid, la durée maximale d'exécution et l'intégration au réseau virtuel, bien avant la puissance brute.
  • Un système réel mélange plusieurs services de calcul ; chaque service en plus doit apporter une capacité qu'aucun autre ne couvre, sinon c'est de la dette d'exploitation.

Dans la série

Palier 2 : Construire les terminaux. Domaine : Calcul.

Pour aller plus loin