Aller au contenu

Concepts de déploiement

🌐 Traduction par IA et humains

Cette traduction a Ă©tĂ© rĂ©alisĂ©e par une IA guidĂ©e par des humains. đŸ€

Elle peut contenir des erreurs d'interprĂ©tation du sens original, ou paraĂźtre peu naturelle, etc. đŸ€–

Vous pouvez améliorer cette traduction en nous aidant à mieux guider le LLM d'IA.

Version anglaise

Lorsque vous déployez une application FastAPI, ou en fait n'importe quel type de web API, il existe plusieurs concepts qui vous importent probablement, et en les utilisant vous pouvez trouver la maniÚre la plus appropriée de déployer votre application.

Parmi les concepts importants, on trouve :

  • SĂ©curitĂ© - HTTPS
  • ExĂ©cuter au dĂ©marrage
  • RedĂ©marrages
  • RĂ©plication (le nombre de processus en cours d'exĂ©cution)
  • MĂ©moire
  • Étapes prĂ©alables avant de dĂ©marrer

Nous allons voir comment ils affectent les déploiements.

Au final, l'objectif ultime est de pouvoir servir vos clients d'API de maniĂšre sĂ©curisĂ©e, d'Ă©viter les interruptions, et d'utiliser les ressources de calcul (par exemple des serveurs/VM distants) aussi efficacement que possible. 🚀

Je vais vous en dire un peu plus ici sur ces concepts, ce qui devrait vous donner l'intuition nĂ©cessaire pour dĂ©cider comment dĂ©ployer votre API dans des environnements trĂšs diffĂ©rents, voire mĂȘme dans des environnements futurs qui n'existent pas encore.

En tenant compte de ces concepts, vous serez en mesure d'évaluer et de concevoir la meilleure façon de déployer vos propres API.

Dans les chapitres suivants, je vous donnerai des recettes concrÚtes pour déployer des applications FastAPI.

Mais pour l'instant, voyons ces idĂ©es conceptuelles importantes. Ces concepts s'appliquent aussi Ă  tout autre type de web API. 💡

Sécurité - HTTPS

Dans le chapitre précédent à propos de HTTPS, nous avons vu comment HTTPS fournit le chiffrement pour votre API.

Nous avons également vu que HTTPS est normalement fourni par un composant externe à votre serveur d'application, un TLS Termination Proxy.

Et il doit y avoir quelque chose chargĂ© de renouveler les certificats HTTPS ; cela peut ĂȘtre le mĂȘme composant ou quelque chose de diffĂ©rent.

Exemples d’outils pour HTTPS

Parmi les outils que vous pourriez utiliser comme TLS Termination Proxy :

  • Traefik
    • GĂšre automatiquement le renouvellement des certificats ✹
  • Caddy
    • GĂšre automatiquement le renouvellement des certificats ✹
  • Nginx
    • Avec un composant externe comme Certbot pour le renouvellement des certificats
  • HAProxy
    • Avec un composant externe comme Certbot pour le renouvellement des certificats
  • Kubernetes avec un Ingress Controller comme Nginx
    • Avec un composant externe comme cert-manager pour le renouvellement des certificats
  • Pris en charge en interne par un fournisseur cloud dans le cadre de ses services (lisez ci-dessous 👇)

Une autre option consiste Ă  utiliser un service cloud qui fait davantage de travail, y compris la mise en place de HTTPS. Il peut avoir certaines restrictions ou vous facturer davantage, etc. Mais dans ce cas, vous n'auriez pas Ă  configurer vous‑mĂȘme un TLS Termination Proxy.

Je vous montrerai des exemples concrets dans les prochains chapitres.


Les concepts suivants à considérer concernent tous le programme qui exécute votre API réelle (par ex. Uvicorn).

Programme et processus

Nous allons beaucoup parler du « processus » en cours d'exĂ©cution, il est donc utile d'ĂȘtre clair sur ce que cela signifie, et sur la diffĂ©rence avec le mot « programme ».

Qu'est-ce qu'un programme

Le mot programme est couramment utilisé pour décrire plusieurs choses :

  • Le code que vous Ă©crivez, les fichiers Python.
  • Le fichier qui peut ĂȘtre exĂ©cutĂ© par le systĂšme d'exploitation, par exemple : python, python.exe ou uvicorn.
  • Un programme particulier lorsqu'il s'exĂ©cute sur le systĂšme d'exploitation, utilisant le CPU et stockant des choses en mĂ©moire. On appelle aussi cela un processus.

Qu'est-ce qu'un processus

Le mot processus est normalement utilisĂ© de maniĂšre plus spĂ©cifique, en ne se rĂ©fĂ©rant qu'Ă  l'Ă©lĂ©ment qui s'exĂ©cute dans le systĂšme d'exploitation (comme dans le dernier point ci‑dessus) :

  • Un programme particulier lorsqu'il s'exĂ©cute sur le systĂšme d'exploitation.
    • Cela ne se rĂ©fĂšre ni au fichier, ni au code ; cela se rĂ©fĂšre spĂ©cifiquement Ă  l'Ă©lĂ©ment qui est exĂ©cutĂ© et gĂ©rĂ© par le systĂšme d'exploitation.
  • N'importe quel programme, n'importe quel code, ne peut faire des choses que lorsqu'il est exĂ©cutĂ©. Donc, lorsqu'il y a un processus en cours.
  • Le processus peut ĂȘtre arrĂȘtĂ© (ou « tuĂ© ») par vous ou par le systĂšme d'exploitation. À ce moment‑lĂ , il cesse de s'exĂ©cuter/d'ĂȘtre exĂ©cutĂ©, et il ne peut plus rien faire.
  • Chaque application que vous avez en cours d'exĂ©cution sur votre ordinateur a un processus derriĂšre elle, chaque programme lancĂ©, chaque fenĂȘtre, etc. Et il y a normalement de nombreux processus exĂ©cutĂ©s en mĂȘme temps tant qu'un ordinateur est allumĂ©.
  • Il peut y avoir plusieurs processus du mĂȘme programme exĂ©cutĂ©s simultanĂ©ment.

Si vous ouvrez le « gestionnaire des tùches » ou le « moniteur systÚme » (ou des outils similaires) de votre systÚme d'exploitation, vous verrez nombre de ces processus en cours d'exécution.

Et, par exemple, vous verrez probablement qu'il y a plusieurs processus exĂ©cutant le mĂȘme navigateur (Firefox, Chrome, Edge, etc.). Ils exĂ©cutent normalement un processus par onglet, plus quelques processus supplĂ©mentaires.


Maintenant que nous connaissons la différence entre les termes processus et programme, continuons à parler des déploiements.

Exécuter au démarrage

Dans la plupart des cas, lorsque vous créez une web API, vous voulez qu'elle tourne en permanence, sans interruption, afin que vos clients puissent toujours y accéder. Bien sûr, sauf si vous avez une raison spécifique de ne vouloir l'exécuter que dans certaines situations, mais la plupart du temps vous la voulez constamment en cours et disponible.

Sur un serveur distant

Lorsque vous configurez un serveur distant (un serveur cloud, une machine virtuelle, etc.), la chose la plus simple Ă  faire est d'utiliser fastapi run (qui utilise Uvicorn) ou quelque chose de similaire, manuellement, de la mĂȘme maniĂšre que lorsque vous dĂ©veloppez en local.

Et cela fonctionnera et sera utile pendant le développement.

Mais si votre connexion au serveur est coupĂ©e, le processus en cours va probablement s'arrĂȘter.

Et si le serveur est redĂ©marrĂ© (par exemple aprĂšs des mises Ă  jour, ou des migrations chez le fournisseur cloud) vous ne le remarquerez probablement pas. Et Ă  cause de cela, vous ne saurez mĂȘme pas que vous devez redĂ©marrer le processus manuellement. Ainsi, votre API restera tout simplement Ă  l'arrĂȘt. đŸ˜±

Lancer automatiquement au démarrage

En général, vous voudrez probablement que le programme serveur (par ex. Uvicorn) soit démarré automatiquement au démarrage du serveur, et sans aucune intervention humaine, afin d'avoir en permanence un processus exécutant votre API (par ex. Uvicorn exécutant votre app FastAPI).

Programme séparé

Pour y parvenir, vous aurez normalement un programme séparé qui s'assure que votre application est lancée au démarrage. Et dans de nombreux cas, il s'assurera également que d'autres composants ou applications sont également lancés, par exemple une base de données.

Exemples d’outils pour lancer au dĂ©marrage

Voici quelques exemples d'outils capables de faire ce travail :

  • Docker
  • Kubernetes
  • Docker Compose
  • Docker en mode Swarm
  • Systemd
  • Supervisor
  • Pris en charge en interne par un fournisseur cloud dans le cadre de ses services
  • Autres ...

Je vous donnerai des exemples plus concrets dans les prochains chapitres.

Redémarrages

De la mĂȘme maniĂšre que vous voulez vous assurer que votre application est lancĂ©e au dĂ©marrage, vous voulez probablement aussi vous assurer qu'elle est redĂ©marrĂ©e aprĂšs des Ă©checs.

Nous faisons des erreurs

Nous, humains, faisons des erreurs, tout le temps. Les logiciels ont presque toujours des bugs cachĂ©s Ă  diffĂ©rents endroits. 🐛

Et nous, dĂ©veloppeurs, continuons Ă  amĂ©liorer le code au fur et Ă  mesure que nous trouvons ces bugs et que nous implĂ©mentons de nouvelles fonctionnalitĂ©s (en ajoutant Ă©ventuellement de nouveaux bugs aussi 😅).

Petites erreurs gérées automatiquement

Lors de la crĂ©ation de web API avec FastAPI, s'il y a une erreur dans notre code, FastAPI la contiendra normalement Ă  la seule requĂȘte qui a dĂ©clenchĂ© l'erreur. 🛡

Le client recevra un 500 Internal Server Error pour cette requĂȘte, mais l'application continuera de fonctionner pour les requĂȘtes suivantes au lieu de simplement s'effondrer complĂštement.

Erreurs plus importantes - plantages

NĂ©anmoins, il peut y avoir des cas oĂč nous Ă©crivons du code qui fait planter l'application entiĂšre, faisant planter Uvicorn et Python. đŸ’„

Et malgrĂ© cela, vous ne voudrez probablement pas que l'application reste Ă  l'arrĂȘt parce qu'il y a eu une erreur Ă  un endroit ; vous voudrez probablement qu'elle continue de tourner, au moins pour les chemins d'accĂšs qui ne sont pas cassĂ©s.

Redémarrer aprÚs un plantage

Mais dans ces cas avec de trÚs mauvaises erreurs qui font planter le processus en cours, vous voudrez un composant externe chargé de redémarrer le processus, au moins quelques fois ...

Astuce

... Bien que si l'application entiÚre plante immédiatement, il n'est probablement pas logique de continuer à la redémarrer indéfiniment. Mais dans ces cas, vous le remarquerez probablement pendant le développement, ou au moins juste aprÚs le déploiement.

Concentrons‑nous donc sur les cas principaux, oĂč elle pourrait planter entiĂšrement dans certaines situations particuliĂšres Ă  l'avenir, et oĂč il est toujours logique de la redĂ©marrer.

Vous voudrez probablement que l'Ă©lĂ©ment chargĂ© de redĂ©marrer votre application soit un composant externe, car Ă  ce stade, l'application elle‑mĂȘme avec Uvicorn et Python a dĂ©jĂ  plantĂ©, donc il n'y a rien dans le mĂȘme code de la mĂȘme app qui pourrait y faire quoi que ce soit.

Exemples d’outils pour redĂ©marrer automatiquement

Dans la plupart des cas, le mĂȘme outil qui est utilisĂ© pour lancer le programme au dĂ©marrage est Ă©galement utilisĂ© pour gĂ©rer les redĂ©marrages automatiques.

Par exemple, cela peut ĂȘtre gĂ©rĂ© par :

  • Docker
  • Kubernetes
  • Docker Compose
  • Docker en mode Swarm
  • Systemd
  • Supervisor
  • Pris en charge en interne par un fournisseur cloud dans le cadre de ses services
  • Autres ...

Réplication - Processus et mémoire

Avec une application FastAPI, en utilisant un programme serveur comme la commande fastapi qui exécute Uvicorn, l'exécuter une fois dans un processus peut servir plusieurs clients simultanément.

Mais dans de nombreux cas, vous voudrez exĂ©cuter plusieurs processus de travail en mĂȘme temps.

Multiples processus - Workers

Si vous avez plus de clients que ce qu'un seul processus peut gĂ©rer (par exemple si la machine virtuelle n'est pas trĂšs grande) et que vous avez plusieurs cƓurs dans le CPU du serveur, alors vous pouvez avoir plusieurs processus exĂ©cutant la mĂȘme application simultanĂ©ment, et distribuer toutes les requĂȘtes entre eux.

