{"id":572015,"date":"2025-06-01T03:09:18","date_gmt":"2025-06-01T02:09:18","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=pycharm&#038;p=572015"},"modified":"2025-09-15T09:23:40","modified_gmt":"2025-09-15T08:23:40","slug":"deployment-von-django-apps-in-kubernetes","status":"publish","type":"pycharm","link":"https:\/\/blog.jetbrains.com\/de\/pycharm\/2025\/06\/deployment-von-django-apps-in-kubernetes\/","title":{"rendered":"Deployment von Django-Apps in Kubernetes"},"content":{"rendered":"<p>Als Open-Source-Plattform f\u00fcr die Orchestrierung von Containern, welche das Deployment, die Skalierung und die Lastverteilung automatisiert, bietet Kubernetes eine unvergleichliche Ausfallsicherheit sowie Flexibilit\u00e4t in Bezug auf die Verwaltung Ihrer Django-Anwendungen<strong>. <\/strong><\/p>\n<p>Ganz gleich, ob Sie ein kleines Projekt launchen oder eine komplexe Anwendung verwalten m\u00f6chten: Kubernetes stellt Ihnen eine robuste Umgebung zur Verf\u00fcgung, um Ihre Django-App zu optimieren. Gleichzeitig wird sichergestellt, dass sie den Anforderungen der modernen Webentwicklung gerecht wird.<\/p>\n<p>Durch die Automatisierung des Deployments, der Skalierung und des Betriebs von containerisierten Anwendungen bietet <a href=\"https:\/\/kubernetes.io\/\" target=\"_blank\" rel=\"noopener\">Kubernetes<\/a> (oder K8s) zahlreiche Vorteile f\u00fcr Organisationen in der schnelllebigen Technologiebranche.<\/p>\n<p>Unabh\u00e4ngig davon, ob Sie Django-Entwickler*in sind und Ihre Deployment-F\u00e4higkeiten verbessern m\u00f6chten, oder Kubernetes-Fan mit Interesse an der Django-Integration, hat dieser Leitfaden f\u00fcr jeden etwas zu bieten.<\/p>\n<p><!--more--><\/p>\n<p>In der Einf\u00fchrung zu diesem Tutorial wird die symbiotische Beziehung zwischen Django und Kubernetes untersucht, die es Ihnen erm\u00f6glicht, Ihre Webanwendung nahtlos zu containerisieren, Workloads \u00fcber Cluster zu verteilen und hohe Verf\u00fcgbarkeit zu gew\u00e4hrleisten.<\/p>\n<h2 class=\"wp-block-heading\">Django<\/h2>\n<p>Das Django-Framework \u2013 ein leistungsstarkes Python-Web-Framework \u2013 steht f\u00fcr Effizienz und Einfachheit in der Welt der Webentwicklung. Django wurde aus dem Bed\u00fcrfnis heraus geboren, schnelle, robuste und leicht zu wartende Webanwendungen zu erstellen, und hat sich mittlerweile als bevorzugte Wahl f\u00fcr Entwickler*innen und Organisationen etabliert.<\/p>\n<p>Django steht f\u00fcr die Philosophie \u201eAlles inklusive\u201c. Es bietet eine umfangreiche Auswahl an integrierten Tools, Bibliotheken und Konventionen, die den Entwicklungsprozess erheblich vereinfachen. Django vereinfacht komplexe Aufgaben wie URL-Routing, Datenbankintegration und Benutzerauthentifizierung, sodass sich Entwickler*innen ganz auf ihre Anwendungen konzentrieren k\u00f6nnen.<\/p>\n<p>Einer der wichtigsten Vorteile von Django ist die Einhaltung des Prinzips \u201eDon&#8217;t repeat yourself\u201c (DRY), wodurch Redundanzen reduziert und die Wartbarkeit des Codes verbessert werden. Au\u00dferdem folgt es dem Architekturmuster Model-View-Controller (MVC), wodurch Apps strukturiert werden und einfach zu verwalten sind.<\/p>\n<p>Django legt au\u00dferdem gro\u00dfen Wert auf Sicherheit und ist daher weniger anf\u00e4llig f\u00fcr g\u00e4ngige Web-Schwachstellen. Es bietet von Grund auf integrierte Funktionen, die einen effektiven Schutz gegen Cross-Site-Scripting (XSS) und Cross-Site-Request-Forgery (CSRF) gew\u00e4hrleisten. Django wartet mit einer starken Kombination aus Geschwindigkeit, Einfachheit sowie Sicherheit auf und ist die ideale Wahl f\u00fcr Entwickler*innen, die mit minimalem Aufwand robuste, funktionsreiche Webanwendungen erstellen m\u00f6chten.<\/p>\n<h2 class=\"wp-block-heading\">Container-Orchestratoren<\/h2>\n<p>Container-Orchestratoren sind unverzichtbare Tools f\u00fcr die Verwaltung und Automatisierung der Bereitstellung, der Skalierung und des Betriebs von containerisierten Anwendungen. Auf dem Markt gibt es mehrere Container-Orchestratoren. Die beliebtesten sind folgende:<\/p>\n<p>1. <strong>Kubernetes<\/strong>, die f\u00fchrende Open-Source-Plattform f\u00fcr Container-Orchestrierung, bietet eine robuste und anpassungsf\u00e4hige Umgebung f\u00fcr den Umgang mit containerisierten Anwendungen. Kubernetes automatisiert Aufgaben wie Skalierung, Lastverteilung sowie Container-Zustandspr\u00fcfungen und hat ein umfassendes \u00d6kosystem von Erweiterungen vorzuweisen.<\/p>\n<p>2. <strong>Docker Swarm<\/strong> ist eine L\u00f6sung f\u00fcr die Container-Orchestrierung, welche von Docker bereitgestellt wird. Docker Swarm wurde mit dem Ziel entwickelt, unkompliziert eingerichtet und m\u00fchelos genutzt werden zu k\u00f6nnen. Es bietet sich besonders f\u00fcr kleinere Anwendungen oder Organisationen an, die bereits mit Docker vertraut sind, da es die gleiche Befehlszeilenschnittstelle und API nutzt wie Docker selbst.<\/p>\n<p>3. <strong>OpenShift<\/strong> ist eine von Red Hat entwickelte Kubernetes-Plattform f\u00fcr Unternehmen. OpenShift f\u00fcgt Entwicklungs- sowie Betriebstools zu Kubernetes hinzu und vereinfacht das Deployment und die Verwaltung von containerisierten Anwendungen.<\/p>\n<p>4. <strong>Nomad<\/strong>, entwickelt von HashiCorp, ist ein schlanker und benutzerfreundlicher Orchestrator, der Container und nicht containerisierte Anwendungen verwalten kann.<\/p>\n<p>5. <strong>Apache Mesos<\/strong> ist ein Open-Source-Kernel f\u00fcr verteilte Systeme. DC\/OS (Betriebssystem f\u00fcr Rechenzentren) ist eine auf Mesos aufbauende Plattform f\u00fcr Unternehmen. DC\/OS erweitert Mesos um zus\u00e4tzliche Funktionen f\u00fcr die Verwaltung und Skalierung von containerisierten Anwendungen.<\/p>\n<p>Software-Teams arbeiten haupts\u00e4chlich mit verwalteten Plattformen, die von bekannten Cloud-Anbietern wie AWS, Google Cloud Platform und Azure bereitgestellt werden. Diese Cloud-Anbieter stellen Dienste wie Amazon EKS, Google GKE und Azure AKS zur Verf\u00fcgung, die allesamt verwaltete Kubernetes-L\u00f6sungen sind. Diese Dienste optimieren die Einrichtung, Erweiterung sowie Verwaltung von Kubernetes-Clustern und lassen sich nahtlos in die jeweiligen Cloud-Umgebungen integrieren, um eine effiziente Container-Orchestrierung und Anwendungsbereitstellung zu gew\u00e4hrleisten.<\/p>\n<h2 class=\"wp-block-heading\">Erstellen einer Django-Anwendung in PyCharm<\/h2>\n<p>In diesem Tutorial beginnen wir mit der Erstellung einer minimalen Django-Anwendung. Anschlie\u00dfend werden wir die Anwendung containerisieren und sie im letzten Schritt mit Docker Desktop in einem lokalen Kubernetes-Cluster bereitstellen.<\/p>\n<p>Falls Sie noch wenig Erfahrung im Umgang mit dem Django-Framework haben und gerne eine Django-Anwendung von Grund auf entwickeln m\u00f6chten, dann ist dieser <a href=\"https:\/\/blog.jetbrains.com\/pycharm\/2023\/04\/create-a-django-app-in-pycharm\/\">Blogbeitrag<\/a> genau das Richtige f\u00fcr Sie.<\/p>\n<p>Sie k\u00f6nnen den in diesem Tutorial verwendeten Quellcode <a href=\"https:\/\/github.com\/mukulmantosh\/django-kubernetes\" target=\"_blank\" rel=\"noopener\">hier<\/a> aufrufen.<\/p>\n<p>Beginnen wir mit der Erstellung einer neuen <a href=\"https:\/\/blog.jetbrains.com\/pycharm\/2023\/04\/create-a-django-app-in-pycharm\/\">Django-Anwendung in PyCharm<\/a>.<\/p>\n<div class=\"buttons\">\n<div class=\"buttons__row\"><a class=\"btn\" href=\"https:\/\/www.jetbrains.com\/pycharm\/web-development\/django\/\" target=\"\" rel=\"noopener\">Testen Sie PyCharm Pro kostenlos<\/a><\/div>\n<\/div>\n<p>Um Ihr Projekt zu erstellen, starten Sie PyCharm und klicken Sie auf <strong>New Project<\/strong>. Falls PyCharm bereits l\u00e4uft, w\u00e4hlen Sie <strong>File | New Project<\/strong> im Hauptmen\u00fc aus.<\/p>\n<p>Geben Sie wichtige Details wie den Projektnamen, den Ort und den Interpretertyp an, indem Sie entweder <a href=\"https:\/\/docs.python.org\/3\/library\/venv.html\" target=\"_blank\" rel=\"noopener\">venv<\/a> oder eine benutzerdefinierte Umgebung verwenden.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/1y08c3RPd7rqmf5qxcZfrWrzDAekMhwhPIWRa10ipnziCXebOqe8WsMfTXG55efz48CBi5eF_zg7clWjfrHI843CGaueY1wwvBZ0qeei_umc2hAPhLtfuEh0DdLF3NKoSW2iPGbpUCtsEzlF5NKUj0o.png\" width=\"624\" height=\"465\" \/><\/p>\n<p>Klicken Sie dann auf <strong>Create<\/strong>.<\/p>\n<p>PyCharm nimmt Ihnen Arbeit ab, indem es Ihr Projekt einrichtet und die virtuelle Umgebung erstellt.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/odWqcTk4mIote11wJzVTV42umN0Ffu_aSMfv9RRVQs2V9BYcL9_q6dSz-e56unGs-HkDc5GrogOvGqDWJNS3FgYOG7MFAcrXAa6U54Fca1nd9aXo8MjUye5_42sEXIb11rTKyiCAWQWPehKrBeyVMT4.png\" width=\"624\" height=\"351\" \/><\/p>\n<h3 class=\"wp-block-heading\">Gunicorn<\/h3>\n<p>Sobald das Projekt erstellt wurde, installieren Sie <a href=\"https:\/\/gunicorn.org\/\" target=\"_blank\" rel=\"noopener\">Gunicorn<\/a> \u2013 dabei handelt es sich um einen beliebten, in Python geschriebenen HTTP-Server, der eine \u201eWeb Server Gateway Interface\u201c (WSGI) nutzt. Gunicorn ist ein Webserver mit Prefork-Worker-Modell f\u00fcr Python-Webanwendungen. Das Tool wird h\u00e4ufig in Kombination mit Web-Frameworks wie Django, Flask sowie anderen verwendet, um Webanwendungen bereitzustellen und \u00fcber das Internet zug\u00e4nglich zu machen.<\/p>\n<p>Das Toolfenster <strong>Python Packages<\/strong> bietet die schnellste und einfachste M\u00f6glichkeit, Pakete f\u00fcr den aktuell ausgew\u00e4hlten Python-Interpreter in der Vorschau anzuzeigen und zu installieren.<\/p>\n<p>Sie k\u00f6nnen das Toolfenster \u00fcber <strong>View | Tool Windows | Python Packages<\/strong> \u00f6ffnen.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/srzllJqDAcLfQmEuJcLcizPVMAGYJGJ4Y5YnAXyT35Q0ntHxXgZgWu0bkviI6RgnVJAyQltuEnmFqnR0nyTtdaJ3oBJc9ofrEnG0HmzsfXz-_kBMiMGb_YzPBJ_pyMtP-RWRBUBGtUihUPKW4CBQPi8.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> ist eine Python-Bibliothek, die f\u00fcr die Verbindung zu und die Interaktion mit PostgreSQL-Datenbanken verwendet wird. Psycopg 2 bietet eine Python-Schnittstelle f\u00fcr die Arbeit mit PostgreSQL, einem der beliebtesten Open-Source-Managementsysteme f\u00fcr relationalen Datenbanken. Psycopg 2 erm\u00f6glicht es Python-Entwickler*innen, verschiedene Datenbankoperationen wie das Einf\u00fcgen, Aktualisieren und Abrufen von Daten sowie die Ausf\u00fchrung von SQL-Abfragen und die Verwaltung von Datenbankverbindungen aus Python-Programmen heraus durchzuf\u00fchren.<\/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>Bevor Sie <code>psycopg2<\/code> installieren, m\u00fcssen Sie die Abh\u00e4ngigkeiten auf Systemebene einspielen: <code>brew install libpq<\/code> f\u00fcr macOS und <code>apt-get install libpq-dev<\/code> f\u00fcr Linux.<\/p>\n<p>Referenz: <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> ist die Client-Bibliothek f\u00fcr PostgreSQL. Es handelt sich um eine C-Bibliothek, welche die notwendigen Funktionen f\u00fcr Client-Anwendungen bereitstellt, um sich mit PostgreSQL-Datenbankservern zu verbinden, mit ihnen zu interagieren und sie zu verwalten.<\/p>\n<p>Nachdem Sie die entsprechenden \u00c4nderungen vorgenommen haben, aktualisieren Sie den Abschnitt in <code>settings.py<\/code> in Bezug auf <code>DATABASES<\/code>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/qpVWdOZBeTsiOkfJIMn4VybYiIS99u_XxR5_6yYhbLNNI3WpMUwmHTk2g7oaQ1o03GXdY7Y23TtHzNM6ht9-onbAVwvPZ06qgVoIAlpuJjddtuHWJhtr9DO3R8I4PHKCM8vBHvPut02m_k6m_vfQ2uc.png\" width=\"624\" height=\"220\" \/><\/p>\n<p>Achten Sie stets darauf, dass Sie Ihre geheimen Anmeldedaten \u00fcber Umgebungsvariablen \u00fcbermitteln.<\/p>\n<h3 class=\"wp-block-heading\">STATIC_ROOT<\/h3>\n<p>In Django ist <code>STATIC_ROOT<\/code> eine Konfigurationseinstellung, die verwendet wird, um den absoluten Dateisystempfad anzugeben, in dem gesammelte statische Dateien gespeichert werden, wenn Sie den Verwaltungsbefehl <code>collectstatic<\/code> ausf\u00fchren. Zu den statischen Dateien geh\u00f6ren in der Regel CSS, JavaScript, Bilder und andere Assets, die von Ihrer Webanwendung verwendet werden. Die Einstellung <code>STATIC_ROOT<\/code> ist ein wesentlicher Bestandteil der Bereitstellung statischer Dateien in einer Produktionsumgebung.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/D-VP39aKKQITKIi2IG_T6hBWEvUCDzTaLfbrDofs-JlOHmFP51Vl2QYH6dmpufWRhgUTPoOtmyKBj155vIGL8DqWyiR79W3NdiYibTb228Yx2Tj0pwC5bPd5F6BCtbMbTvfKHJ6lDYBlmbLqv1jUmoA.png\" width=\"624\" height=\"323\" \/><\/p>\n<p>Setzen Sie eine Umgebungsvariable f\u00fcr <code>STATIC_ROOT<\/code> in Zeile 127 ein. Diese Variable verweist auf einen Dateipfad, der zu einem persistenten Kubernetes-Volume f\u00fchrt. Die Konfiguration dieses Set-ups wird sp\u00e4ter genauer erl\u00e4utert.<\/p>\n<p>Um statische Dateien zu sammeln, f\u00fchren Sie den folgenden Befehl aus:<\/p>\n<p><code>python manage.py collectstatic<\/code><\/p>\n<p>Dieser Befehl sammelt die statischen Dateien und legt sie im Verzeichnis <code>STATIC_ROOT<\/code> ab. Sie k\u00f6nnen diese Assets dann direkt \u00fcber einen NGINX- oder Apache-Webserver bereitstellen \u2013 ein effizienterer Ansatz f\u00fcr Produktionsumgebungen.<\/p>\n<h3 class=\"wp-block-heading\">Dockerfile<\/h3>\n<p>Ein Dockerfile ist ein einfaches Textdokument, das Direktiven f\u00fcr die Erstellung von Docker-Images enth\u00e4lt.<\/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>: Diese Zeile gibt das Basis-Image f\u00fcr das Docker-Image an, wobei das offizielle Python-3.11-Image von Docker Hub verwendet wird. Die Anwendung wird auf Grundlage dieses Basis-Image erstellt und ausgef\u00fchrt. Python ist bereits vorinstalliert.<\/p>\n<p>2. <strong><code>ENV PYTHONUNBUFFERED 1<\/code><\/strong>: Diese Zeile setzt die Umgebungsvariable <code>PYTHONUNBUFFERED<\/code> auf <code>1<\/code>. H\u00e4ufig wird empfohlen, diese Umgebungsvariable zu setzen, wenn Sie Python in Docker-Containern ausf\u00fchren, um sicherzustellen, dass Python die Ausgabe nicht buffert. Dies erm\u00f6glicht es, Protokolle und Debugging-Informationen f\u00fcr die Anwendung in Echtzeit zu erhalten.<\/p>\n<p>3. <strong><code>WORKDIR \/app<\/code><\/strong>: Diese Zeile setzt das Arbeitsverzeichnis innerhalb des Docker-Containers auf <code>\/app<\/code>. Alle nachfolgenden Befehle werden in diesem Verzeichnis ausgef\u00fchrt.<\/p>\n<p>4. <strong><code>COPY . \/app<\/code><\/strong>: Diese Zeile kopiert den Inhalt des aktuellen Verzeichnisses (das Verzeichnis, in dem sich die Dockerdatei befindet) in das Verzeichnis <code>\/app<\/code> innerhalb des Containers. Dazu geh\u00f6ren Ihr Anwendungscode und s\u00e4mtliche Dateien, die f\u00fcr das Docker-Image ben\u00f6tigt werden.<\/p>\n<p>5. <strong><code>RUN pip install -r requirements.txt<\/code><\/strong>: Diese Zeile f\u00fchrt den Befehl <code>pip install <\/code> aus, um die Python-Abh\u00e4ngigkeiten zu installieren, die in der Datei <code>requirements.txt<\/code> aufgef\u00fchrt sind, welche sich im Verzeichnis <code>\/app<\/code> befindet. Dies ist eine g\u00e4ngige Praxis f\u00fcr Python-Anwendungen, da Sie auf diese Weise die Abh\u00e4ngigkeiten der Anwendung verwalten k\u00f6nnen.<\/p>\n<p>6. <strong><code>EXPOSE 8000<\/code><\/strong>: Diese Zeile teilt Docker mit, dass der Container auf Port 8000 lauscht. Der Port wird nicht wirklich \u00f6ffentlich gemacht. Es handelt sich um eine Metadaten-Deklaration, die angibt, welche Ports der Container verwenden darf.<\/p>\n<p>7. <strong><code>CMD [\"gunicorn\", \"django_kubernetes_tutorial.wsgi:application\", \"--bind\", \"0.0.0.0:8000\"]<\/code><\/strong>: Diese Zeile gibt den Standardbefehl an, der beim Starten des Containers ausgef\u00fchrt wird. Gunicorn wird verwendet, um die Django-Anwendung bereitzustellen. Das Binding von Gunicorn erfolgt so, dass es auf allen Netzwerkschnittstellen (<code>0.0.0.0<\/code>) auf Port 8000 mit der WSGI-Anwendung lauscht, die unter <code>django_kubernetes_tutorial.wsgi:application<\/code> definiert ist.<\/p>\n<h3 class=\"wp-block-heading\">DockerHub<\/h3>\n<p>Besuchen Sie <a href=\"http:\/\/hub.docker.com\" target=\"_blank\" rel=\"noopener\">hub.docker.com<\/a> und melden Sie sich entweder an oder registrieren Sie sich auf der Plattform.<\/p>\n<p>Klicken Sie auf <strong>Create repository<\/strong>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/j6njSAI3cnn1FeazOY-aKjKXXZPQXnTi7tzWC4hK2-FSZ-oUj3vz3oc2yOYFsGyvWbKZZ9B3nAMOLAA4r68yN6GEJFjsGccTMvWW1ph26pXKCpcPkzJjLwBJMC5J_kUXiKVzlSg6ZatV5tol2QXjlnw.png\" width=\"624\" height=\"432\" \/><\/p>\n<p>Als N\u00e4chstes geben Sie den Namen des Repositorys an und stellen die Sichtbarkeit auf \u201ePublic\u201c. Falls Sie mit sensiblen oder vertraulichen Informationen arbeiten, stellen Sie die Sichtbarkeit auf <strong>Private<\/strong>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/Vj1dqmm0ro7S-McOV4FwMNyc2sWoZ-mVmiD0TbptoeAyK44vbSvJIXcRrvcUxcw_CxPtt_Q3R0VTzkLlpuEUdKiM9Po1ZGbTwZFfJgo7yCkRV2Vzjck_q52H4lUcABbHLOE0FvdDZagx1dvHveEkvgc.png\" width=\"624\" height=\"453\" \/><\/p>\n<p>Nachdem das Repository erstellt wurde, m\u00fcssen Sie das Docker-Image generieren und es dann in die Registry pushen.<\/p>\n<p>Bevor Sie den Befehl ausf\u00fchren, vergewissern Sie sich, dass die Datei <code>requirements.txt<\/code> aktuell ist, indem Sie Folgendes ausf\u00fchren:<\/p>\n<p><code>pip freeze &gt; requirements.txt<\/code><\/p>\n<p>Um ein Image zu erstellen, f\u00fchren Sie den folgenden Befehl aus:<\/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>Dieser Befehl h\u00e4ngt von Ihren spezifischen Umst\u00e4nden ab und Sie m\u00fcssen Ihren pers\u00f6nlichen Benutzernamen verwenden.<\/p>\n<p>Anschlie\u00dfend m\u00fcssen Sie sich bei Docker Hub authentifizieren, um das Image in die Registry zu pushen.<\/p>\n<p>Geben Sie den folgenden Befehl in das Terminal ein:<\/p>\n<p><code>docker login<\/code><\/p>\n<p>Geben Sie Ihren Benutzernamen und Ihr Passwort ein. Sobald die Daten erfolgreich authentifiziert wurden, k\u00f6nnen Sie das Image pushen, indem Sie Folgendes ausf\u00fchren:<\/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>Sobald das Image erfolgreich gepusht wurde, k\u00f6nnen Sie die \u00c4nderungen in Docker Hub einsehen.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/R5Dsklfxw_4yJZDE5-Sqg7sA5hsK6Ss_xuqoZMcrsWyLEMHz2Cn7CxrAxMDpD44HfIMihudAfwQope_6FpIXHqgYlgrrGg1bSuYgoJr9nxDpJCzQyQHQatqOpW-R-nywAhkz8FWNyCa0zVy9CX_fLwo.png\" width=\"624\" height=\"239\" \/><\/p>\n<p>Falls Sie nicht vorhaben, weitere Images in die Registry zu pushen, k\u00f6nnen Sie sich abmelden, indem Sie den folgenden Befehl ausf\u00fchren:<\/p>\n<p><code>docker logout<\/code><\/p>\n<p>Falls Sie dieses Image lokal pullen m\u00f6chten, besuchen Sie <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\">Kubernetes-Konfiguration: Schreiben von YAML-Dateien<\/h2>\n<p><strong>Dieser Abschnitt des Tutorials beschreibt das Deployment von Anwendungen in lokalen Kubernetes-Clustern.<\/strong><\/p>\n<p>F\u00fcr dieses Tutorial werden wir Docker Desktop verwenden, aber Sie k\u00f6nnen auch minikube oder kind nutzen.<\/p>\n<h3 class=\"wp-block-heading\">Namespaces<\/h3>\n<p>In Kubernetes sind <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/overview\/working-with-objects\/namespaces\/\" target=\"_blank\" rel=\"noopener\">Namespaces<\/a> virtuelle Partitionen innerhalb eines Clusters, die zur Gruppierung und Isolierung von Ressourcen sowie Objekten verwendet werden. Auf diese Weise k\u00f6nnen Sie mehrere virtuelle Cluster innerhalb eines einzigen physischen Clusters erstellen.<\/p>\n<p>Sie k\u00f6nnen Namespaces mit <code><a href=\"https:\/\/kubernetes.io\/docs\/reference\/kubectl\/\" target=\"_blank\" rel=\"noopener\">kubectl<\/a><\/code>, dem Kubernetes-Befehlszeilen-Tool, oder durch Definition in YAML-Manifesten beim Deployment von Ressourcen erstellen und verwalten.<\/p>\n<ul>\n<li>Wenn Sie Docker Desktop als bevorzugte Plattform f\u00fcr die Ausf\u00fchrung von Kubernetes gew\u00e4hlt haben, m\u00fcssen Sie Kubernetes in den Einstellungen aktivieren, indem Sie auf das Kontrollk\u00e4stchen <strong>Enable Kubernetes<\/strong> klicken.<\/li>\n<\/ul>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/945ORpQLrnTDqbNfZTK-1A8KjfxdrWZCocP992yiPSNgv57t-GLr5RvRV7I5TJurmuVDW24Xm-i7c4eBIC7gV4UrhJJb9PKhEhuqHJmWvpG87mCgema7ZiXljFZ-6-Qxp4aOmvzRr1vjzcpDUJTkf6E.png\" width=\"624\" height=\"368\" \/><\/p>\n<p>F\u00fchren Sie den folgenden Befehl im Terminal aus, um einen Namespace zu erstellen:<\/p>\n<p><code>kubectl create ns django-app<\/code><\/p>\n<h2 class=\"wp-block-heading\">Deployment von Datenbanken mit K8s<\/h2>\n<p>Lassen Sie uns zun\u00e4chst eine PostgreSQL-Instanz in unserem Kubernetes-Cluster in der lokalen Umgebung einrichten.<\/p>\n<h3 class=\"wp-block-heading\">PersistentVolume<\/h3>\n<p>In Kubernetes bezeichnet ein <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/storage\/persistent-volumes\/\" target=\"_blank\" rel=\"noopener\">persistentes Volumen<\/a> (PV) einen Teil des Speichers im Cluster, den ein Administrator bereitgestellt hat. Durch die Speicherung von Daten auf eine Art und Weise, die unabh\u00e4ngig vom Lebenszyklus eines Pods ist, erm\u00f6glichen PV eine entkoppelte und flexiblere Verwaltung sowie Abstraktion von Speicherressourcen. Das bedeutet, dass die Daten auch dann erhalten bleiben, wenn der Pod, der sie verwendet, gel\u00f6scht oder auf einen anderen Knoten im Cluster verschoben wird.<\/p>\n<p>Erstellen wir nun ein persistentes Volumen und nennen wir es <code>pv.yml<\/code>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/7ad-L7W-VSSsV1aouIP2RqA7mHcjvr9TwzQPSbqKtg5ED_ZQigyZzVmqyM7XeEp343xKGKvQpdOUHTrHloOCsWgP5ufp_q43LK97-2gozI6AZ5iXA1b5aiI8yyvFbVYHxKzFMjwYfX4ELEbuZvUOUWM.png\" width=\"624\" height=\"631\" \/><\/p>\n<p>Diese YAML-Konfiguration definiert eine PersistentVolume-Ressource mit dem Namen <code>postgres-pv<\/code> mit einer Kapazit\u00e4t von einem Gigabyte. Die Ressource wird mit dem Zugriffsmodus <code>ReadWriteOnce<\/code> gemountet und \u00fcber einen lokalen Pfad im Dateisystem des Knotens unter <code>\/data\/db<\/code> bereitgestellt. Dieses PV kann verwendet werden, um persistenten Speicher f\u00fcr Pods bereitzustellen, die Zugriff auf ein Verzeichnis im Dateisystem des Knotens ben\u00f6tigen. Es eignet sich f\u00fcr Anwendungen wie PostgreSQL oder andere zustandsbehaftete Dienste, die persistenten Speicher erfordern.<\/p>\n<p>F\u00fcr die Produktion empfehlen wir entweder die Verwendung von Cloud-L\u00f6sungen wie AWS RDS oder Google CloudSQL oder die Verwendung von 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>In Kubernetes bezeichnet <a href=\"https:\/\/kubernetes.io\/docs\/tasks\/configure-pod-container\/configure-persistent-volume-storage\/#create-a-persistentvolumeclaim\" target=\"_blank\" rel=\"noopener\">PersistentVolumeClaim<\/a> (PVC) ein Ressourcenobjekt, das von einem Pod verwendet wird, um eine bestimmte Menge an Speicher mit bestimmten Eigenschaften von einem PV anzufordern. PVCs bieten Anwendungen die M\u00f6glichkeit, Speicherressourcen zu beanspruchen, ohne die Details der zugrunde liegenden Speicherinfrastruktur kennen zu m\u00fcssen.<\/p>\n<p>Durch die Erstellung und Verwendung von PVCs bietet Kubernetes eine M\u00f6glichkeit, Speicherressourcen f\u00fcr Anwendungen dynamisch zuzuweisen sowie zu verwalten und gleichzeitig die zugrunde liegende Speicherinfrastruktur zu abstrahieren, was die Arbeit mit und die Verwaltung von zustandsbehafteten Anwendungen in containerisierten Umgebungen erleichtert.<\/p>\n<p>Lassen Sie uns einen PVC erstellen \u2013 nennen wir ihn <code>pvc.yml<\/code>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/X_Td_1FR8BElq2OK1mODusNTDcPHevnlT18IkCN8E08fT2rfkfsIY2iawyk3dcl7Dxlpr2NeDimz-RtJQbeH5QPqmM0nHWggq-fU4zw_dDbeH-2utnnKWGusBWt-CXO9-BM3M5ygvErDHfOlZtoWh7w.png\" width=\"624\" height=\"577\" \/><\/p>\n<p>Ein PVC fordert Speicherressourcen an und ist an ein PV gebunden, das den eigentlichen Speicher bereitstellt.<\/p>\n<p>Diese YAML-Konfiguration definiert einen PersistentVolumeClaim mit dem Namen <code>postgres-pvc<\/code> innerhalb des Namespace <code>django-app<\/code>. Der PVC fordert einen Gigabyte Speicherplatz mit dem Zugriffsmodus <code>ReadWriteOnce<\/code> an und gibt explizit die StorageClass <code>manual<\/code> an. Dieser PVC soll an ein bestehendes PV mit dem Namen <code>postgres-pv<\/code> gebunden werden. Damit wird dieses Volume f\u00fcr die Verwendung durch Pods innerhalb des Namespace <code>django-app<\/code> reserviert, die auf diesen PVC verweisen.<\/p>\n<h3 class=\"wp-block-heading\">ConfigMap<\/h3>\n<p>In Kubernetes bezeichnet eine <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/configuration\/configmap\/\" target=\"_blank\" rel=\"noopener\">ConfigMap<\/a> ein API-Objekt, das zum Speichern von Konfigurationsdaten in Schl\u00fcssel-Wert-Paaren verwendet wird. ConfigMaps bieten eine M\u00f6glichkeit, die Konfigurationsdaten vom Anwendungscode zu entkoppeln. So lassen sich Konfigurationen leichter verwalten und aktualisieren, ohne dass Container ver\u00e4ndert und neu bereitgestellt werden m\u00fcssen. Sie sind besonders n\u00fctzlich f\u00fcr die Konfiguration von Anwendungen, Microservices und anderen Komponenten innerhalb eines Kubernetes-Clusters.<\/p>\n<p>Lassen Sie uns eine ConfigMap erstellen \u2013 nennen wir sie <code>cm.yml<\/code>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/wvDyPcHd888DKzevEdpSAURy5e6IzinJthTUHK5z58-BnPhFx0bXrnaexUXpzJkhbXkbZa-zgdjcttbKIvI01hznnCrw9-E9LAmSlMD4o1GDQ-99rjgKgqIF9vXsacJ3_K_XPckDmAWrpEvFDYmOw_Y.png\" width=\"624\" height=\"524\" \/><\/p>\n<p>Obwohl in diesem Tutorial ConfigMaps verwendet werden, wird aus Sicherheitsgr\u00fcnden empfohlen, sensible Anmeldedaten in Kubernetes <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/configuration\/secret\/\" target=\"_blank\" rel=\"noopener\">Secrets<\/a> zu speichern oder Alternativen wie Bitnami Sealed Secrets, AWS Parameter Store oder HashiCorp Vault in Erw\u00e4gung zu ziehen.<\/p>\n<h3 class=\"wp-block-heading\">Deployment<\/h3>\n<p>In Kubernetes bezeichnet ein <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/workloads\/controllers\/deployment\/\" target=\"_blank\" rel=\"noopener\">Deployment<\/a> ein Ressourcenobjekt, das zur Verwaltung der Bereitstellung und Skalierung von Anwendungen verwendet wird. Ein Deployment ist Teil der Kubernetes-API-Gruppe und bietet eine deklarative M\u00f6glichkeit, den gew\u00fcnschten Zustand Ihrer Anwendung zu definieren und zu verwalten.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/fu5av6IILewmdL6cpFurozbGqH6gWdutfRmxwUb-0FGPs6j05xNSE4jwYeDsD2BKA_GE8WOaTqx2C85DX2mkz21LPzBFl_BHcSD-lIXthE0zaYSgUEWZ-gIQB07qIZ0V-iIm0cWiBCpmHcqvlpuirso.png\" width=\"624\" height=\"735\" \/><\/p>\n<p>Ein Deployment ist eine Kubernetes-Ressource auf h\u00f6herer Ebene, die f\u00fcr die Verwaltung und Skalierung von Anwendungs-Pods verwendet wird.<\/p>\n<p>Diese YAML-Konfiguration definiert ein Deployment namens <code>postgres<\/code> im Namespace <code>django-app<\/code>. Die Konfiguration stellt eine einzelne Replik einer PostgreSQL-Datenbank (Version 16.0) mit persistentem Speicher bereit. Der Datenbank-Pod tr\u00e4gt die Bezeichnung <code>app: postgresdb<\/code> und der Speicher wird von einem PVC namens <code>postgres-pvc<\/code> bereitgestellt. Die Konfiguration und die Anmeldedaten f\u00fcr den PostgreSQL-Container werden \u00fcber eine ConfigMap namens <code>db-secret-credentials<\/code> \u00fcbermittelt.<\/p>\n<h3 class=\"wp-block-heading\">Service<\/h3>\n<p>In Kubernetes bezeichnet ein <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/services-networking\/service\/\" target=\"_blank\" rel=\"noopener\">Service<\/a> ein Ressourcenobjekt, das verwendet wird, um eine Gruppe von Pods als Netzwerkdienst bereitzustellen. Services erm\u00f6glichen die Netzwerkkommunikation zwischen verschiedenen Teilen Ihrer Anwendung, die in einem Kubernetes-Cluster laufen, und bieten einen stabilen Endpunkt f\u00fcr den Zugriff von Clients auf diese Teile. Services abstrahieren die zugrunde liegende Netzwerkinfrastruktur und erleichtern so die Verbindung und Auffindung der Komponenten Ihrer Anwendung.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/p4NneUHgkfOqr2cp1bIZVYEH1weBKgZ5cWjPOgnATHQGdQwULM9BlzPRJXyPqf0v3FqHrztZ9rmL6P3RSInOE6vNC21UenOjGz-872-KzklWAQGm2Rr3uOKIQMRMlLvCIHiswccwGtI-eVeBI7b61EI.png\" width=\"624\" height=\"525\" \/><\/p>\n<p>Diese YAML-Konfiguration definiert einen NodePort-Service mit dem Namen <code>postgres-service<\/code> innerhalb des Namespace <code>django-app<\/code>. Die Konfiguration stellt den PostgreSQL-Service, der in Pods mit der Bezeichnung \u201e<code>app: postgresdb<\/code>\u201c l\u00e4uft, auf Port 5432 innerhalb des Clusters zur Verf\u00fcgung. Externe Clients k\u00f6nnen \u00fcber Port 30004 von jeder IP-Adresse eines Node aus auf den Service zugreifen. Dieser Service bietet eine M\u00f6glichkeit, die PostgreSQL-Datenbank von au\u00dferhalb des Kubernetes-Clusters zug\u00e4nglich zu machen.<\/p>\n<h2 class=\"wp-block-heading\">Erstellen von YAML-Konfigurationen f\u00fcr eine Django-Anwendung<\/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\/09\/FJCpL5-QEQHMI7w0j2XnboyV-y6NOoRZPzOd3GXJju2CLizk2kmnXEBcDaUSAOuvHfFrOcKel3VcVs0fimdgovM9NSn5aw31hDTYSkyAgYSK14EqO-bj2CgL2p-6h20IDY0Ei-szg63ZKYIr77kIOZs.png\" width=\"624\" height=\"525\" \/><\/p>\n<p>Diese YAML-Datei definiert ein PersistentVolume mit dem Namen <code>staticfiles-pv<\/code> mit einer Speicherkapazit\u00e4t von einem Gigabyte, auf dem mehrere Pods gleichzeitig lesen und schreiben k\u00f6nnen. Der Speicher wird von einem lokalen Hostpfad bereitgestellt, der sich in <code>\/data\/static<\/code> befindet. Die statischen Django-Dateien werden an diesem Ort gespeichert.<\/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\/09\/01PqOjeQXzeBx4RIkSdTRXttHzaEZexNL_OsQPfaCiOqbLTY85QhXOSCx0ojmGxSINUpuO4FhcZLk4Sl5YosJISr4GBMWeecUeObtbGiGXR9k_uQftED-89TurtbyVoaujef1ixQ4FQ8zSoa8j2MWp4.png\" width=\"624\" height=\"504\" \/><\/p>\n<p>Diese YAML-Datei definiert einen PVC namens <code>staticfiles-pvc<\/code> im Namespace <code>django-app<\/code>. Es wird Speicherplatz mit einer Kapazit\u00e4t von mindestens einem Gigabyte von einem PV mit der StorageClass \u201emanual\u201c angefordert und es wird angegeben, dass <code>ReadWriteMany<\/code>-Zugriff ben\u00f6tigt wird. Der Claim bindet sich ausdr\u00fccklich an ein bestehendes PV mit dem Namen <code>staticfiles-pv<\/code>, um den Speicherbedarf zu decken. Dadurch k\u00f6nnen Pods im Namespace <code>django-app<\/code> diesen PVC verwenden, um auf den vom zugeh\u00f6rigen PV bereitgestellten Speicher zuzugreifen und diesen zu nutzen.<\/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\/09\/zWM1NlnXZNXcXFBqcJo2iDvVn1HsVKmSqrrWASDo8g7iQFtHKQksufKcirqeKrpNKhLPw-EBLT5BPAapQDSvNTRF1Z9yzZlTO2bxOs2PdQNJYSwMdkDKXnMQJekawNLJe7FzJXuhAcyjKIZ6wjBw28c.png\" width=\"624\" height=\"459\" \/><\/p>\n<p>Diese YAML-Datei definiert eine ConfigMap namens <code>app-cm<\/code> im Namespace <code>django-app<\/code> und enth\u00e4lt verschiedene Schl\u00fcssel-Wert-Paare, die Konfigurationsdaten speichern. Diese ConfigMap kann von Pods oder anderen Ressourcen innerhalb des Namespace <code>django-app<\/code> verwendet werden, um auf Konfigurationseinstellungen wie Datenbank-Verbindungsinformationen und statische Dateipfade zuzugreifen.<\/p>\n<h3 class=\"wp-block-heading\">Deployment<\/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>Diese YAML-Datei definiert ein Deployment mit dem Namen <code>django-app-deploy<\/code> im Namespace <code>django-app<\/code>. Es wird eine Replik (Pod) erstellt, auf der ein Container mit einem bestimmten Docker-Image und einer bestimmten Konfiguration l\u00e4uft. Der Pod ist mit zwei Volumes verbunden, <code>postgres-db-storage<\/code> und <code>staticfiles<\/code>, die durch PVCs abgesichert sind. Der Container ist so konfiguriert, dass er Umgebungsvariablen aus einer ConfigMap namens <code>app-cm<\/code> verwendet und auf Port 8000 lauscht. Die Volumen werden an bestimmten Pfaden innerhalb des Containers gemountet, um den Zugriff auf den Datenbankspeicher und statische Dateien zu erm\u00f6glichen. Dieses Deployment ist eine g\u00e4ngige Methode, um eine Django-Anwendung mit Kubernetes auszuf\u00fchren.<\/p>\n<p>Falls Sie daran interessiert sind, Bilder aus einer privaten Registry zu pullen, dann k\u00f6nnen Sie <a href=\"https:\/\/kubernetes.io\/docs\/tasks\/configure-pod-container\/pull-image-private-registry\/\" target=\"_blank\" rel=\"noopener\">hier<\/a> mehr erfahren.<\/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\/09\/Z0wfNZT1VrOT-9FznBYsl1LGu_b635fuSFtpoLRacsqfBiLAOi_tw7p87Ao8p9ZPx8-84e5NFerr3krbB5OsW2Vo9ps_hAvlaXV-2ga2RBLsm7vfPJ0rUUyzvvBg4NoQ0c_K7BO8I4u5vOgbUT1BBU.png\" width=\"624\" height=\"577\" \/><\/p>\n<p>Der Service lauscht auf Port 8000 und leitet den eingehenden Traffic an Pods weiter, die als <code>app: django-application<\/code> gekennzeichnet sind. Dies ist eine g\u00e4ngige Konfiguration f\u00fcr die Freigabe und die Lastenverteilung von Webanwendungen in einem Kubernetes-Cluster, in dem mehrere Instanzen derselben Anwendung ausgef\u00fchrt werden. Der Service sorgt daf\u00fcr, dass der Traffic gleichm\u00e4\u00dfig verteilt wird.<\/p>\n<h2 class=\"wp-block-heading\">NGINX<\/h2>\n<p><a href=\"https:\/\/www.nginx.com\/\" target=\"_blank\" rel=\"noopener\">NGINX<\/a> ist ein leistungsstarker Web- und Reverse-Proxy-Server, der f\u00fcr seine Geschwindigkeit, Zuverl\u00e4ssigkeit und Skalierbarkeit bekannt ist. Er wickelt den Webtraffic, die Lastverteilung sowie die Bereitstellung von Inhalten effizient ab und ist daher eine beliebte Wahl f\u00fcr Websites und Anwendungen.<\/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\/09\/Itj5_NS6IlHVlnJ49MnCsE2Hu8x0X7X2EW_Nm3qy7ujShq1mBmawFBCFk4iKbsDZ890n2xTJFGs1TlmRrZ0QDqL35IC6mj07cq8tz1GVisueNR4cDsqPZW1gTD5j7ZoTBJcWba5VpFXXZAwagXE0y60.png\" width=\"624\" height=\"460\" \/><\/p>\n<p>Diese YAML-Datei definiert eine Kubernetes-ConfigMap namens <code>nginx-cm<\/code> im Namespace <code>django-app<\/code> und enth\u00e4lt ein Schl\u00fcssel-Wert-Paar, wobei der Schl\u00fcssel <code>default.conf<\/code> und der Wert eine mehrzeilige NGINX-Konfigurationsdatei ist, welche die Anfrage an den Backend-Server weiterleitet.<\/p>\n<h3 class=\"wp-block-heading\">Bereitstellung<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/4ErlDKYewor2Owj0YrtS7O01WkXzFkTBHoN5LGlEGBfvX_MGUzXgxF0ur0eDSIBD2HdJlbg4zpAE1v1OwT_LkSYR3RS4hQFnW3jwX_wEjE_L4cCIeuHI-wspyiTGaw6z8JnHXw8buX0yvbWsr3eSNDo.png\" width=\"624\" height=\"727\" \/><\/p>\n<p>Diese YAML-Datei definiert ein Deployment, das Pods erstellt und verwaltet, auf denen ein NGINX-Container mit bestimmten Volumen und Konfigurationen l\u00e4uft. Das Deployment stellt sicher, dass eine Replik dieses Pods immer im Namespace <code>django-app<\/code> l\u00e4uft. Au\u00dferdem \u00fcberschreibt es die Standardkonfiguration von NGINX, indem es diese durch die ConfigMap <code>nginx-cm<\/code> ersetzt.<\/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\/09\/PqinRZHVtGiapAjd5aD4-mA4sRmxTlRnfkSl5y6GRrPY4KpD2MsuMkkKspX1J-JHNwEdSlxb_Vtuex3SRd0caY4x-zI744KCZ-AKgjYc976FWHiEZVl9dM-oyJuPgE-DoEyU46RLokubkL-otadMZ40.png\" width=\"624\" height=\"631\" \/><\/p>\n<p>Diese YAML-Konfiguration erstellt einen Kubernetes-Service namens <code>nginx-service<\/code> im Namespace <code>django-app<\/code>. Die Konfiguration stellt Pods mit der Bezeichnung <code>app:nginx<\/code> auf Port 80 innerhalb des Clusters zur Verf\u00fcgung und macht den Service auch auf NodePort 30005 auf jedem Cluster-Knoten zug\u00e4nglich. Dadurch kann der externe Traffic die Pods, auf denen die NGINX-Anwendung l\u00e4uft, \u00fcber den NodePort-Service erreichen.<\/p>\n<h2 class=\"wp-block-heading\">Verwaltung von Batch-Workloads mit Kubernetes-Jobs<\/h2>\n<p>In Kubernetes bezeichnet ein <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/workloads\/controllers\/job\/\" target=\"_blank\" rel=\"noopener\">Job<\/a> ein Ressourcenobjekt, das eine einzelne Arbeitseinheit oder eine endliche Aufgabe darstellt. Jobs sind so konzipiert, dass sie Aufgaben bis zum Ende ausf\u00fchren, wobei eine bestimmte Anzahl von Aufgaben erfolgreich abgeschlossen werden muss.<\/p>\n<h3 class=\"wp-block-heading\">Datenbankmigration<\/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>Diese YAML-Konfiguration definiert einen Kubernetes-Job namens <code>django-db-migrations<\/code> im Namespace <code>django-app<\/code>. Der Job f\u00fchrt einen Container mit einem benutzerdefinierten Docker-Image f\u00fcr Django-Migrationen aus und bindet einen PVC ein, um Speicherplatz f\u00fcr datenbankbezogene Dateien bereitzustellen. Falls der Job fehlschl\u00e4gt, kann er bis zu 15 Mal wiederholt werden. Der Pod wird nach Abschluss noch 100 Sekunden lang beibehalten. Dieser Job erstellt neue Tabellen in PostgreSQL.<\/p>\n<h3 class=\"wp-block-heading\">Statische Dateien<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/41sZvQpth3_7rpCpoCuUY0k588q9aANJoVs6DxWJSGF2qvZQDo0u9jcxEbjjEb9IQ3oLUTNkboM61EoKbGOxsnsJFHfzLYjlwFqq8TXtuYNLZne2h358Yn-MyoNrk8JVGRpu0erDPr4yHqevTlXzxtY.png\" width=\"624\" height=\"643\" \/><\/p>\n<p>Diese YAML-Konfiguration definiert einen Kubernetes-Job namens <code>django-staticfiles<\/code> im Namespace <code>django-app<\/code>. Der Job f\u00fchrt einen Container mit einem benutzerdefinierten Docker-Image aus, um statische Dateien f\u00fcr eine Django-Anwendung zu sammeln, und mountet einen PVC, um die statischen Dateien zu speichern. Falls der Job fehlschl\u00e4gt, kann er bis zu dreimal wiederholt werden. Der Pod wird nach Abschluss noch f\u00fcr 100 Sekunden zu Debugging-Zwecken beibehalten. Dieser Job kopiert die statischen Dateien in den mountPath, der <code>\/data\/static<\/code> lautet.<\/p>\n<h2 class=\"wp-block-heading\">Starten der Anwendung<\/h2>\n<p>Um die Anwendung zu starten, wechseln Sie in das Verzeichnis <code>k8s<\/code> und f\u00fchren Sie den folgenden Befehl aus:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/t7jeYgU4ZqFBXc-2WwudXN8V4cibZZt5M0Tob6-0zV570MXlHkql6QBw4Oxibl5WWdGnfB9510sYpfjnIhsjvs9AObRuhIrR91r8b3Q8Vu2pJYuLfFhm2ixDw7Oddkvh-5tP3nUADGAu5DX725cJ6YI.png\" width=\"624\" height=\"392\" \/><\/p>\n<p>Verwenden Sie nach dem Deployment der Anwendung den folgenden Befehl, um den Status der laufenden Pods zu \u00fcberpr\u00fcfen:<\/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\/09\/PiIyWEPFMtnrTpvspZ6gc65Z81xUgAbiqSQ2XgphxJ229PKgASge2sNzU0_YG_vC-k_hFBMNH1lF1CTBbY5oDWnNDne1Cf3nI809BP6bIUr0xHvRbNsOI_TkLwLwu7QFmcnKBarHlsK7tu8dBsqjgMA.png\" width=\"624\" height=\"108\" \/><\/p>\n<h3 class=\"wp-block-heading\">Erstellen eines Superusers in Django<\/h3>\n<p>Sobald alle Ihre Anwendungen eingerichtet sind, erstellen Sie einen Superuser, mit dem Sie sich in den Django-Admin-Bereich einloggen k\u00f6nnen.<\/p>\n<p>F\u00fchren Sie den folgenden Befehl aus, um die Liste der laufenden Pods einzusehen:<\/p>\n<p><code>kubectl get pods -n django-app<\/code><\/p>\n<p>Um in die Container-Shell zu gelangen, f\u00fchren Sie Folgendes aus:<\/p>\n<p><code>kubectl exec -it  -n django-app -- sh<\/code><\/p>\n<p>F\u00fchren Sie anschlie\u00dfend Folgendes aus:<\/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\/09\/y65m6YcxuejXhXIdGCr7_aqy_gGj4FhrtWsddWZgxWv2nBEnCedmQoPNupQQ0JRn7sMMwElFo09TMoPImbR6v2Sc3rirDBW6sLK2daaNbh3NDfvT83DrtTDHPiutsdc3vKC-V5nfXNYjrIzt26igd_o.png\" width=\"624\" height=\"197\" \/><\/p>\n<p>Sobald Sie den Superuser erfolgreich erstellt haben, \u00f6ffnen Sie <a href=\"http:\/\/127.0.0.1:30005\" target=\"_blank\" rel=\"noopener\">http:\/\/127.0.0.1:30005<\/a> in einem Browser. Sie werden auf die Standard-Begr\u00fc\u00dfungsseite weitergeleitet.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/tpozSD_EtSgHLFQ1ud5EV4_OJFdmgSUGlS6u4iEMI9rVrduVIlaJS1NHoD4D6WhjCdC7oASEobsfm9ar0cWUxEydoSVsTfuoOWTJw-5usNmJrusEyD50SGJYbKUWU_BLgdbipbfYeeKBcW1ecK8_gsQ.png\" width=\"624\" height=\"321\" \/><\/p>\n<p>Wechseln Sie dann \u00fcber <a href=\"http:\/\/127.0.0.1:30005\/admin\" target=\"_blank\" rel=\"noopener\">http:\/\/127.0.0.1:30005\/admin<\/a> in den Django-Admin-Bereich.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/WcwAvYrT3499Hr32HybiT6VuuanZh8keoS95n0N3-lasuJ8z4rsmQydIp4MLCGVORtQLZnECw2y3IKB9e2J8Mg8ScRF1HpvD-bu68MSYv_Ti_GBr3P4Y0gtc8B6aaUfg2kRF2VLj0NXUWLDRCiy3sjg.png\" width=\"624\" height=\"447\" \/><\/p>\n<p>Geben Sie den soeben vergebenen Benutzernamen und das entsprechende Passwort ein.<\/p>\n<p>Sobald Sie sich authentifiziert haben, werden Sie zur Django-Administrationsseite weitergeleitet.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/u4my3QzTYVifPI-wEPH__wlI6M7tUITtpDeoPnoK6bM6NC2nSAutEumLtR3CScqWcEFrnH8KrkH3k2QMna_Yyz2mnTO1qF8idfFOiG263r8k7Y_6wU-QsbihmY7Av08sRX_05wSc72Nw9DKnFiYOgeE.png\" width=\"624\" height=\"400\" \/><\/p>\n<p>Wenn Sie versuchen, sich \u00fcber localhost:30005\/admin anzumelden, erhalten Sie m\u00f6glicherweise den Fehler <em>403 Forbidden<\/em> (CSRF).<\/p>\n<p>Sie k\u00f6nnen diesen in der Datei <code>settings.py<\/code> unter <code>CSRF_TRUSTED_ORIGINS<\/code> beheben.<\/p>\n<p><code>CSRF_TRUSTED_ORIGINS<\/code> ist eine <a href=\"https:\/\/docs.djangoproject.com\/en\/4.2\/ref\/settings\/#std-setting-CSRF_TRUSTED_ORIGINS\" target=\"_blank\" rel=\"noopener\">Einstellung <\/a>in Django, die verwendet wird, um eine Liste von vertrauensw\u00fcrdigen Origins f\u00fcr den Schutz vor Cross-Site-Request-Forgery (CSRF) anzugeben. CSRF ist eine Sicherheitsl\u00fccke, die auftreten kann, wenn ein Angreifer einen Benutzer dazu verleitet, unwissentlich eine unerw\u00fcnschte Anfrage an eine Webanwendung zu stellen. Um dies zu verhindern, enth\u00e4lt Django eingebauten CSRF-Schutz.<\/p>\n<p><code>CSRF_TRUSTED_ORIGINS<\/code> erm\u00f6glicht es Ihnen, eine Liste von Origins (Websites) zu definieren, von denen CSRF-gesch\u00fctzte Anfragen akzeptiert werden. Jede Anfrage, die von einem Origin ausgeht, der nicht in dieser Liste enthalten ist, wird als potenziell b\u00f6sartig eingestuft und entsprechend blockiert.<\/p>\n<p>Diese Einstellung kann verwendet werden, um bestimmte Cross-Origin-Anfragen an Ihre Django-Anwendung zuzulassen und gleichzeitig die Sicherheit gegen CSRF-Angriffe zu gew\u00e4hrleisten. Das ist besonders hilfreich in Szenarien, in denen Ihre Anwendung mit anderen Webdiensten oder APIs interagieren muss, die auf verschiedenen Domains gehostet werden.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/DTDVeAkR8-rHFCbeoMqWHHSSCBDNjQ96OLDPcexK0TVmbzk9bRgHajXVqFiy4r_yTd6mE1GM7TGuCwYcTJ0owbKhhjLxaJlgE9_KjgEk6APxHsHsPXtdRtJwRbYgejaoHuxpWzUEsaUAt3oHjzrTvVM-1.png\" width=\"624\" height=\"428\" \/><\/p>\n<p>Falls Sie GUI-Tools wie <a href=\"https:\/\/kubernetes.io\/docs\/tasks\/access-application-cluster\/web-ui-dashboard\/\" target=\"_blank\" rel=\"noopener\">Kubernetes Dashboard<\/a> verwenden, k\u00f6nnen Sie Ihre laufenden Pods, Deployments, persistenten Volumes usw. leicht visualisieren.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/2lssXclYX6wG01Kf5SX7hng9Yxd0JuqeFAYR-UDdEBIXJyzNZItFQFGMT1UxAifh3FywhRmaWzrwafuv0L9nciqBE7yf09hf7sYmpijHkrZoe_MXeBIow9q_CrlZAUHLmNHDzMTcO8XZqWHOxjZHcnw.png\" width=\"624\" height=\"325\" \/><\/p>\n<h2 class=\"wp-block-heading\">Kubernetes-Unterst\u00fctzung in PyCharm<\/h2>\n<p>PyCharm verf\u00fcgt \u00fcber einen erweiterten Editor und umfassende Laufzeitunterst\u00fctzung, die speziell f\u00fcr Kubernetes entwickelt wurden. Diese leistungsstarken Tools bieten eine Vielzahl von Funktionen, die darauf abzielen, Ihre Kubernetes-Verwaltung zu optimieren, z. B.:<\/p>\n<ul>\n<li>Durchsuchen von Cluster-Objekten, Extrahieren und Bearbeiten ihrer Konfigurationen und Beschreiben derselben.<\/li>\n<li>Anzeige von Ereignissen.<\/li>\n<li>Ansehen und Herunterladen von Pod-Protokollen.<\/li>\n<li>Anh\u00e4ngen der Pod-Konsole.<\/li>\n<li>Ausf\u00fchren von Shell in Pods.<\/li>\n<li>Weiterleitung von Ports an einen Pod.<\/li>\n<li>Anwenden von Ressourcen-YAML-Konfigurationen aus dem Editor.<\/li>\n<li>L\u00f6schen von Ressourcen aus dem Cluster.<\/li>\n<li>Vervollst\u00e4ndigung der ConfigMap- und Secret-Eintr\u00e4ge aus dem Cluster.<\/li>\n<li>Konfigurieren der Pfade zu <code>kubectl<\/code>.<\/li>\n<li>Konfigurieren der benutzerdefinierten <code>kubeconfig<\/code>-Dateien; global und pro Projekt.<\/li>\n<li>Wechseln von Kontexten und Namespaces.<\/li>\n<li>Verwendung des API-Schemas (einschlie\u00dflich CRD) des aktiven Clusters zur Bearbeitung von Ressourcenmanifesten.<\/li>\n<\/ul>\n<p>Sehen Sie sich dieses <a href=\"https:\/\/www.youtube.com\/watch?v=NqotF4kRvTc\" target=\"_blank\" rel=\"noopener\">Video<\/a> an, um mehr \u00fcber die Arbeit mit Kubernetes in PyCharm Professional zu erfahren.<\/p>\n<p>Testen Sie PyCharm kostenlos f\u00fcr Ihre Kubernetes-Aufgaben!<\/p>\n<div class=\"buttons\">\n<div class=\"buttons__row\"><a class=\"btn\" href=\"https:\/\/www.jetbrains.com\/de-de\/pycharm\/download\/\" target=\"\" rel=\"noopener\">PYCHARM HERUNTERLADEN<\/a><\/div>\n<\/div>\n<h2 class=\"wp-block-heading\">Weitere Informationen<\/h2>\n<p>Haben Sie bereits ein umfassenderes Verst\u00e4ndnis von Kubernetes? Dann unternehmen Sie den n\u00e4chsten Schritt in Ihrer Programmierkarriere, indem Sie sich mit Cloud-L\u00f6sungen besch\u00e4ftigen. Sehen Sie sich unsere Tutorials zu <a href=\"https:\/\/www.jetbrains.com\/pycharm\/guide\/tutorials\/fastapi-aws-kubernetes\/\" target=\"_blank\" rel=\"noopener\">AWS EKS<\/a> und <a href=\"https:\/\/www.jetbrains.com\/pycharm\/guide\/tutorials\/cloud-code-pycharm\/\" target=\"_blank\" rel=\"noopener\">Google Kubernetes Engine<\/a> an.<\/p>\n<p><strong>Autor des urspr\u00fcnglichen Blogposts<\/strong><\/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":811,"featured_media":572183,"comment_status":"closed","ping_status":"closed","template":"","categories":[8377],"tags":[963,5635,154],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/pycharm\/572015"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/pycharm"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/types\/pycharm"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/users\/811"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/comments?post=572015"}],"version-history":[{"count":8,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/pycharm\/572015\/revisions"}],"predecessor-version":[{"id":600712,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/pycharm\/572015\/revisions\/600712"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/media\/572183"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/media?parent=572015"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/categories?post=572015"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/tags?post=572015"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/cross-post-tag?post=572015"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}