{"id":593222,"date":"2025-08-19T08:10:38","date_gmt":"2025-08-19T07:10:38","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=pycharm&#038;p=593222"},"modified":"2025-10-16T10:58:39","modified_gmt":"2025-10-16T09:58:39","slug":"deploiement-d-applications-django-dans-kubernetes","status":"publish","type":"pycharm","link":"https:\/\/blog.jetbrains.com\/fr\/pycharm\/2025\/08\/deploiement-d-applications-django-dans-kubernetes\/","title":{"rendered":"D\u00e9ploiement d&#8217;applications Django dans Kubernetes"},"content":{"rendered":"<p>En tant que plateforme d&#8217;orchestration de conteneurs open source automatisant le d\u00e9ploiement, la mise \u00e0 l&#8217;\u00e9chelle et l&#8217;\u00e9quilibrage de charge, Kubernetes offre une r\u00e9silience et une flexibilit\u00e9 in\u00e9gal\u00e9es pour la gestion de vos applications Django<strong>. <\/strong><\/p>\n<p>Qu&#8217;il s&#8217;agisse de lancer un projet \u00e0 petite \u00e9chelle ou de g\u00e9rer une application complexe, Kubernetes fournit un environnement robuste pour am\u00e9liorer votre application Django en garantissant qu&#8217;elle r\u00e9ponde aux exigences du d\u00e9veloppement web moderne.<\/p>\n<p>En automatisant le d\u00e9ploiement, la mise \u00e0 l&#8217;\u00e9chelle et la gestion des applications conteneuris\u00e9es, <a href=\"https:\/\/kubernetes.io\/\" target=\"_blank\" rel=\"noopener\">Kubernetes<\/a> (ou K8s) pr\u00e9sente de nombreux avantages pour les organisations du secteur fortement \u00e9volutif de la tech.<\/p>\n<p>Que vous soyez un d\u00e9veloppeur Django cherchant \u00e0 am\u00e9liorer ses comp\u00e9tences de d\u00e9ploiement ou un fan de Kubernetes qui souhaite explorer l&#8217;int\u00e9gration de Django, ce guide est fait pour vous.<\/p>\n<p><!--more--><\/p>\n<p>L&#8217;introduction de ce tutoriel traite de la relation symbiotique entre Django et Kubernetes, qui vous permet de cr\u00e9er de conteneuriser de mani\u00e8re fluide transparente votre application web, de r\u00e9partir les charges de travail sur les clusters et de garantir une haute disponibilit\u00e9.<\/p>\n<h2 class=\"wp-block-heading\">Django<\/h2>\n<p>Le framework Django, un framework web Python de haut niveau, se distingue par son efficacit\u00e9 et sa simplicit\u00e9 dans le domaine du d\u00e9veloppement web. Con\u00e7u pour cr\u00e9er des applications web rapides, robustes et faciles \u00e0 maintenir, Django est devenu une r\u00e9f\u00e9rence pour les d\u00e9veloppeurs et les organisations.<\/p>\n<p>Fondamentalement, Django a une approche \u00ab\u00a0batteries-included\u00a0\u00bb, qui offre un ensemble \u00e9tendu d&#8217;outils int\u00e9gr\u00e9s, de biblioth\u00e8ques et de conventions qui facilitent le processus de d\u00e9veloppement. Il simplifie les t\u00e2ches complexes comme le routage d&#8217;URL, l&#8217;int\u00e9gration des bases de donn\u00e9es et l&#8217;authentification des utilisateurs, ce qui permet aux d\u00e9veloppeurs de se concentrer sur la cr\u00e9ation de leurs applications.<\/p>\n<p>L&#8217;un des principaux avantages de Django r\u00e9side dans son principe \u00ab\u00a0Ne vous r\u00e9p\u00e9tez pas\u00a0\u00bb (Don&#8217;t repeat yourself, DRY), qui r\u00e9duit les redondances et facilite la maintenance du code. Il applique \u00e9galement l&#8217;architecture mod\u00e8le-vue-contr\u00f4leur (model-view-controller, MVC), ce qui permet d&#8217;obtenir des applications structur\u00e9es et faciles \u00e0 g\u00e9rer.<\/p>\n<p>Django donne \u00e9galement la priorit\u00e9 \u00e0 la s\u00e9curit\u00e9, en r\u00e9duisant l&#8217;exposition aux vuln\u00e9rabilit\u00e9s web les plus courantes. Il inclut d\u00e8s le d\u00e9part des fonctionnalit\u00e9s telles que la protection contre les scripts intersites (XSS) et la falsification de requ\u00eates intersites (CSRF). Offrant une combinaison puissante de vitesse, de simplicit\u00e9 et de s\u00e9curit\u00e9, Django est un choix id\u00e9al pour les d\u00e9veloppeurs souhaitant cr\u00e9er facilement des applications web robustes et riches en fonctionnalit\u00e9s.<\/p>\n<h2 class=\"wp-block-heading\">Orchestrateurs de conteneurs<\/h2>\n<p>Les orchestrateurs de conteneurs sont des outils essentiels pour g\u00e9rer et automatiser le d\u00e9ploiement, la mise \u00e0 l&#8217;\u00e9chelle et la gestion des applications conteneuris\u00e9es. Plusieurs orchestrateurs de conteneurs sont disponibles sur le march\u00e9, les plus populaires \u00e9tant\u00a0:<\/p>\n<p>1. <strong>Kubernetes<\/strong>, cette plateforme d&#8217;orchestration de conteneurs open source tr\u00e8s appr\u00e9ci\u00e9e offre un environnement robuste et adaptable pour g\u00e9rer les applications conteneuris\u00e9es. Elle automatise des t\u00e2ches telles que la mise \u00e0 l&#8217;\u00e9chelle, l&#8217;\u00e9quilibrage de charge et la v\u00e9rification de l&#8217;\u00e9tat des conteneurs gr\u00e2ce \u00e0 un vaste \u00e9cosyst\u00e8me d&#8217;extensions.<\/p>\n<p>2. <strong>Docker Swarm<\/strong> est une solution d&#8217;orchestration de conteneurs propos\u00e9e par Docker. Con\u00e7ue pour \u00eatre simple \u00e0 configurer et \u00e0 utiliser, c&#8217;est un bon choix pour les applications les plus simples ou les organisations utilisant d\u00e9j\u00e0 Docker, car elle utilise la m\u00eame interface de ligne de commande et la m\u00eame API que Docker.<\/p>\n<p>3. <strong>OpenShift<\/strong> est une plateforme Kubernetes d&#8217;entreprise d\u00e9velopp\u00e9e par Red Hat. Elle ajoute des outils de d\u00e9veloppement et d&#8217;op\u00e9rations \u00e0 Kubernetes, ce qui simplifie le d\u00e9ploiement et la gestion des applications conteneuris\u00e9es.<\/p>\n<p>4. <strong>Nomad<\/strong>, d\u00e9velopp\u00e9 par HashiCorp, est un orchestrateur l\u00e9ger et convivial permettant de g\u00e9rer \u00e0 la fois les applications conteneuris\u00e9es et non conteneuris\u00e9es.<\/p>\n<p>5. <strong>Apache Mesos <\/strong>est un noyau de syst\u00e8me distribu\u00e9 open source et DC\/OS (Data Center Operating System) est une plateforme d&#8217;entreprise construite sur Mesos. DC\/OS \u00e9tend les fonctionnalit\u00e9s de Mesos pour la gestion et la mise \u00e0 l&#8217;\u00e9chelle des applications conteneuris\u00e9es.<\/p>\n<p>Les \u00e9quipes de d\u00e9veloppement logiciel travaillent principalement avec les plateformes g\u00e9r\u00e9es propos\u00e9es par des fournisseurs cloud reconnus tels que AWS, Google Cloud Platform et Azure. Ces fournisseurs cloud offrent des services comme Amazon EKS, Google GKE et Azure AKS, qui sont toutes des solutions Kubernetes g\u00e9r\u00e9es. Ces services simplifient la configuration, l&#8217;expansion et l&#8217;administration des clusters Kubernetes et permettent de les int\u00e9grer facilement avec les environnements cloud respectifs afin d&#8217;assurer une orchestration efficace des conteneurs et du d\u00e9ploiement des applications.<\/p>\n<h2 class=\"wp-block-heading\">Cr\u00e9er une application Django dans PyCharm<\/h2>\n<p>Dans ce tutoriel, nous allons commencer par g\u00e9n\u00e9rer une application Django minimaliste. Nous allons ensuite conteneuriser cette application, et pour finir, nous la d\u00e9ployer sur un cluster Kubernetes local en utilisant Docker Desktop.<\/p>\n<p>Si vous d\u00e9couvrez le framework Django et souhaitez savoir comment cr\u00e9er une application Django \u00e0 partir de 0, lisez cet <a href=\"https:\/\/blog.jetbrains.com\/pycharm\/2023\/04\/create-a-django-app-in-pycharm\/\">article de blog<\/a>.<\/p>\n<p>Vous pouvez acc\u00e9der au code source utilis\u00e9 dans ce tutoriel <a href=\"https:\/\/github.com\/mukulmantosh\/django-kubernetes\" target=\"_blank\" rel=\"noopener\">ici<\/a>.<\/p>\n<p>Commen\u00e7ons en cr\u00e9ant une nouvelle <a href=\"https:\/\/blog.jetbrains.com\/pycharm\/2023\/04\/create-a-django-app-in-pycharm\/\">application Django dans PyCharm<\/a>.<\/p>\n<div class=\"buttons\">\n<div class=\"buttons__row\"><a class=\"btn\" href=\"https:\/\/www.jetbrains.com\/fr-fr\/pycharm\/web-development\/django\/\" target=\"\" rel=\"noopener\">Essayer PyCharm Pro gratuitement<\/a><\/div>\n<\/div>\n<p>Pour cr\u00e9er votre projet, lancez PyCharm et cliquez sur <strong>New Project<\/strong>. Si PyCharm est d\u00e9j\u00e0 lanc\u00e9, s\u00e9lectionnez <strong>File | New Project<\/strong> dans le menu principal.<\/p>\n<p>Fournissez les informations essentielles, telles que le nom du projet, l&#8217;emplacement et le type d&#8217;interpr\u00e9teur, en utilisant <a href=\"https:\/\/docs.python.org\/3\/library\/venv.html\" target=\"_blank\" rel=\"noopener\">venv<\/a> ou un environnement personnalis\u00e9.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/1y08c3RPd7rqmf5qxcZfrWrzDAekMhwhPIWRa10ipnziCXebOqe8WsMfTXG55efz48CBi5eF_zg7clWjfrHI843CGaueY1wwvBZ0qeei_umc2hAPhLtfuEh0DdLF3NKoSW2iPGbpUCtsEzlF5NKUj0o-2.png\" width=\"624\" height=\"465\" \/><\/p>\n<p>Cliquez ensuite sur <strong>Create<\/strong>.<\/p>\n<p>PyCharm se chargera de la plus grande partie de la configuration du projet et de la cr\u00e9ation de l&#8217;environnement virtuel.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/odWqcTk4mIote11wJzVTV42umN0Ffu_aSMfv9RRVQs2V9BYcL9_q6dSz-e56unGs-HkDc5GrogOvGqDWJNS3FgYOG7MFAcrXAa6U54Fca1nd9aXo8MjUye5_42sEXIb11rTKyiCAWQWPehKrBeyVMT4-1.png\" width=\"624\" height=\"351\" \/><\/p>\n<h3 class=\"wp-block-heading\">Gunicorn<\/h3>\n<p>Une fois le projet cr\u00e9\u00e9, installez <a href=\"https:\/\/gunicorn.org\/\" target=\"_blank\" rel=\"noopener\">Gunicorn<\/a>\u00a0; il s&#8217;agit d&#8217;un serveur web HTTP WSGI populaire \u00e9crit en Python. Gunicorn est un serveur web bas\u00e9 sur le mod\u00e8le des workers pr\u00e9-fork qui est tr\u00e8s sollicit\u00e9 pour servir des applications web en Python. Il est souvent utilis\u00e9 en conjonction avec des frameworks web tels que Django, Flask et autres pour d\u00e9ployer des applications web et les rendre accessibles sur Internet.<\/p>\n<p>La fen\u00eatre d&#8217;outils <strong>Python Packages<\/strong> fournit le moyen le plus rapide et simple pour obtenir un aper\u00e7u des packages et les installer pour l&#8217;interpr\u00e9teur Python actuellement s\u00e9lectionn\u00e9.<\/p>\n<p>Vous pouvez ouvrir la fen\u00eatre d&#8217;outils via <strong>View | Tool Windows | Python Packages<\/strong>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/srzllJqDAcLfQmEuJcLcizPVMAGYJGJ4Y5YnAXyT35Q0ntHxXgZgWu0bkviI6RgnVJAyQltuEnmFqnR0nyTtdaJ3oBJc9ofrEnG0HmzsfXz-_kBMiMGb_YzPBJ_pyMtP-RWRBUBGtUihUPKW4CBQPi8-1.png\" width=\"624\" height=\"187\" \/><\/p>\n<h3 class=\"wp-block-heading\">Psycopg 2<\/h3>\n<p><a href=\"https:\/\/www.psycopg.org\/docs\/\" target=\"_blank\" rel=\"noopener\">Psycopg 2<\/a> est une biblioth\u00e8que Python servant \u00e0 se connecter aux bases de donn\u00e9es PostgreSQL et \u00e0 interagir avec elles. Il fournit une interface Python pour travailler avec PostgreSQL, l&#8217;un des SGBDR open source les plus populaires. Psycopg 2 permet aux d\u00e9veloppeurs Python d&#8217;ex\u00e9cuter diff\u00e9rentes op\u00e9rations avec les bases de donn\u00e9es, telles que l&#8217;insertion, la mise \u00e0 jour et l&#8217;extraction de donn\u00e9es, ainsi que l&#8217;ex\u00e9cution de requ\u00eates SQL et la gestion de connexions de bases de donn\u00e9es \u00e0 partir de programmes en Python.<\/p>\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-452825\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/03\/image-7.png\" alt=\"\" width=\"1273\" height=\"455\" \/><\/figure>\n<p>Avant d&#8217;installer <code>psycopg2<\/code>, assurez-vous d&#8217;installer les d\u00e9pendances syst\u00e8me\u00a0: <code>brew install libpq<\/code> pour macOS et <code>apt-get install libpq-dev<\/code> pour Linux.<\/p>\n<p>R\u00e9f\u00e9rence\u00a0: <a href=\"https:\/\/www.postgresql.org\/docs\/16\/libpq.html\" target=\"_blank\" rel=\"noopener\">postgresql.org\/docs\/16\/libpq.html<\/a><\/p>\n<p><code>libpq<\/code> est la biblioth\u00e8que client pour PostgreSQL. Il s&#8217;agit d&#8217;une biblioth\u00e8que C qui r\u00e9unit toutes les fonctionnalit\u00e9s n\u00e9cessaires pour que les applications client se connectent aux serveurs de bases de donn\u00e9es PostgreSQL, afin d&#8217;interagir avec eux ou de les g\u00e9rer.<\/p>\n<p>Une fois les modifications termin\u00e9es, mettez \u00e0 jour la section de <code>settings.py<\/code> qui se rapporte \u00e0 <code>DATABASES<\/code>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/qpVWdOZBeTsiOkfJIMn4VybYiIS99u_XxR5_6yYhbLNNI3WpMUwmHTk2g7oaQ1o03GXdY7Y23TtHzNM6ht9-onbAVwvPZ06qgVoIAlpuJjddtuHWJhtr9DO3R8I4PHKCM8vBHvPut02m_k6m_vfQ2uc-1.png\" width=\"624\" height=\"220\" \/><\/p>\n<p>Veillez \u00e0 transf\u00e9rer les informations d&#8217;authentification secr\u00e8tes au moyen des variables d&#8217;environnement.<\/p>\n<h3 class=\"wp-block-heading\">STATIC_ROOT<\/h3>\n<p>Dans Django, <code>STATIC_ROOT<\/code> est un param\u00e8tre de configuration permettant de sp\u00e9cifier le chemin absolu des fichiers syst\u00e8me o\u00f9 les fichiers statiques collect\u00e9s seront stock\u00e9s lorsque vous ex\u00e9cutez la commande de gestion <code>collectstatic<\/code>. Les fichiers statiques incluent g\u00e9n\u00e9ralement CSS, JavaScript, les images et autres ressources de votre application web. Le param\u00e8tre <code>STATIC_ROOT<\/code> est un \u00e9l\u00e9ment essentiel des serveurs de fichiers statiques dans un environnement de production.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/D-VP39aKKQITKIi2IG_T6hBWEvUCDzTaLfbrDofs-JlOHmFP51Vl2QYH6dmpufWRhgUTPoOtmyKBj155vIGL8DqWyiR79W3NdiYibTb228Yx2Tj0pwC5bPd5F6BCtbMbTvfKHJ6lDYBlmbLqv1jUmoA-1.png\" width=\"624\" height=\"323\" \/><\/p>\n<p>D\u00e9finissez une variable d&#8217;environnement pour <code>STATIC_ROOT<\/code> \u00e0 la ligne 127. Cette variable pointe vers un chemin de fichier qui m\u00e8ne \u00e0 un PersistentVolume Kubernetes. J&#8217;expliquerai plus tard comment cr\u00e9er cette configuration.<\/p>\n<p>Pour collecter les fichiers statiques, ex\u00e9cutez la commande suivante\u00a0:<\/p>\n<p><code>python manage.py collectstatic<\/code><\/p>\n<p>Cette commande regroupera les fichiers statiques et les placera dans le r\u00e9pertoire <code>STATIC_ROOT<\/code>. Vous pouvez ensuite servir ces ressources directement avec un serveur web NGINX ou Apache, car cela constitue une approche plus efficace pour les environnements de production.<\/p>\n<h3 class=\"wp-block-heading\">Dockerfile<\/h3>\n<p>Un Dockerfile est un simple document texte contenant des directives de construction des images Docker.<\/p>\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-452658\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/03\/image-4.png\" alt=\"\" width=\"1600\" height=\"636\" \/><\/figure>\n<p>1. <strong><code>FROM python:3.11<\/code><\/strong>\u00a0: cette ligne sp\u00e9cifie l&#8217;image de base pour l&#8217;image Docker utilisant l&#8217;image Python 3.11 officielle de Docker Hub. L&#8217;application sera construite et ex\u00e9cut\u00e9e sur la base de cette image, dans laquelle Python est pr\u00e9-install\u00e9.<\/p>\n<p>2. <strong><code>ENV PYTHONUNBUFFERED 1<\/code><\/strong>\u00a0: cette ligne d\u00e9finit la variable d&#8217;environnement <code>PYTHONUNBUFFERED<\/code> sur <code>1<\/code>. Il est souvent recommand\u00e9 de d\u00e9finir cette variable d&#8217;environnement lors de l&#8217;ex\u00e9cution de Python dans des conteneurs Docker pour s&#8217;assurer que Python ne place pas la sortie en m\u00e9moire tampon. Cela facilite l&#8217;obtention de fichiers journaux en temps r\u00e9el et le d\u00e9bogage des informations \u00e0 partir de l&#8217;application.<\/p>\n<p>3. <strong><code>WORKDIR \/app<\/code><\/strong>\u00a0: cette ligne d\u00e9finit le r\u00e9pertoire de travail du conteneur Docker sur <code>\/app<\/code>. Toutes les commandes suivantes seront ex\u00e9cut\u00e9es dans ce r\u00e9pertoire.<\/p>\n<p>4. <strong><code>COPY . \/app<\/code><\/strong>\u00a0: cette ligne copie le contenu du r\u00e9pertoire actif (celui o\u00f9 se trouve le Dockerfile) dans le r\u00e9pertoire <code>\/app<\/code> du conteneur. Cela inclut le code de votre application et tous les fichiers n\u00e9cessaires pour l&#8217;image Docker.<\/p>\n<p>5. <strong><code>RUN pip install -r requirements.txt<\/code><\/strong>\u00a0: cette ligne ex\u00e9cute la commande <code>pip install<\/code> pour installer les d\u00e9pendances Python figurant dans le fichier <code>requirements.txt<\/code> situ\u00e9 dans le r\u00e9pertoire <code>\/app<\/code>. Il s&#8217;agit d&#8217;une pratique courante pour les applications Python, car elle permet de g\u00e9rer les d\u00e9pendances de l&#8217;application.<\/p>\n<p>6. <strong><code>EXPOSE 8000<\/code><\/strong>\u00a0: cette ligne informe Docker que le conteneur \u00e9coute sur le port 8000. Elle ne publie pas le port. Il s&#8217;agit d&#8217;une d\u00e9claration de m\u00e9tadonn\u00e9es qui indique les ports que le conteneur peut utiliser.<\/p>\n<p>7. <strong><code>CMD [\"gunicorn\", \"django_kubernetes_tutorial.wsgi:application\", \"--bind\", \"0.0.0.0:8000\"]<\/code><\/strong>\u00a0: cette ligne sp\u00e9cifie la commande par d\u00e9faut \u00e0 ex\u00e9cuter lors du d\u00e9marrage du conteneur. Elle utilise Gunicorn pour servir l&#8217;application Django et force Gunicorn \u00e0 \u00e9couter toutes les interfaces r\u00e9seau (<code>0.0.0.0<\/code>) sur le port 8000 en utilisant l&#8217;application WSGI d\u00e9finie dans <code>django_kubernetes_tutorial.wsgi:application<\/code>.<\/p>\n<h3 class=\"wp-block-heading\">DockerHub<\/h3>\n<p>Ouvrez la page <a href=\"http:\/\/hub.docker.com\" target=\"_blank\" rel=\"noopener\">hub.docker.com<\/a> et connectez ou inscrivez-vous sur la plateforme.<\/p>\n<p>Cliquez sur <strong>Create repository<\/strong>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/j6njSAI3cnn1FeazOY-aKjKXXZPQXnTi7tzWC4hK2-FSZ-oUj3vz3oc2yOYFsGyvWbKZZ9B3nAMOLAA4r68yN6GEJFjsGccTMvWW1ph26pXKCpcPkzJjLwBJMC5J_kUXiKVzlSg6ZatV5tol2QXjlnw-1.png\" width=\"624\" height=\"432\" \/><\/p>\n<p>Ensuite, fournissez le nom du r\u00e9f\u00e9rentiel et d\u00e9finissez la visibilit\u00e9 sur publique. Si vous manipulez des informations sensibles ou confidentielles, d\u00e9finissez la visibilit\u00e9 sur <strong>priv\u00e9e<\/strong>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/Vj1dqmm0ro7S-McOV4FwMNyc2sWoZ-mVmiD0TbptoeAyK44vbSvJIXcRrvcUxcw_CxPtt_Q3R0VTzkLlpuEUdKiM9Po1ZGbTwZFfJgo7yCkRV2Vzjck_q52H4lUcABbHLOE0FvdDZagx1dvHveEkvgc.png\" width=\"624\" height=\"453\" \/><\/p>\n<p>Une fois le r\u00e9f\u00e9rentiel cr\u00e9\u00e9, vous devez cr\u00e9er l&#8217;image docker et pousser cette image vers le registre.<\/p>\n<p>Avant d&#8217;ex\u00e9cuter la commande, assurez-vous que votre fichier <code>requirements.txt<\/code> est \u00e0 jour en ex\u00e9cutant la commande suivante\u00a0:<\/p>\n<p><code>pip freeze &gt; requirements.txt<\/code><\/p>\n<p>Pour construire une image, ex\u00e9cutez la commande suivante\u00a0:<\/p>\n<p><code>docker build -t mukulmantosh\/django-kubernetes:1.0 .<\/code><\/p>\n<p><code>docker build -t \/django-kubernetes:1.0 .<\/code><\/p>\n<p>Cette commande peut varier en fonction de vos circonstances et vous devez utiliser votre propre nom d&#8217;utilisateur.<\/p>\n<p>Vous devez ensuite vous identifier sur Docker Hub pour faire un push de l&#8217;image dans le registre.<\/p>\n<p>Tapez la commande suivante dans le terminal\u00a0:<\/p>\n<p><code>docker login<\/code><\/p>\n<p>Entrez votre nom d&#8217;utilisateur et votre mot de passe. Une fois le processus d&#8217;authentification termin\u00e9, vous pouvez faire un push de l&#8217;image en ex\u00e9cutant\u00a0:<\/p>\n<p><code>docker push mukulmantosh\/django-kubernetes:1.0\u00a0<\/code><\/p>\n<p><code>docker push \/django-kubernetes:1.0\u00a0<\/code><\/p>\n<p>Une fois l&#8217;image pouss\u00e9e, vous pouvez observer des modifications dans Docker Hub.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/R5Dsklfxw_4yJZDE5-Sqg7sA5hsK6Ss_xuqoZMcrsWyLEMHz2Cn7CxrAxMDpD44HfIMihudAfwQope_6FpIXHqgYlgrrGg1bSuYgoJr9nxDpJCzQyQHQatqOpW-R-nywAhkz8FWNyCa0zVy9CX_fLwo.png\" width=\"624\" height=\"239\" \/><\/p>\n<p>Si vous ne pr\u00e9voyez pas de faire d&#8217;autres push d&#8217;images dans le registre, vous pouvez vous d\u00e9connecter en ex\u00e9cutant la commande\u00a0:<\/p>\n<p><code>docker logout<\/code><\/p>\n<p>Si vous souhaitez extraire cette image localement, allez sur la page <a href=\"https:\/\/hub.docker.com\/r\/mukulmantosh\/django-kubernetes\" target=\"_blank\" rel=\"noopener\">hub.docker.com\/r\/mukulmantosh\/django-kubernetes<\/a>.<\/p>\n<h2 class=\"wp-block-heading\">Configuration de Kubernetes\u00a0: \u00e9crire des fichiers YAML<\/h2>\n<p><strong>Cette section du tutoriel d\u00e9crit le d\u00e9ploiement d&#8217;applications sur des clusters Kubernetes locaux.<\/strong><\/p>\n<p>Pour ce tutoriel, nous allons utiliser Docker Desktop, mais vous pouvez aussi utiliser minikube ou kind.<\/p>\n<h3 class=\"wp-block-heading\">Namespaces<\/h3>\n<p>Dans Kubernetes, <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/overview\/working-with-objects\/namespaces\/\" target=\"_blank\" rel=\"noopener\">namespaces<\/a> est une partition virtuelle dans un cluster qui est utilis\u00e9e pour grouper et isoler des ressources et des objets. C&#8217;est une fa\u00e7on de cr\u00e9er plusieurs clusters virtuels dans un m\u00eame cluster physique.<\/p>\n<p>Vous pouvez cr\u00e9er et g\u00e9rer les namespaces en utilisant <code><a href=\"https:\/\/kubernetes.io\/docs\/reference\/kubectl\/\" target=\"_blank\" rel=\"noopener\">kubectl<\/a><\/code>, l&#8217;outil de ligne de commande de Kubernetes ou en les d\u00e9finissant dans les manifestes YAML lors du d\u00e9ploiement des ressources.<\/p>\n<ul>\n<li>Si vous avez choisi Docker Desktop comme plateforme principale d&#8217;ex\u00e9cution de Kubernetes, veillez \u00e0 activer Kubernetes dans les param\u00e8tres en cliquant sur la case \u00e0 cocher <strong>Enable Kubernetes<\/strong>.<\/li>\n<\/ul>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/945ORpQLrnTDqbNfZTK-1A8KjfxdrWZCocP992yiPSNgv57t-GLr5RvRV7I5TJurmuVDW24Xm-i7c4eBIC7gV4UrhJJb9PKhEhuqHJmWvpG87mCgema7ZiXljFZ-6-Qxp4aOmvzRr1vjzcpDUJTkf6E.png\" width=\"624\" height=\"368\" \/><\/p>\n<p>Ex\u00e9cutez la commande suivante dans le terminal pour cr\u00e9er un namespace\u00a0:<\/p>\n<p><code>kubectl create ns django-app<\/code><\/p>\n<h2 class=\"wp-block-heading\">D\u00e9ploiement de bases de donn\u00e9es avec K8s<\/h2>\n<p>Pour commencer, nous allons cr\u00e9er une instance PostgreSQL dans notre cluster Kubernetes sur l&#8217;environnement local.<\/p>\n<h3 class=\"wp-block-heading\">PersistentVolume<\/h3>\n<p>Dans Kubernetes, un <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/storage\/persistent-volumes\/\" target=\"_blank\" rel=\"noopener\">PersistentVolume<\/a> (PV) est un \u00e9l\u00e9ment de stockage du cluster qui a \u00e9t\u00e9 provisionn\u00e9 par un administrateur. En stockant les donn\u00e9es d&#8217;une fa\u00e7on ind\u00e9pendante du cycle de vie d&#8217;un pod, les volumes persistants permettent une gestion et une abstraction des ressources de stockage plus d\u00e9coupl\u00e9es et flexibles. Cela signifie que les donn\u00e9es peuvent persister m\u00eame si le pod qui les utilise est supprim\u00e9 ou replanifi\u00e9 sur un autre n\u0153ud du cluster.<\/p>\n<p>Nous allons cr\u00e9er un PV et l&#8217;appeler <code>pv.yml<\/code>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/7ad-L7W-VSSsV1aouIP2RqA7mHcjvr9TwzQPSbqKtg5ED_ZQigyZzVmqyM7XeEp343xKGKvQpdOUHTrHloOCsWgP5ufp_q43LK97-2gozI6AZ5iXA1b5aiI8yyvFbVYHxKzFMjwYfX4ELEbuZvUOUWM.png\" width=\"624\" height=\"631\" \/><\/p>\n<p>Cette configuration YAML d\u00e9finit une ressource PersistentVolume appel\u00e9e <code>postgres-pv<\/code> dot\u00e9e d&#8217;une capacit\u00e9 de 1\u00a0Go, qui est mont\u00e9e avec le mode d&#8217;acc\u00e8s <code>ReadWriteOnce<\/code> et qui est fournie par un chemin local sur le syst\u00e8me de fichiers du n\u0153ud situ\u00e9 dans <code>\/data\/db<\/code>. Ce PV peut \u00eatre utilis\u00e9 pour assurer le stockage persistant des pods qui doivent acc\u00e9der \u00e0 un r\u00e9pertoire sur le syst\u00e8me de fichiers du n\u0153ud et convient pour des applications telles que PostgreSQL, ou d&#8217;autres services avec \u00e9tat n\u00e9cessitant un stockage persistant.<\/p>\n<p>Pour la production, nous recommandons d&#8217;utiliser des solutions cloud telles que AWS RDS ou Google CloudSQL, ou encore Kubernetes <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/workloads\/controllers\/statefulset\/\" target=\"_blank\" rel=\"noopener\">StatefulSets<\/a>.<\/p>\n<h3 class=\"wp-block-heading\">PersistentVolumeClaim<\/h3>\n<p>Dans Kubernetes, un <a href=\"https:\/\/kubernetes.io\/docs\/tasks\/configure-pod-container\/configure-persistent-volume-storage\/#create-a-persistentvolumeclaim\" target=\"_blank\" rel=\"noopener\">PersistentVolumeClaim<\/a> (PVC) est un objet de ressource utilis\u00e9 par un pod pour demander une certaine quantit\u00e9 de stockage avec certaines propri\u00e9t\u00e9s d&#8217;un volume persistant. Les PVC permettent aux applications de demander des ressources de stockage sans avoir \u00e0 conna\u00eetre les d\u00e9tails de l&#8217;infrastructure de stockage sous-jacente.<\/p>\n<p>En cr\u00e9ant et utilisant des PVC, Kubernetes permet d&#8217;allouer et de g\u00e9rer de fa\u00e7on dynamique les ressources de stockage des applications tout en d\u00e9mat\u00e9rialisant l&#8217;infrastructure de stockage, ce qui facilite leur manipulation et permet de g\u00e9rer les applications avec \u00e9tat dans des environnements conteneuris\u00e9s.<\/p>\n<p>Nous allons cr\u00e9er un PVC et l&#8217;appeler <code>pvc.yml<\/code>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/X_Td_1FR8BElq2OK1mODusNTDcPHevnlT18IkCN8E08fT2rfkfsIY2iawyk3dcl7Dxlpr2NeDimz-RtJQbeH5QPqmM0nHWggq-fU4zw_dDbeH-2utnnKWGusBWt-CXO9-BM3M5ygvErDHfOlZtoWh7w.png\" width=\"624\" height=\"577\" \/><\/p>\n<p>Un PVC n\u00e9cessite des ressources de stockage et est li\u00e9 \u00e0 un volume persistant qui assure ce stockage.<\/p>\n<p>Cette configuration YAML d\u00e9finit un PersistentVolumeClaim appel\u00e9 <code>postgres-pvc<\/code> dans le namespace <code>django-app<\/code>. Elle consomme un gigaoctet de stockage en mode d&#8217;acc\u00e8s <code>ReadWriteOnce<\/code> et d\u00e9finit explicitement StorageClass sur <code>manual<\/code>. Ce PVC doit \u00eatre li\u00e9 \u00e0 un PV existant appel\u00e9 <code>postgres-pv<\/code>, ce qui revient \u00e0 r\u00e9server ce volume pour les pods dans le namespace <code>django-app<\/code> qui r\u00e9f\u00e9rence ce PVC.<\/p>\n<h3 class=\"wp-block-heading\">ConfigMap<\/h3>\n<p>Dans Kubernetes, un <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/configuration\/configmap\/\" target=\"_blank\" rel=\"noopener\">ConfigMap<\/a> est un objet d&#8217;API servant \u00e0 stocker les donn\u00e9es de configuration dans des paires cl\u00e9-valeur. Il offre un moyen de d\u00e9coupler les donn\u00e9es de configuration du code de l&#8217;application, ce qui facilite leur gestion et leur mise \u00e0 jour sans avoir \u00e0 modifier et red\u00e9ployer les conteneurs. Cela s&#8217;av\u00e8re particuli\u00e8rement utile pour configurer les applications, les microservices et autres composants d&#8217;un cluster Kubernetes.<\/p>\n<p>Nous allons cr\u00e9er un ConfigMap et l&#8217;appeler <code>cm.yml<\/code>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/wvDyPcHd888DKzevEdpSAURy5e6IzinJthTUHK5z58-BnPhFx0bXrnaexUXpzJkhbXkbZa-zgdjcttbKIvI01hznnCrw9-E9LAmSlMD4o1GDQ-99rjgKgqIF9vXsacJ3_K_XPckDmAWrpEvFDYmOw_Y.png\" width=\"624\" height=\"524\" \/><\/p>\n<p>Ce tutoriel utilise des ConfigMap, mais pour des raisons de s\u00e9curit\u00e9, il est recommand\u00e9 de stocker les informations d&#8217;authentification sensibles dans des <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/configuration\/secret\/\" target=\"_blank\" rel=\"noopener\">Secrets<\/a> Kubernetes ou d&#8217;explorer d&#8217;autres solutions, telles que Bitnami Sealed Secrets, AWS Parameter Store ou HashiCorp Vault.<\/p>\n<h3 class=\"wp-block-heading\">Deployment<\/h3>\n<p>Dans Kubernetes, <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/workloads\/controllers\/deployment\/\" target=\"_blank\" rel=\"noopener\">Deployment<\/a> est un objet de ressource permettant de g\u00e9rer le d\u00e9ploiement et l&#8217;\u00e9volution des applications. Il fait partie du groupe d&#8217;API Kubernetes et apporte une solution d\u00e9clarative pour d\u00e9finir et g\u00e9rer l&#8217;\u00e9tat voulu de votre application.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/fu5av6IILewmdL6cpFurozbGqH6gWdutfRmxwUb-0FGPs6j05xNSE4jwYeDsD2BKA_GE8WOaTqx2C85DX2mkz21LPzBFl_BHcSD-lIXthE0zaYSgUEWZ-gIQB07qIZ0V-iIm0cWiBCpmHcqvlpuirso.png\" width=\"624\" height=\"735\" \/><\/p>\n<p>Un Deployment est une ressource Kubernetes de plus haut niveau pour g\u00e9rer et mettre \u00e0 l&#8217;\u00e9chelle les pods d&#8217;applications.<\/p>\n<p>Cette configuration YAML d\u00e9finit un Deployment appel\u00e9 <code>postgres<\/code> dans le namespace <code>django-app<\/code>. Il d\u00e9ploie une r\u00e9plique unique d&#8217;une base de donn\u00e9es PostgreSQL (version 16.0) \u00e0 stockage persistant. Le pod de base de donn\u00e9es est appel\u00e9 <code>app: postgresdb<\/code> et le stockage est assur\u00e9 par un PVC appel\u00e9 <code>postgres-pvc<\/code>. La configuration et les informations d&#8217;authentification du conteneur PostgreSQL sont fournies par un ConfigMap appel\u00e9 <code>db-secret-credentials<\/code>.<\/p>\n<h3 class=\"wp-block-heading\">Service<\/h3>\n<p>Dans Kubernetes, un <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/services-networking\/service\/\" target=\"_blank\" rel=\"noopener\">Service<\/a> est un objet de ressource permettant d&#8217;exposer un ensemble de pods en tant que service r\u00e9seau. Le r\u00f4le d&#8217;un Service est d&#8217;assurer la communication r\u00e9seau entre diff\u00e9rentes parties de votre application s&#8217;ex\u00e9cutant dans un cluster Kubernetes et de fournir un point de terminaison stable permettant aux clients d&#8217;y acc\u00e9der. Cela permet d&#8217;abstraire l&#8217;infrastructure r\u00e9seau sous-jacente pour faciliter la connexion et la d\u00e9couverte des composants de votre application.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/p4NneUHgkfOqr2cp1bIZVYEH1weBKgZ5cWjPOgnATHQGdQwULM9BlzPRJXyPqf0v3FqHrztZ9rmL6P3RSInOE6vNC21UenOjGz-872-KzklWAQGm2Rr3uOKIQMRMlLvCIHiswccwGtI-eVeBI7b61EI.png\" width=\"624\" height=\"525\" \/><\/p>\n<p>Cette configuration YAML d\u00e9finit un Service NodePort sous le nom <code>postgres-service<\/code> dans le namespace <code>django-app<\/code>. Elle expose le service PostgreSQL s&#8217;ex\u00e9cutant dans les pods portant le libell\u00e9 \u00ab\u00a0<code>app: postgresdb<\/code>\u00a0\u00bb sur le port 5432 du cluster. Les clients externes peuvent acc\u00e9der au Service \u00e0 l&#8217;adresse IP du n\u0153ud voulu en utilisant le port 30004. Ce Service rend la base de donn\u00e9es PostgreSQL accessible depuis l&#8217;ext\u00e9rieur du cluster Kubernetes.<\/p>\n<h2 class=\"wp-block-heading\">Cr\u00e9er des configurations YAML pour une application Django<\/h2>\n<h3 class=\"wp-block-heading\">PersistentVolume<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/FJCpL5-QEQHMI7w0j2XnboyV-y6NOoRZPzOd3GXJju2CLizk2kmnXEBcDaUSAOuvHfFrOcKel3VcVs0fimdgovM9NSn5aw31hDTYSkyAgYSK14EqO-bj2CgL2p-6h20IDY0Ei-szg63ZKYIr77kIOZs.png\" width=\"624\" height=\"525\" \/><\/p>\n<p>Cette configuration YAML d\u00e9finit un PersistentVolume appel\u00e9 <code>staticfiles-pv<\/code> dot\u00e9 d&#8217;une capacit\u00e9 de stockage de 1\u00a0Go, ce qui permet \u00e0 plusieurs pods d&#8217;y effectuer des op\u00e9rations simultan\u00e9es de lecture et d&#8217;\u00e9criture. Le stockage est fourni par un chemin d&#8217;h\u00f4te local situ\u00e9 dans <code>\/data\/static<\/code>. Les fichiers statiques Django seront stock\u00e9s \u00e0 cet endroit.<\/p>\n<h3 class=\"wp-block-heading\">PersistentVolumeClaim<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/01PqOjeQXzeBx4RIkSdTRXttHzaEZexNL_OsQPfaCiOqbLTY85QhXOSCx0ojmGxSINUpuO4FhcZLk4Sl5YosJISr4GBMWeecUeObtbGiGXR9k_uQftED-89TurtbyVoaujef1ixQ4FQ8zSoa8j2MWp4-1.png\" width=\"624\" height=\"504\" \/><\/p>\n<p>Cette configuration YAML d\u00e9finit un PVC appel\u00e9 <code>staticfiles-pvc<\/code> dans le namespace <code>django-app<\/code>. Elle n\u00e9cessite une capacit\u00e9 de stockage d&#8217;au moins 1\u00a0Go sur un volume persistant comportant la classe \u00ab\u00a0manuelle\u00a0\u00bb StorageClass et demande un acc\u00e8s <code>ReadWriteMany<\/code>. Cette demande cr\u00e9e une liaison explicite \u00e0 un volume persistant appel\u00e9 <code>staticfiles-pv<\/code> pour satisfaire les besoins de stockage. Cela permet aux pods du namespace <code>django-app<\/code> d&#8217;utiliser ce PVC pour acc\u00e9der au stockage fourni par le PV associ\u00e9 et l&#8217;utiliser.<\/p>\n<h3 class=\"wp-block-heading\">ConfigMap<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/zWM1NlnXZNXcXFBqcJo2iDvVn1HsVKmSqrrWASDo8g7iQFtHKQksufKcirqeKrpNKhLPw-EBLT5BPAapQDSvNTRF1Z9yzZlTO2bxOs2PdQNJYSwMdkDKXnMQJekawNLJe7FzJXuhAcyjKIZ6wjBw28c-1.png\" width=\"624\" height=\"459\" \/><\/p>\n<p>Cette configuration YAML d\u00e9finit un ConfigMap appel\u00e9 <code>app-cm<\/code> dans le namespace <code>django-app<\/code> qui contient diff\u00e9rentes paires cl\u00e9\/valeur stockant les donn\u00e9es de configuration. Ce ConfigMap est utilisable par les pods ou autres ressources appartenant au namespace <code>django-app<\/code> pour acc\u00e9der aux param\u00e8tres de configuration, tels que les informations de connexion \u00e0 la base de donn\u00e9es et les chemins de fichiers statiques.<\/p>\n<h3 class=\"wp-block-heading\">D\u00e9ploiement<\/h3>\n<figure class=\"wp-block-image size-full is-resized\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-456835\" style=\"aspect-ratio: 0.7497020262216925; width: 582px; height: auto;\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/03\/deploy.png\" alt=\"\" width=\"1258\" height=\"1678\" \/><\/figure>\n<p>Cette configuration YAML d\u00e9finit un Deployment appel\u00e9 <code>django-app-deploy<\/code> dans le namespace <code>django-app<\/code>. Elle cr\u00e9e une r\u00e9plique (un pod) ex\u00e9cutant un conteneur avec une image et une configuration Docker sp\u00e9cifiques. Ce pod est associ\u00e9 \u00e0 deux volumes, <code>postgres-db-storage<\/code> et <code>staticfiles<\/code>, qui sont fournis par l&#8217;interm\u00e9diaire de PVC. Le conteneur est configur\u00e9 de fa\u00e7on \u00e0 utiliser des variables d&#8217;environnement provenant d&#8217;un ConfigMap appel\u00e9 <code>app-cm<\/code> et \u00e9coute sur le port\u00a08000. Les volumes sont mont\u00e9s \u00e0 des chemins sp\u00e9cifiques dans le conteneur pour fournir un acc\u00e8s au stockage de la base de donn\u00e9es et aux fichiers statiques. Ce Deployment est une solution courante pour ex\u00e9cuter des applications Django utilisant Kubernetes.<\/p>\n<p>Si vous souhaitez savoir comment extraire des images d&#8217;un r\u00e9f\u00e9rentiel priv\u00e9, lisez <a href=\"https:\/\/kubernetes.io\/docs\/tasks\/configure-pod-container\/pull-image-private-registry\/\" target=\"_blank\" rel=\"noopener\">cet article<\/a>.<\/p>\n<h3 class=\"wp-block-heading\">Service<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/Z0wfNZT1VrOT-9FznBYsl1LGu_b635fuSFtpoLRacsqfBiLAOi_tw7p87Ao8p9ZPx8-84e5NFerr3krbB5OsW2Vo9ps_hAvlaXV-2ga2RBLsm7vfPJ0rUUyzvvBg4NoQ0c_K7BO8I4u5vOgbUT1BBU-1.png\" width=\"624\" height=\"577\" \/><\/p>\n<p>Le Service \u00e9coute sur le port\u00a08000 et dirige le trafic entrant vers les pods libell\u00e9s <code>app: django-application<\/code>. Il s&#8217;agit d&#8217;une configuration commune pour l&#8217;exposition et l&#8217;\u00e9quilibrage des charges dans un cluster Kubernetes ex\u00e9cutant plusieurs instances de la m\u00eame application web. Le Service s&#8217;assure que le trafic est distribu\u00e9 de fa\u00e7on \u00e9gale entre elles.<\/p>\n<h2 class=\"wp-block-heading\">NGINX<\/h2>\n<p><a href=\"https:\/\/www.nginx.com\/\" target=\"_blank\" rel=\"noopener\">NGINX<\/a> est un serveur web et proxy inverse hautes performances, appr\u00e9ci\u00e9 pour sa rapidit\u00e9, sa fiabilit\u00e9 et son \u00e9volutivit\u00e9. Il g\u00e8re efficacement le trafic web, l&#8217;\u00e9quilibrage des charges et la remise du contenu, ce qui en fait un choix id\u00e9al pour les sites web et les applications.<\/p>\n<h3 class=\"wp-block-heading\">ConfigMap<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/Itj5_NS6IlHVlnJ49MnCsE2Hu8x0X7X2EW_Nm3qy7ujShq1mBmawFBCFk4iKbsDZ890n2xTJFGs1TlmRrZ0QDqL35IC6mj07cq8tz1GVisueNR4cDsqPZW1gTD5j7ZoTBJcWba5VpFXXZAwagXE0y60-2.png\" width=\"624\" height=\"460\" \/><\/p>\n<p>Cette configuration YAML d\u00e9finit un ConfigMap Kubernetes appel\u00e9 <code>nginx-cm<\/code> dans le namespace <code>django-app<\/code> qui contient une paire cl\u00e9\/valeur o\u00f9 la cl\u00e9 est <code>default.conf<\/code> et la valeur est un fichier de configuration NGINX multiligne qui transf\u00e8re la requ\u00eate au serveur backend par l&#8217;interm\u00e9diaire d&#8217;un proxy.<\/p>\n<h3 class=\"wp-block-heading\">D\u00e9ploiement<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/4ErlDKYewor2Owj0YrtS7O01WkXzFkTBHoN5LGlEGBfvX_MGUzXgxF0ur0eDSIBD2HdJlbg4zpAE1v1OwT_LkSYR3RS4hQFnW3jwX_wEjE_L4cCIeuHI-wspyiTGaw6z8JnHXw8buX0yvbWsr3eSNDo-1.png\" width=\"624\" height=\"727\" \/><\/p>\n<p>Cette configuration YAML d\u00e9finit un Deployment qui cr\u00e9e et g\u00e8re les pods ex\u00e9cutant un conteneur NGINX utilisant des volumes et des configurations sp\u00e9cifiques. Le Deployment permet de s&#8217;assurer qu&#8217;une r\u00e9plique de ce pod est toujours en cours d&#8217;ex\u00e9cution dans le namespace <code>django-app<\/code>. Il remplace \u00e9galement la configuration NGINX par d\u00e9faut par le ConfigMap <code>nginx-cm<\/code>.<\/p>\n<h3 class=\"wp-block-heading\">Service<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/PqinRZHVtGiapAjd5aD4-mA4sRmxTlRnfkSl5y6GRrPY4KpD2MsuMkkKspX1J-JHNwEdSlxb_Vtuex3SRd0caY4x-zI744KCZ-AKgjYc976FWHiEZVl9dM-oyJuPgE-DoEyU46RLokubkL-otadMZ40-4.png\" width=\"624\" height=\"631\" \/><\/p>\n<p>Cette configuration YAML cr\u00e9e un Service Kubernetes sous le nom <code>nginx-service<\/code> dans le namespace <code>django-app<\/code>. Elle expose les pods libell\u00e9s <code>app:nginx<\/code> sur le port\u00a080 du cluster et rend \u00e9galement le Service accessible sur le NodePort 30005 dans chacun des n\u0153uds du cluster. Cela permet au trafic externe d&#8217;atteindre les pods ex\u00e9cutant l&#8217;application NGINX via le service NodePort.<\/p>\n<h2 class=\"wp-block-heading\">Gestion de charges de travail group\u00e9es avec un Job Kubernetes<\/h2>\n<p>Dans Kubernetes, un <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/workloads\/controllers\/job\/\" target=\"_blank\" rel=\"noopener\">Job<\/a> est un objet de ressource qui repr\u00e9sente une seule unit\u00e9 de travail ou une seule t\u00e2che d\u00e9finie. Il sert \u00e0 ex\u00e9cuter des t\u00e2ches \u00e0 leur terme jusqu&#8217;\u00e0 atteindre un nombre sp\u00e9cifi\u00e9 d&#8217;ex\u00e9cutions termin\u00e9es avec succ\u00e8s.<\/p>\n<h3 class=\"wp-block-heading\">Migration des bases de donn\u00e9es<\/h3>\n<figure class=\"wp-block-image size-full is-resized\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-456823\" style=\"aspect-ratio: 0.9512195121951219; width: 597px; height: auto;\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/03\/migration.png\" alt=\"\" width=\"1326\" height=\"1394\" \/><\/figure>\n<p>Cette configuration YAML d\u00e9finit un Job Kubernetes appel\u00e9 <code>django-db-migrations<\/code> dans le namespace <code>django-app<\/code>. Ce Job ex\u00e9cute un conteneur utilisant une image Docker personnalis\u00e9e pour les migrations Django et monte un PVC pour assurer le stockage des fichiers relatifs \u00e0 la base de donn\u00e9es. Si le Job \u00e9choue, il est possible de refaire jusqu&#8217;\u00e0 15\u00a0essais, et il conserve son pod pendant 100\u00a0secondes apr\u00e8s l&#8217;ex\u00e9cution. Ce Job cr\u00e9e de nouvelles tables dans PostgreSQL.<\/p>\n<h3 class=\"wp-block-heading\">Fichiers statiques<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/41sZvQpth3_7rpCpoCuUY0k588q9aANJoVs6DxWJSGF2qvZQDo0u9jcxEbjjEb9IQ3oLUTNkboM61EoKbGOxsnsJFHfzLYjlwFqq8TXtuYNLZne2h358Yn-MyoNrk8JVGRpu0erDPr4yHqevTlXzxtY-4.png\" width=\"624\" height=\"643\" \/><\/p>\n<p>Cette configuration YAML d\u00e9finit un Job Kubernetes appel\u00e9 <code>django-staticfiles<\/code> dans le namespace <code>django-app<\/code>. Ce Job ex\u00e9cute un conteneur utilisant une image Docker personnalis\u00e9e pour la collecte de fichiers statiques destin\u00e9s \u00e0 une application Django et monte un PVC pour assurer le stockage des fichiers statiques. Si le Job \u00e9choue, il est possible de refaire jusqu&#8217;\u00e0 trois\u00a0essais, et il conserve son pod pendant 100\u00a0secondes apr\u00e8s l&#8217;ex\u00e9cution pour permettre le d\u00e9bogage. Ce Job copie les fichiers statiques dans le mountPath, qui a la valeur <code>\/data\/static<\/code>.<\/p>\n<h2 class=\"wp-block-heading\">Lancement de l&#8217;application<\/h2>\n<p>Pour lancer l&#8217;application, naviguez jusqu&#8217;au r\u00e9pertoire <code>k8s<\/code> et ex\u00e9cutez la commande suivante\u00a0:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/t7jeYgU4ZqFBXc-2WwudXN8V4cibZZt5M0Tob6-0zV570MXlHkql6QBw4Oxibl5WWdGnfB9510sYpfjnIhsjvs9AObRuhIrR91r8b3Q8Vu2pJYuLfFhm2ixDw7Oddkvh-5tP3nUADGAu5DX725cJ6YI-4.png\" width=\"624\" height=\"392\" \/><\/p>\n<p>Une fois l&#8217;application d\u00e9ploy\u00e9e, utilisez la commande suivante pour v\u00e9rifier l&#8217;\u00e9tat des pods en cours d&#8217;ex\u00e9cution\u00a0:<\/p>\n<p><code>kubectl get pods -n django-app -w<\/code><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/PiIyWEPFMtnrTpvspZ6gc65Z81xUgAbiqSQ2XgphxJ229PKgASge2sNzU0_YG_vC-k_hFBMNH1lF1CTBbY5oDWnNDne1Cf3nI809BP6bIUr0xHvRbNsOI_TkLwLwu7QFmcnKBarHlsK7tu8dBsqjgMA-4.png\" width=\"624\" height=\"108\" \/><\/p>\n<h3 class=\"wp-block-heading\">Cr\u00e9ation d&#8217;un superutilisateur dans Django<\/h3>\n<p>Une fois l&#8217;ensemble de vos applications configur\u00e9es et en cours d&#8217;ex\u00e9cution, cr\u00e9ez un superutilisateur pour vous connecter au module d&#8217;administration de Django.<\/p>\n<p>Ex\u00e9cutez la commande suivante pour obtenir la liste des pods en cours d&#8217;ex\u00e9cution\u00a0:<\/p>\n<p><code>kubectl get pods -n django-app<\/code><\/p>\n<p>Pour entrer dans le shell du conteneur, ex\u00e9cutez\u00a0:<\/p>\n<p><code>kubectl exec -it  -n django-app -- sh<\/code><\/p>\n<p>Puis, ex\u00e9cutez\u00a0:<\/p>\n<p><code>python manage.py createsuperuser<\/code><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/y65m6YcxuejXhXIdGCr7_aqy_gGj4FhrtWsddWZgxWv2nBEnCedmQoPNupQQ0JRn7sMMwElFo09TMoPImbR6v2Sc3rirDBW6sLK2daaNbh3NDfvT83DrtTDHPiutsdc3vKC-V5nfXNYjrIzt26igd_o-4.png\" width=\"624\" height=\"197\" \/><\/p>\n<p>Une fois le superutilisateur cr\u00e9\u00e9, ouvrez <a href=\"http:\/\/127.0.0.1:30005\" target=\"_blank\" rel=\"noopener\">http:\/\/127.0.0.1:30005<\/a> dans un navigateur. Vous serez dirig\u00e9 vers la page d&#8217;accueil par d\u00e9faut.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/tpozSD_EtSgHLFQ1ud5EV4_OJFdmgSUGlS6u4iEMI9rVrduVIlaJS1NHoD4D6WhjCdC7oASEobsfm9ar0cWUxEydoSVsTfuoOWTJw-5usNmJrusEyD50SGJYbKUWU_BLgdbipbfYeeKBcW1ecK8_gsQ-3.png\" width=\"624\" height=\"321\" \/><\/p>\n<p>Ensuite, allez dans le module d&#8217;administration de Django via <a href=\"http:\/\/127.0.0.1:30005\/admin\" target=\"_blank\" rel=\"noopener\">http:\/\/127.0.0.1:30005\/admin<\/a>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/WcwAvYrT3499Hr32HybiT6VuuanZh8keoS95n0N3-lasuJ8z4rsmQydIp4MLCGVORtQLZnECw2y3IKB9e2J8Mg8ScRF1HpvD-bu68MSYv_Ti_GBr3P4Y0gtc8B6aaUfg2kRF2VLj0NXUWLDRCiy3sjg-3.png\" width=\"624\" height=\"447\" \/><\/p>\n<p>Saisissez le nom d&#8217;utilisateur et le mot de passe que vous venez de cr\u00e9er.<\/p>\n<p>Une fois authentifi\u00e9, vous serez redirig\u00e9 vers la page d&#8217;administration de Django.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/u4my3QzTYVifPI-wEPH__wlI6M7tUITtpDeoPnoK6bM6NC2nSAutEumLtR3CScqWcEFrnH8KrkH3k2QMna_Yyz2mnTO1qF8idfFOiG263r8k7Y_6wU-QsbihmY7Av08sRX_05wSc72Nw9DKnFiYOgeE-4.png\" width=\"624\" height=\"400\" \/><\/p>\n<p>Si vous tentez de vous connecter via localhost:30005\/admin, vous risquez de recevoir une erreur <em>403 Forbidden<\/em> (CSRF).<\/p>\n<p>Vous pouvez r\u00e9soudre cela dans la section <code>CSRF_TRUSTED_ORIGINS<\/code> du fichier <code>settings.py<\/code>.<\/p>\n<p><code>CSRF_TRUSTED_ORIGINS<\/code> est un <a href=\"https:\/\/docs.djangoproject.com\/en\/4.2\/ref\/settings\/#std-setting-CSRF_TRUSTED_ORIGINS\" target=\"_blank\" rel=\"noopener\">param\u00e8tre <\/a>Django qui permet de sp\u00e9cifier une liste d&#8217;origines de confiance pour la protection CSRF (falsification de requ\u00eate inter-sites). CSRF est une vuln\u00e9rabilit\u00e9 de s\u00e9curit\u00e9 qui peut survenir lorsqu&#8217;un pirate parvient \u00e0 tromper un utilisateur pour qu&#8217;il effectue involontairement une requ\u00eate ind\u00e9sirable dans une application web. Pour emp\u00eacher cela, Django inclut une protection CSRF int\u00e9gr\u00e9e.<\/p>\n<p><code>CSRF_TRUSTED_ORIGINS<\/code> vous permet de d\u00e9finir une liste d&#8217;origines (sites web) \u00e0 partir desquelles les requ\u00eates prot\u00e9g\u00e9es contre CSRF sont accept\u00e9es. Toute requ\u00eate dont l&#8217;origine ne figure pas dans cette liste sera consid\u00e9r\u00e9e comme potentiellement malveillante et bloqu\u00e9e sans appel.<\/p>\n<p>Ce param\u00e8tre permet d&#8217;autoriser certaines requ\u00eates d&#8217;origine crois\u00e9e dans votre application Django tout en assurant la s\u00e9curit\u00e9 contre les attaques CSRF. Cela est particuli\u00e8rement utile dans les sc\u00e9narios o\u00f9 votre application doit interagir avec d&#8217;autres services web ou API qui sont h\u00e9berg\u00e9s sur d&#8217;autres domaines.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/DTDVeAkR8-rHFCbeoMqWHHSSCBDNjQ96OLDPcexK0TVmbzk9bRgHajXVqFiy4r_yTd6mE1GM7TGuCwYcTJ0owbKhhjLxaJlgE9_KjgEk6APxHsHsPXtdRtJwRbYgejaoHuxpWzUEsaUAt3oHjzrTvVM-4.png\" width=\"624\" height=\"428\" \/><\/p>\n<p>Si vous utilisez d&#8217;autres outils d&#8217;interface utilisateur graphique tels que <a href=\"https:\/\/kubernetes.io\/docs\/tasks\/access-application-cluster\/web-ui-dashboard\/\" target=\"_blank\" rel=\"noopener\">Kubernetes Dashboard<\/a>, vous pouvez facilement visualiser les pods en cours d&#8217;ex\u00e9cution, les d\u00e9ploiements, les volumes persistants, etc.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/2lssXclYX6wG01Kf5SX7hng9Yxd0JuqeFAYR-UDdEBIXJyzNZItFQFGMT1UxAifh3FywhRmaWzrwafuv0L9nciqBE7yf09hf7sYmpijHkrZoe_MXeBIow9q_CrlZAUHLmNHDzMTcO8XZqWHOxjZHcnw-4.png\" width=\"624\" height=\"325\" \/><\/p>\n<h2 class=\"wp-block-heading\">Prise en charge de Kubernetes dans PyCharm<\/h2>\n<p>PyCharm offre un \u00e9diteur \u00e9tendu et une prise en charge de l&#8217;ex\u00e9cution adapt\u00e9s \u00e0 Kubernetes, ce qui apporte de nombreuses fonctionnalit\u00e9s pour simplifier la gestion de Kubernetes, notamment\u00a0:<\/p>\n<ul>\n<li>Parcourir les objets du cluster, extraire et modifier leurs configurations et les d\u00e9crire.<\/li>\n<li>Afficher les \u00e9v\u00e9nements.<\/li>\n<li>Afficher et t\u00e9l\u00e9charger les journaux des pods.<\/li>\n<li>Attacher la console de pods.<\/li>\n<li>Ex\u00e9cuter le shell dans les pods.<\/li>\n<li>Transf\u00e9rer les ports \u00e0 un pod.<\/li>\n<li>Appliquer les configurations YAML des ressources depuis l&#8217;\u00e9diteur.<\/li>\n<li>Supprimer les ressources du cluster.<\/li>\n<li>Saisie semi-automatique des entr\u00e9es ConfigMap et Secret depuis le cluster.<\/li>\n<li>Configuration des chemins sur <code>kubectl<\/code>.<\/li>\n<li>Configuration des fichiers <code>kubeconfig<\/code> personnalis\u00e9s globalement et par projet.<\/li>\n<li>Changer de contexte et de namespace.<\/li>\n<li>Utilisation d&#8217;un sch\u00e9ma d&#8217;API (avec notamment CRD) depuis le cluster actif pour modifier les manifestes de ressources.<\/li>\n<\/ul>\n<p>Regardez cette <a href=\"https:\/\/www.youtube.com\/watch?v=NqotF4kRvTc\" target=\"_blank\" rel=\"noopener\">vid\u00e9o<\/a> pour en savoir plus sur l&#8217;utilisation de Kubernetes dans PyCharm Professional.<\/p>\n<p>Essayez PyCharm gratuitement pour vos t\u00e2ches Kubernetes\u00a0!<\/p>\n<div class=\"buttons\">\n<div class=\"buttons__row\"><a class=\"btn\" href=\"https:\/\/www.jetbrains.com\/fr-fr\/pycharm\/download\/\" target=\"\" rel=\"noopener\">T\u00c9L\u00c9CHARGER PYCHARM<\/a><\/div>\n<\/div>\n<h2 class=\"wp-block-heading\">R\u00e9f\u00e9rences<\/h2>\n<p>Vous ma\u00eetrisez d\u00e9j\u00e0 Kubernetes\u00a0? Allez encore plus loin en explorant les solutions cloud et en consultant nos tutoriels sur <a href=\"https:\/\/www.jetbrains.com\/pycharm\/guide\/tutorials\/fastapi-aws-kubernetes\/\" target=\"_blank\" rel=\"noopener\">AWS EKS<\/a> et <a href=\"https:\/\/www.jetbrains.com\/pycharm\/guide\/tutorials\/cloud-code-pycharm\/\" target=\"_blank\" rel=\"noopener\">Google Kubernetes Engine<\/a>.<\/p>\n<p><em>Auteur de l\u2019article original en anglais :<\/em><\/p>\n\n    <div class=\"about-author \">\n        <div class=\"about-author__box\">\n            <div class=\"row\">\n                <div class=\"about-author__box-img\">\n                    <img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/mukul-200x200.jpg\" width=\"200\" height=\"200\" alt=\"Mukul Mantosh\" loading=\"lazy\"  class=\"avatar avatar-200 wp-user-avatar wp-user-avatar-200 photo avatar-default\">\n                <\/div>\n                <div class=\"about-author__box-text\">\n                                            <h4>Mukul Mantosh<\/h4>\n                                                        <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n","protected":false},"author":813,"featured_media":593225,"comment_status":"closed","ping_status":"closed","template":"","categories":[8377],"tags":[963,5635,154],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/pycharm\/593222"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/pycharm"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/types\/pycharm"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/users\/813"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/comments?post=593222"}],"version-history":[{"count":10,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/pycharm\/593222\/revisions"}],"predecessor-version":[{"id":650238,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/pycharm\/593222\/revisions\/650238"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/media\/593225"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/media?parent=593222"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/categories?post=593222"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/tags?post=593222"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/cross-post-tag?post=593222"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}