Quand vous exĂ©cutez plusieurs processus du mĂȘme programme d'API, on les appelle couramment des workers.

Processus workers et ports

Rappelez‑vous, d'aprĂšs les documents À propos de HTTPS, qu'un seul processus peut Ă©couter une combinaison de port et d'adresse IP sur un serveur ?

C'est toujours vrai.

Donc, pour pouvoir avoir plusieurs processus en mĂȘme temps, il doit y avoir un seul processus Ă  l'Ă©coute sur un port qui transmet ensuite la communication Ă  chaque processus worker d'une maniĂšre ou d'une autre.

Mémoire par processus

Maintenant, lorsque le programme charge des choses en mémoire, par exemple, un modÚle de machine learning dans une variable, ou le contenu d'un gros fichier dans une variable, tout cela consomme une partie de la mémoire (RAM) du serveur.

Et plusieurs processus ne partagent normalement pas de mémoire. Cela signifie que chaque processus en cours a ses propres éléments, variables et mémoire. Et si vous consommez une grande quantité de mémoire dans votre code, chaque processus consommera une quantité équivalente de mémoire.

Mémoire du serveur

Par exemple, si votre code charge un modÚle de Machine Learning de 1 Go, lorsque vous exécutez un processus avec votre API, il consommera au moins 1 Go de RAM. Et si vous démarrez 4 processus (4 workers), chacun consommera 1 Go de RAM. Donc au total, votre API consommera 4 Go de RAM.

