Infrastructure et cloud
Où tourne ton application, comment elle survit à une panne, et combien ça coûte vraiment.
Une application, c'est du code, mais aussi des machines, un réseau, une base de données, des fichiers, et une facture. Cette fiche part du cas le plus simple, un seul serveur, et montre ce qui change quand le trafic grandit ou quand une panne n'est plus acceptable. Puis elle compare les façons d'héberger : ton propre serveur, le cloud à la demande, les plateformes gérées et le serverless.
Le but n'est pas de t'envoyer sur l'architecture la plus impressionnante. C'est de savoir laquelle correspond à ton besoin, et ce qu'elle coûte en argent comme en travail. Beaucoup d'applications vivent très bien sur un seul serveur.
1.Le point de départ : un serveur
La boutique tourne sur un VPS (Virtual Private Server), une machine virtuelle louée quelques dizaines d'euros par mois. Tout est dessus : nginx, PHP-FPM, PostgreSQL, Redis, les tâches planifiées, les fichiers envoyés par les clients. C'est ce que tu as appris à administrer en fiche 11.
- C'est simple : une seule machine à comprendre, à surveiller et à sauvegarder.
- C'est bon marché, et le coût est fixe et prévisible.
- C'est un point unique de panne (single point of failure) : si la machine tombe, tout tombe. Une mise à jour du système qui demande un redémarrage coupe aussi le site.
- Tout se partage : un import lourd ou une requête SQL lente ralentit aussi les pages vues par les clients.
Pour un site interne, une association, un produit qui démarre ou une boutique à quelques milliers de visites par jour, un serveur bien sauvegardé (fiche 13), surveillé et mis à jour reste souvent le meilleur choix. Une coupure de quelques minutes par mois y est acceptable. Ne paie pas tout de suite pour des problèmes que tu n'as pas encore.
2.Grandir : verticalement ou horizontalement
Le trafic double, le serveur sature. Il existe deux façons de grandir (en anglais, scaling) :
- Verticalement (scale up) : une machine plus grosse. C'est le premier réflexe, et souvent le bon : aucun changement dans le code. Mais il y a une limite, et la machine reste unique.
- Horizontalement (scale out) : plusieurs machines identiques derrière un répartiteur de charge (load balancer, fiche 9). Plus de limite théorique, et une machine peut tomber sans couper le site. C'est aussi ce que fait Kubernetes avec ses réplicas (fiche 12).
Une condition apparaît pour la seconde : la requête suivante d'un client peut arriver sur une autre machine. L'application doit donc fonctionner sans rien garder sur le disque local.
3.Une application sans état
Une application sans état (stateless) ne garde rien d'important sur la machine qui l'exécute. Prenons les sessions : par défaut, Symfony les range dans des fichiers, sur le disque du serveur. Avec deux serveurs et un répartiteur qui envoie les requêtes à tour de rôle, Alice se connecte sur le serveur A, qui range sa session sur son disque. Sa requête suivante arrive sur le serveur B, qui n'a jamais vu cette connexion : pour lui, Alice est anonyme (schéma 19.2). Le même problème touche tout ce qui reste sur le disque local. Il faut tout recenser, et déplacer chaque chose dans un service partagé :
| Ce qui est sur le disque | Le problème avec deux serveurs | Où le mettre |
|---|---|---|
| Les sessions | Déconnexions au hasard | Redis ou la base de données |
| Les fichiers envoyés | L'image est sur un serveur, pas sur l'autre | Un stockage objet (S3 ou compatible), avec Flysystem |
| Le cache applicatif | Chaque serveur a sa version, parfois périmée | Redis |
| Les verrous (Lock) | Deux serveurs prennent le même verrou | Redis ou la base de données |
| Les tâches planifiées | La facture mensuelle part en deux exemplaires | Une seule instance, ou le Scheduler avec un verrou |
| Les logs | Éparpillés, et perdus quand la machine disparaît | La sortie standard, collectée ailleurs (fiche 21) |
# config/packages/framework.yaml (extrait) : rien d'important sur le disque du serveur
framework:
session:
handler_id: '%env(REDIS_URL)%' # sessions partagées par tous les serveurs
cache:
app: cache.adapter.redis
default_redis_provider: '%env(REDIS_URL)%'
lock: '%env(REDIS_URL)%' # un verrou visible de tous les serveursLe cache de Symfony lui-même (le dossier var/cache, construit au déploiement) peut rester local : il est identique sur chaque machine, puisqu'il vient de la même image (fiche 18).
4.Une architecture type
Voici la forme que prennent beaucoup d'applications web chez un fournisseur cloud. Chaque bloc existe aussi en « service géré » : le fournisseur s'occupe des mises à jour, des sauvegardes et du remplacement en cas de panne.
- Un réseau privé (VPC, Virtual Private Cloud) : les serveurs et la base n'ont pas d'adresse publique. Seul le répartiteur de charge est joignable depuis Internet. Pour administrer, on passe par une machine d'accès unique (un bastion) ou par l'accès à distance géré du fournisseur.
- Des zones : une région (Paris, Francfort…) contient plusieurs zones de disponibilité, des centres de données séparés, avec leur propre alimentation électrique. Répartir les machines sur deux zones protège d'un incendie ou d'une coupure de courant.
- Une base principale et une copie : la base de secours reçoit chaque écriture et prend le relais en cas de panne, en général en une ou deux minutes.
- Un CDN (Content Delivery Network, fiche 9) sert les images et les fichiers CSS et JavaScript depuis des serveurs proches des visiteurs.
- Des workers traitent les messages Messenger en arrière-plan (fiches 16 et 17), sur des machines à part : un gros traitement ne ralentit plus les pages.
- Un stockage objet public par erreur. Des fuites massives de données viennent d'un simple réglage de lecture publique. Garde tout privé par défaut, et sers les fichiers par des URL signées, qui expirent.
- Des droits trop larges. Chaque composant reçoit uniquement ce dont il a besoin, comme cette politique d'accès qui ne permet que de lire et d'écrire les fichiers envoyés :
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "UploadsSeulement",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::boutique-uploads/*"
}
]
}- Le compte principal utilisé au quotidien. Protège-le par une double authentification, range-le, et travaille avec des comptes nominatifs aux droits limités.
- Un port d'administration ouvert à tout Internet (SSH, base de données). Les règles de pare-feu du fournisseur (les groupes de sécurité) n'ouvrent que ce qui est nécessaire, et seulement à qui en a besoin (fiche 11).
5.La haute disponibilité et son prix
On exprime la disponibilité en pourcentage du temps où le service fonctionne, souvent en « nombre de 9 ». Traduite en temps d'arrêt cumulé sur un an, elle devient beaucoup plus concrète :
| Disponibilité | Arrêt possible par an | Ordre de grandeur |
|---|---|---|
| 99 % | 3,7 jours | Un serveur unique, sans précaution particulière |
| 99,9 % | 8 h 46 min | Un objectif courant pour une application métier |
| 99,95 % | 4 h 23 min | Ce que promettent souvent les services gérés |
| 99,99 % | 53 min | Des machines en double partout, sur plusieurs zones |
Une application est une chaîne d'éléments, et deux règles permettent d'estimer sa disponibilité :
- En série, les disponibilités se multiplient. Une requête traverse le répartiteur, un serveur et la base : il suffit qu'un seul tombe. L'ensemble est donc moins disponible que son élément le plus faible.
- En parallèle, elles se protègent. Deux serveurs, dont un seul suffit, ne tombent ensemble que si les deux tombent : on calcule 1 − (1 − a)², où a est la disponibilité d'un serveur.
Prenons un répartiteur à 99,99 %, des serveurs à 99,9 % et une base à 99,95 % :
| Architecture | Calcul | Disponibilité | Arrêt par an |
|---|---|---|---|
| Un serveur, une base | 0,9999 × 0,999 × 0,9995 | 99,84 % | 14 h |
| Deux serveurs, une base | 0,9999 × (1 − 0,001²) × 0,9995 | 99,94 % | 5 h 16 min |
| Deux serveurs, deux bases | 0,9999 × (1 − 0,001²) × (1 − 0,0005²) | 99,99 % | 53 min |
Trois enseignements :
- Doubler les serveurs ne suffit pas : tant que la base reste unique, c'est elle qui limite tout.
- Ces chiffres sont des estimations : ils supposent des pannes indépendantes. Une erreur de configuration déployée partout, ou une région entière en panne, fait tomber tous les exemplaires à la fois.
- Chaque 9 supplémentaire coûte cher : des machines en double, une base de secours, plusieurs zones, et des personnes capables de réagir la nuit.
Deux chiffres complètent la disponibilité, et se décident avec le métier, pas seulement par l'équipe technique :
- Le RTO (Recovery Time Objective) : combien de temps le service peut rester arrêté après une panne grave.
- Le RPO (Recovery Point Objective) : combien de données récentes on accepte de perdre. Une sauvegarde par nuit, c'est un RPO de 24 heures. La sauvegarde et sa restauration sont détaillées en fiche 13.
Pose la question au métier sous la forme d'un coût : « si la boutique est fermée deux heures un mardi après-midi, combien perd-on ? ». Pour la plupart des applications, 99,9 % suffisent largement. Viser 99,99 % sans que la perte le justifie, c'est payer très cher pour quelques heures par an.
6.IaaS, PaaS, conteneurs, serverless : qui gère quoi
Le mot « cloud » recouvre plusieurs façons de louer des ressources. Elles diffèrent surtout par ce que tu gères, et ce que gère le fournisseur :
- L'IaaS (Infrastructure as a Service) loue des machines virtuelles, des disques et des réseaux, à la demande : AWS EC2, Scaleway Instances, OVHcloud Public Cloud. Tu gères le système comme sur ton propre serveur, mais tu crées une machine en une minute.
- Le PaaS (Platform as a Service) prend ton code et le fait tourner : tu choisis la version de PHP, la plateforme s'occupe du reste. Clever Cloud ou Upsun, la plateforme de l'éditeur de Platform.sh, en sont des exemples.
- Les conteneurs gérés (CaaS) font tourner ton image Docker sans que tu administres de serveur : Google Cloud Run, AWS ECS avec Fargate, ou un Kubernetes géré par le fournisseur.
- Le serverless, ou FaaS (Function as a Service), exécute ton code à chaque événement, et seulement à ce moment-là : AWS Lambda, Google Cloud Functions, Scaleway Serverless Functions.
Une règle ne change jamais, quel que soit le modèle : tes données, ton code et les droits d'accès restent sous ta responsabilité. Les fournisseurs l'appellent le modèle de responsabilité partagée. Un fournisseur ne te protège pas d'un bucket laissé public ou d'un mot de passe faible.
7.Le serverless
Le nom trompe : il y a bien des serveurs, mais tu ne les vois jamais. Ton code est lancé à chaque requête ou à chaque événement (un fichier déposé, un message dans une file), facturé à la durée d'exécution, et rien n'est facturé quand rien ne se passe. Pour PHP, l'outil de référence est Bref, qui fait tourner une application Symfony sur AWS Lambda :
# serverless.yml : une application Symfony sur AWS Lambda avec Bref.
# Les noms de runtime dépendent de ta version de Bref : vérifie-les dans sa documentation.
service: boutique
provider:
name: aws
region: eu-west-3 # Paris
environment:
APP_ENV: prod
plugins:
- ./vendor/bref/bref
functions:
web: # chaque requête HTTP lance l'application
handler: public/index.php
runtime: php-84-fpm
timeout: 28 # secondes, la limite de l'API Gateway est proche
events:
- httpApi: '*'
worker: # les messages Messenger, depuis une file SQS
handler: bin/consumer.php
runtime: php-84
timeout: 120- Il grandit tout seul : cent requêtes simultanées lancent cent exécutions, sans rien configurer.
- Le démarrage à froid (cold start) : après une période sans trafic, la première requête attend que l'environnement démarre, de quelques centaines de millisecondes à plus d'une seconde.
- Des limites strictes : 15 minutes au plus par exécution sur Lambda, environ 30 secondes derrière l'API HTTP, et aucun disque persistant. Tout doit être sans état (section 3).
- La base de données souffre : mille exécutions simultanées, ce sont mille connexions à PostgreSQL. Il faut un intermédiaire qui les regroupe, comme RDS Proxy chez AWS.
Utile pour un trafic faible ou très irrégulier (un site d'événement, un back-office peu utilisé), des traitements déclenchés par des événements (redimensionner une image déposée), et les petites équipes qui ne veulent administrer aucun serveur.
À éviter pour un trafic élevé et régulier (plus cher, voir section 8), les traitements longs, les connexions permanentes comme les WebSockets, et les pages où chaque milliseconde compte. Et il lie fortement l'application à un fournisseur.
8.Le coût et la dépendance au fournisseur
Le cloud se paie à l'usage. C'est sa force, et son piège : la facture dépend de choix techniques que l'on fait sans y penser. Comparons un serveur à prix fixe et du serverless facturé à la requête, avec des tarifs inventés, mais de l'ordre de grandeur de ceux des grands fournisseurs :
- Le serveur coûte 40 € par mois, et encaisse jusqu'à 20 millions de requêtes. Au-delà, il en faut un second.
- Le serverless facture 0,20 € par million d'appels, plus le temps de calcul : une requête de 200 millisecondes avec 1 Go de mémoire. Au total, environ 3,53 € par million de requêtes.
| Requêtes par mois | Serveur | Serverless |
|---|---|---|
| 100 000 | 40 € | 0,35 € |
| 1 million | 40 € | 3,53 € |
| 10 millions | 40 € | 35,33 € |
| 15 millions | 40 € | 53 € |
| 30 millions | 80 € | 106 € |
- Le coût caché le plus fréquent est le trafic sortant : les données qui quittent le cloud (vers les visiteurs, vers un autre fournisseur) sont souvent facturées au Go, alors que l'entrée est gratuite.
- Les services gérés coûtent plus cher que leur équivalent installé à la main, une base gérée par exemple. Tu paies le travail qu'ils t'évitent : sauvegardes, mises à jour, bascule en cas de panne. C'est souvent rentable, mais il faut le savoir.
- Une ressource oubliée se paie tous les mois : un environnement de test jamais éteint, un disque d'une machine supprimée. Configure des alertes de budget dès le premier jour.
- Le temps humain compte aussi : un serveur moins cher qui demande deux jours de maintenance par mois n'est pas moins cher.
Reste la dépendance au fournisseur (vendor lock-in) : plus tu utilises de services propres à un fournisseur, plus le quitter coûte cher. Tout n'est pas égal :
- Facile à déplacer : une image Docker, une base PostgreSQL, un stockage compatible S3 (la plupart des fournisseurs reprennent cette interface).
- Difficile à déplacer : une base propriétaire comme DynamoDB, des fonctions Lambda branchées sur dix services d'AWS, un système de files propre à un fournisseur.
- La souveraineté : un fournisseur américain reste soumis au droit américain, comme le Cloud Act, même pour des données stockées en France. Pour des données sensibles (santé, administration), la qualification SecNumCloud de l'ANSSI désigne des offres protégées de ces lois.
Refuser tout service propriétaire mène à tout réinstaller soi-même, et donc à se priver de ce qui fait l'intérêt du cloud. La bonne question : « si on devait partir dans deux ans, quelles parties faudrait-il réécrire, et combien de temps ? ». Si la réponse est acceptable, la dépendance l'est aussi.
Pièges fréquents
| Piège | Ce qui arrive | La parade |
|---|---|---|
| Commencer par l'architecture la plus complexe | Une facture et une charge de travail sans rapport avec le trafic | Un serveur bien tenu, puis grandir quand le besoin est mesuré |
| Ajouter un second serveur sans rendre l'application sans état | Déconnexions, fichiers introuvables, tâches en double | Sessions, fichiers, cache et verrous dans des services partagés |
| Doubler les serveurs, garder une seule base | La base reste le point unique de panne | Calculer la disponibilité de toute la chaîne |
| Une base ou un SSH joignable depuis Internet | Des tentatives d'intrusion en continu | Réseau privé, groupes de sécurité, bastion |
| Un stockage objet en lecture publique | Une fuite de toutes les données envoyées par les clients | Privé par défaut, URL signées |
| Des droits « administrateur » pour l'application | Une faille dans l'application donne tout le compte cloud | Une politique d'accès minimale par composant |
| Aucune alerte de budget | Une facture multipliée par dix découverte en fin de mois | Des alertes dès le premier jour |
| Du serverless pour un trafic élevé et constant | Plus cher qu'un serveur, et des connexions à la base saturées | Comparer les coûts avec les chiffres réels |
| Viser 99,99 % sans demander au métier | Une infrastructure très chère pour un gain que personne n'a demandé | Fixer disponibilité, RTO et RPO avec le métier |
Checklist avant de choisir une infrastructure
- Je connais le trafic actuel, ses pics, et sa croissance probable.
- La disponibilité visée, le RTO et le RPO ont été décidés avec le métier.
- L'application est sans état, ou je sais ce qu'il faut déplacer pour qu'elle le soit.
- J'ai calculé la disponibilité de toute la chaîne, base comprise.
- Seul le répartiteur est public ; les ports d'administration sont fermés à Internet.
- Chaque composant a des droits minimaux, et le compte principal est protégé par une double authentification.
- J'ai comparé les coûts avec mes chiffres, trafic sortant compris, et configuré des alertes de budget.
- Je sais quelles parties seraient à réécrire si l'on changeait de fournisseur.
Exercice : choisir une infrastructure
Trois projets, trois besoins. Pour chacun, tu vas proposer une infrastructure et la justifier par des chiffres, avec une feuille, un crayon et les règles des sections 5 et 8.
- Une association : 2 000 visites par jour, un formulaire d'inscription, un bénévole pour la technique. Une coupure d'une heure n'est pas grave.
- Une boutique en ligne : 50 000 visites par jour, dix fois plus pendant les soldes. Une heure d'arrêt un jour de soldes coûte environ 20 000 €.
- Un traitement nocturne : chaque nuit, redimensionner les photos déposées dans la journée, entre 0 et 30 000 selon les jours. Rien ne se passe le reste du temps.
Pour chaque projet :
- Choisis un modèle d'hébergement (section 6), et dis ce que tu ne veux pas gérer toi-même.
- Dessine l'architecture sur papier, comme le schéma 19.3, avec seulement les blocs nécessaires.
- Calcule sa disponibilité avec les deux règles de la section 5 (multiplier en série, 1 − (1 − a)² en parallèle), et compare-la au besoin.
- Estime son coût mensuel avec les hypothèses de la section 8, et dis où ton projet se situe sur le schéma 19.5.
- Liste ce que l'application doit changer pour devenir sans état, s'il le faut.
- Question de recul : pour la boutique, à partir de quelle durée d'arrêt par an une base de secours devient-elle rentable ?
Conseils
- Dessine avant de louer. Une architecture sur une feuille, avec une flèche par échange, révèle les points uniques de panne et les ports ouverts avant qu'ils coûtent quoi que ce soit.
- Grandis d'abord verticalement, tant que c'est possible et raisonnable : c'est souvent le moyen le plus simple de gagner du temps. Prépare quand même l'application à être sans état, ça ne coûte presque rien.
- Utilise les calculateurs de prix des fournisseurs, avec tes vrais chiffres, et relis la facture du premier mois ligne par ligne.
- Lis le cadre « Well-Architected » d'AWS, ou son équivalent chez d'autres fournisseurs : même si tu n'utilises pas AWS, ses questions sur la fiabilité, la sécurité et le coût valent pour toute infrastructure.
Documentation officielle
- Les sessions dans Symfony, dont le stockage dans Redis ou en base
- Le composant Lock et le composant Scheduler
- FlysystemBundle, pour stocker les fichiers sur S3 ou un service compatible (en anglais)
- Bref, PHP et Symfony sur AWS Lambda (en anglais)
- Le modèle de responsabilité partagée, chez AWS
- Le cadre AWS Well-Architected (en anglais)
- L'ANSSI, qui publie la liste des offres qualifiées SecNumCloud