Et si votre serveur distant ou votre machine virtuelle n'a que 3 Go de RAM, essayer de charger plus de 4 Go de RAM posera problùme. 🚹

Multiples processus - Un exemple

Dans cet exemple, il y a un processus gestionnaire qui démarre et contrÎle deux processus workers.

Ce processus gestionnaire serait probablement celui qui écoute sur le port de l'IP. Et il transmettrait toute la communication aux processus workers.

Ces processus workers seraient ceux qui exĂ©cutent votre application, ils effectueraient les calculs principaux pour recevoir une requĂȘte et renvoyer une rĂ©ponse, et ils chargeraient tout ce que vous mettez dans des variables en RAM.

Et bien sĂ»r, la mĂȘme machine aurait probablement d'autres processus en cours d'exĂ©cution Ă©galement, en plus de votre application.

Un détail intéressant est que le pourcentage de CPU utilisé par chaque processus peut varier fortement dans le temps, mais la mémoire (RAM) reste normalement plus ou moins stable.

Si vous avez une API qui effectue une quantité comparable de calculs à chaque fois et que vous avez beaucoup de clients, alors l'utilisation du CPU sera probablement également stable (au lieu de monter et descendre rapidement en permanence).

Exemples d’outils et de stratĂ©gies de rĂ©plication

Il peut y avoir plusieurs approches pour y parvenir, et je vous en dirai plus sur des stratégies spécifiques dans les prochains chapitres, par exemple en parlant de Docker et des conteneurs.

La principale contrainte à considérer est qu'il doit y avoir un seul composant gérant le port sur l'IP publique. Et il doit ensuite avoir un moyen de transmettre la communication aux processus/workers répliqués.

Voici quelques combinaisons et stratégies possibles :

  • Uvicorn avec --workers
    • Un gestionnaire de processus Uvicorn Ă©couterait sur l'IP et le port, et il dĂ©marrerait plusieurs processus workers Uvicorn.
  • Kubernetes et autres systĂšmes de conteneurs distribuĂ©s
    • Quelque chose dans la couche Kubernetes Ă©couterait sur l'IP et le port. La rĂ©plication se ferait en ayant plusieurs conteneurs, chacun avec un processus Uvicorn en cours.
  • Services cloud qui s'en chargent pour vous
    • Le service cloud gĂ©rera probablement la rĂ©plication pour vous. Il vous permettra Ă©ventuellement de dĂ©finir un processus Ă  exĂ©cuter, ou une image de conteneur Ă  utiliser ; dans tous les cas, ce sera trĂšs probablement un seul processus Uvicorn, et le service cloud sera chargĂ© de le rĂ©pliquer.

Astuce

Ne vous inquiétez pas si certains de ces éléments concernant les conteneurs, Docker ou Kubernetes ne sont pas encore trÚs clairs.

Je vous en dirai plus sur les images de conteneurs, Docker, Kubernetes, etc. dans un chapitre Ă  venir : FastAPI dans des conteneurs - Docker.

Étapes prĂ©alables avant de dĂ©marrer

Il existe de nombreux cas oĂč vous souhaitez effectuer certaines Ă©tapes avant de dĂ©marrer votre application.

Par exemple, vous pourriez vouloir exécuter des migrations de base de données.

Mais dans la plupart des cas, vous voudrez effectuer ces étapes une seule fois.

Vous voudrez donc avoir un processus unique pour effectuer ces étapes préalables, avant de démarrer l'application.

Et vous devez vous assurer que c'est un processus unique qui exĂ©cute ces Ă©tapes prĂ©alables mĂȘme si, ensuite, vous dĂ©marrez plusieurs processus (plusieurs workers) pour l'application elle‑mĂȘme. Si ces Ă©tapes Ă©taient exĂ©cutĂ©es par plusieurs processus, ils dupliqueraient le travail en l'exĂ©cutant en parallĂšle, et si les Ă©tapes Ă©taient dĂ©licates comme une migration de base de donnĂ©es, elles pourraient entrer en conflit les unes avec les autres.

Bien sĂ»r, il y a des cas oĂč il n'y a aucun problĂšme Ă  exĂ©cuter les Ă©tapes prĂ©alables plusieurs fois ; dans ce cas, c'est beaucoup plus simple Ă  gĂ©rer.

Astuce

Gardez aussi Ă  l'esprit que selon votre configuration, dans certains cas vous n'aurez peut‑ĂȘtre mĂȘme pas besoin d'Ă©tapes prĂ©alables avant de dĂ©marrer votre application.

Dans ce cas, vous n'auriez pas Ă  vous soucier de tout cela. đŸ€·

Exemples de stratégies pour les étapes préalables

Cela dépendra fortement de la maniÚre dont vous déployez votre systÚme, et sera probablement lié à votre maniÚre de démarrer les programmes, de gérer les redémarrages, etc.

Voici quelques idées possibles :

  • Un « Init Container » dans Kubernetes qui s'exĂ©cute avant votre conteneur d'application
  • Un script bash qui exĂ©cute les Ă©tapes prĂ©alables puis dĂ©marre votre application
    • Vous aurez toujours besoin d'un moyen de dĂ©marrer/redĂ©marrer ce script bash, de dĂ©tecter les erreurs, etc.

Astuce

Je vous donnerai des exemples plus concrets pour faire cela avec des conteneurs dans un chapitre Ă  venir : FastAPI dans des conteneurs - Docker.

Utilisation des ressources

Votre ou vos serveurs constituent une ressource que vos programmes peuvent consommer ou utiliser : le temps de calcul des CPU et la mémoire RAM disponible.

Quelle quantitĂ© des ressources systĂšme voulez‑vous consommer/utiliser ? Il peut ĂȘtre facile de penser « pas beaucoup », mais en rĂ©alitĂ©, vous voudrez probablement consommer le plus possible sans planter.

Si vous payez pour 3 serveurs mais que vous n'utilisez qu'un petit peu de leur RAM et CPU, vous gaspillez probablement de l'argent 💾, et gaspillez probablement l'Ă©lectricitĂ© des serveurs 🌎, etc.

Dans ce cas, il pourrait ĂȘtre prĂ©fĂ©rable de n'avoir que 2 serveurs et d'utiliser un pourcentage plus Ă©levĂ© de leurs ressources (CPU, mĂ©moire, disque, bande passante rĂ©seau, etc.).

À l'inverse, si vous avez 2 serveurs et que vous utilisez 100 % de leur CPU et de leur RAM, Ă  un moment donnĂ© un processus demandera plus de mĂ©moire, et le serveur devra utiliser le disque comme « mĂ©moire » (ce qui peut ĂȘtre des milliers de fois plus lent), voire planter. Ou un processus pourrait avoir besoin de faire un calcul et devrait attendre que le CPU soit Ă  nouveau libre.

Dans ce cas, il serait préférable d'obtenir un serveur supplémentaire et d'y exécuter certains processus afin qu'ils aient tous suffisamment de RAM et de temps CPU.

Il est Ă©galement possible que, pour une raison quelconque, vous ayez un pic d'utilisation de votre API. Peut‑ĂȘtre qu'elle devient virale, ou peut‑ĂȘtre que d'autres services ou bots commencent Ă  l'utiliser. Et vous voudrez peut‑ĂȘtre disposer de ressources supplĂ©mentaires pour ĂȘtre en sĂ©curitĂ© dans ces cas.

Vous pouvez définir un chiffre arbitraire comme cible, par exemple entre 50 % et 90 % d'utilisation des ressources. L'idée est que ce sont probablement les principaux éléments que vous voudrez mesurer et utiliser pour ajuster vos déploiements.

Vous pouvez utiliser des outils simples comme htop pour voir le CPU et la RAM utilisés sur votre serveur ou la quantité utilisée par chaque processus. Ou vous pouvez utiliser des outils de supervision plus complexes, éventuellement distribués sur plusieurs serveurs, etc.

Récapitulatif

Vous venez de lire ici certains des principaux concepts que vous devrez probablement garder à l'esprit lorsque vous décidez comment déployer votre application :

  • SĂ©curitĂ© - HTTPS
  • ExĂ©cuter au dĂ©marrage
  • RedĂ©marrages
  • RĂ©plication (le nombre de processus en cours d'exĂ©cution)
  • MĂ©moire
  • Étapes prĂ©alables avant de dĂ©marrer

Comprendre ces idĂ©es et comment les appliquer devrait vous donner l'intuition nĂ©cessaire pour prendre toutes les dĂ©cisions lors de la configuration et de l'ajustement de vos dĂ©ploiements. đŸ€“

Dans les sections suivantes, je vous donnerai des exemples plus concrets de stratĂ©gies possibles Ă  suivre. 🚀