{"id":571260,"date":"2025-05-28T16:32:00","date_gmt":"2025-05-28T15:32:00","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=pycharm&#038;p=571260"},"modified":"2025-09-15T09:32:18","modified_gmt":"2025-09-15T08:32:18","slug":"implementacion-de-aplicaciones-de-django-en-kubernetes","status":"publish","type":"pycharm","link":"https:\/\/blog.jetbrains.com\/es\/pycharm\/2025\/05\/implementacion-de-aplicaciones-de-django-en-kubernetes\/","title":{"rendered":"Implementaci\u00f3n de aplicaciones de Django en Kubernetes"},"content":{"rendered":"<p>Como una plataforma de orquestaci\u00f3n de contenedores de c\u00f3digo abierto que automatiza la implementaci\u00f3n, el escalado y el equilibrio de carga, Kubernetes ofrece una resiliencia inigualable en la gesti\u00f3n de sus aplicaciones de Django<strong>. <\/strong><\/p>\n<p>Tanto si est\u00e1 lanzando un proyecto a peque\u00f1a escala como si est\u00e1 gestionando una aplicaci\u00f3n compleja, Kubernetes proporciona un entorno robusto para mejorar su aplicaci\u00f3n de Django, y garantiza que est\u00e9 preparada para satisfacer las necesidades del desarrollo web moderno.<\/p>\n<p>Al automatizar la implementaci\u00f3n, el escalado y el funcionamiento de aplicaciones en contenedores, <a href=\"https:\/\/kubernetes.io\/\" target=\"_blank\" rel=\"noopener\">Kubernetes<\/a> (o K8s) ofrece numerosas ventajas a las organizaciones en el acelerado sector tecnol\u00f3gico.<\/p>\n<p>Tanto si es un desarrollador de Django que busca mejorar sus habilidades de implementaci\u00f3n como un entusiasta de Kubernetes que quiere explorar la integraci\u00f3n de Django, esta gu\u00eda tiene algo para todos.<\/p>\n<p><!--more--><\/p>\n<p>La introducci\u00f3n a este tutorial explora la relaci\u00f3n simbi\u00f3tica entre Django y Kubernetes, lo que le permite crear contenedores para su aplicaci\u00f3n web, distribuir cargas de trabajo en cl\u00fasteres y garantizar una alta disponibilidad.<\/p>\n<h2 class=\"wp-block-heading\">Django<\/h2>\n<p>Django es un marco de trabajo web Python de alto nivel que se erige como un faro de eficiencia y simplicidad en el mundo de desarrollo web. Django naci\u00f3 de la necesidad de crear aplicaciones web r\u00e1pidas, robustas y f\u00e1ciles de mantener, y se ha convertido en la opci\u00f3n preferida de desarrolladores y organizaciones.<\/p>\n<p>En su n\u00facleo, Django adopta la filosof\u00eda \u00abpilas incluidas\u00bb, y ofrece una amplia gama de herramientas, bibliotecas y convenciones integradas que facilitan el proceso de desarrollo. Simplifica tareas complejas como el enrutamiento de URL, la integraci\u00f3n de bases de datos y la autenticaci\u00f3n de usuarios, lo que permite a los desarrolladores centrarse en la creaci\u00f3n de sus aplicaciones.<\/p>\n<p>Una de las principales ventajas de Django es su adhesi\u00f3n al principio \u00ablibre de repeticiones\u00bb (don\u2019t repeat yourself, DRY), lo que reduce la redundancia y mejora la mantenibilidad del c\u00f3digo. Tambi\u00e9n sigue el patr\u00f3n arquitect\u00f3nico modelo-vista-controlador (MVC), lo que hace que las aplicaciones sean estructuradas y f\u00e1ciles de gestionar.<\/p>\n<p>Django tambi\u00e9n da prioridad a la seguridad, por lo que es menos propenso a vulnerabilidades web comunes. Incluye funcionalidades como la protecci\u00f3n contra \u00abcross-site scripting\u00bb (XSS) o \u00abcross-site request forgery\u00bb (CSRF) sin necesidad de configuraciones adicionales. Django ofrece una potente combinaci\u00f3n de velocidad, simplicidad y seguridad, y es una opci\u00f3n ideal para los desarrolladores que buscan crear aplicaciones web robustas y llenas de funcionalidades con un esfuerzo m\u00ednimo.<\/p>\n<h2 class=\"wp-block-heading\">Orquestadores de contenedores<\/h2>\n<p>Los orquestadores de contenedores son herramientas esenciales para gestionar y automatizar la implementaci\u00f3n, el escalado y el funcionamiento de aplicaciones en contenedores. Hay varios tipos de orquestadores de contenedores disponibles en el mercado. Estos son algunos de los m\u00e1s populares:<\/p>\n<p>1. <strong>Kubernetes<\/strong>, la plataforma de orquestaci\u00f3n de contenedores de c\u00f3digo abierto, ofrece un entorno robusto y adaptable para gestionar aplicaciones en contenedores. Automatiza tareas como el escalamiento, el equilibrio de carga y las comprobaciones de estado de contenedores con un amplio ecosistema de extensiones.<\/p>\n<p>2. <strong>Docker Swarm<\/strong> es una soluci\u00f3n de orquestaci\u00f3n de contenedores proporcionada por Docker. Dise\u00f1ado para ser f\u00e1cil de configurar y utilizar, es una buena opci\u00f3n para aplicaciones m\u00e1s peque\u00f1as u organizaciones que ya utilizan Docker, ya que emplea la misma interfaz de l\u00ednea de comandos y API que Docker.<\/p>\n<p>3. <strong>OpenShift<\/strong> es una plataforma empresarial de Kubernetes desarrollada por Red Hat. A\u00f1ade herramientas de desarrollo y operativas a Kubernetes, lo que simplifica la implementaci\u00f3n y la gesti\u00f3n de aplicaciones en contenedores.<\/p>\n<p>4. <strong>Nomad<\/strong>, desarrollado por HashiCorp, es un orquestador \u00e1gil y f\u00e1cil de usar capaz de gestionar contenedores y aplicaciones sin contenedores.<\/p>\n<p>5. <strong>Apache Mesos<\/strong> es un kernel de sistemas distribuidos de c\u00f3digo abierto, y DC\/OS (Data Center Operating System) es una plataforma de calidad empresarial creada en Mesos. DC\/OS ampl\u00eda Mesos con funcionalidades adicionales para gestionar y escalar aplicaciones en contenedores.<\/p>\n<p>Los equipos de software trabajan principalmente con plataformas gestionadas ofrecidas por conocidos proveedores en la nube como AWS, Google Cloud Platform y Azure. Estos proveedores en la nube ofrecen servicios como Amazon EKS, Google GKE y Azure AKS, todos los cuales son soluciones administradas de Kubernetes. Estos servicios simplifican la configuraci\u00f3n, expansi\u00f3n y administraci\u00f3n de cl\u00fasteres de Kubernetes y se integran a la perfecci\u00f3n con los respectivos entornos en la nube, lo que garantiza una orquestaci\u00f3n de contenedores y una implementaci\u00f3n de aplicaciones eficientes.<\/p>\n<h2 class=\"wp-block-heading\">C\u00f3mo crear una aplicaci\u00f3n de Django en PyCharm<\/h2>\n<p>En este tutorial empezaremos generando una aplicaci\u00f3n de Django m\u00ednima. A continuaci\u00f3n, colocaremos la aplicaci\u00f3n en contenedores y, en el \u00faltimo paso, la implementaremos en un cl\u00faster de Kubernetes local mediante Docker Desktop.<\/p>\n<p>Si no ha trabajado antes con el marco de trabajo Django pero desea crear una aplicaci\u00f3n de Django desde cero, consulte este <a href=\"https:\/\/blog.jetbrains.com\/pycharm\/2023\/04\/create-a-django-app-in-pycharm\/\">art\u00edculo<\/a> del blog.<\/p>\n<p><a href=\"https:\/\/github.com\/mukulmantosh\/django-kubernetes\" target=\"_blank\" rel=\"noopener\">Aqu\u00ed<\/a> puede acceder al c\u00f3digo fuente utilizado en este tutorial.<\/p>\n<p>Comencemos creando una nueva <a href=\"https:\/\/blog.jetbrains.com\/pycharm\/2023\/04\/create-a-django-app-in-pycharm\/\">aplicaci\u00f3n de Django en PyCharm<\/a>.<\/p>\n<div class=\"buttons\">\n<div class=\"buttons__row\">\n                                                <a href=\"https:\/\/www.jetbrains.com\/pycharm\/web-development\/django\/\" class=\"btn\" target=\"\" rel=\"noopener\">Probar PyCharm Pro gratis<\/a>\n                                                    <\/div>\n<\/p>\n<\/div>\n<p>Para crear su proyecto, inicie PyCharm y haga clic en <strong>New Project<\/strong>. Si PyCharm ya se est\u00e1 ejecutando, seleccione <strong>File | New Project<\/strong> en el men\u00fa principal.<\/p>\n<p>Proporcione detalles esenciales como el nombre de proyecto, la ubicaci\u00f3n y el tipo de int\u00e9rprete, utilizando <a href=\"https:\/\/docs.python.org\/3\/library\/venv.html\" target=\"_blank\" rel=\"noopener\">venv<\/a> o un entorno personalizado.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/1y08c3RPd7rqmf5qxcZfrWrzDAekMhwhPIWRa10ipnziCXebOqe8WsMfTXG55efz48CBi5eF_zg7clWjfrHI843CGaueY1wwvBZ0qeei_umc2hAPhLtfuEh0DdLF3NKoSW2iPGbpUCtsEzlF5NKUj0o-1.png\" width=\"624\" height=\"465\"><\/p>\n<p>A continuaci\u00f3n, haga clic en <strong>Create<\/strong>.<\/p>\n<p>PyCharm hace todo el trabajo pesado configurando su proyecto y creando el entorno virtual.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/odWqcTk4mIote11wJzVTV42umN0Ffu_aSMfv9RRVQs2V9BYcL9_q6dSz-e56unGs-HkDc5GrogOvGqDWJNS3FgYOG7MFAcrXAa6U54Fca1nd9aXo8MjUye5_42sEXIb11rTKyiCAWQWPehKrBeyVMT4-1.png\" width=\"624\" height=\"351\"><\/p>\n<h3 class=\"wp-block-heading\">Gunicorn<\/h3>\n<p>Una vez creado el proyecto, instale <a href=\"https:\/\/gunicorn.org\/\" target=\"_blank\" rel=\"noopener\">Gunicorn<\/a>, un servidor HTTP popular de la interfaz de pasarela del servidor web de Python (WSGI). Gunicorn, un servidor web con modelo de trabajador de pre-fork utilizado para servir aplicaciones web de Python, se utiliza a menudo en combinaci\u00f3n con marcos de trabajo web como Django, Flask y otros para implementar aplicaciones web y hacerlas accesibles a trav\u00e9s de Internet.<\/p>\n<p>La ventana de herramientas <strong>Python Packages<\/strong> ofrece la forma m\u00e1s r\u00e1pida y sencilla de previsualizar e instalar paquetes para el int\u00e9rprete Python seleccionado en ese momento.<\/p>\n<p>Puede abrir la ventana de herramientas a trav\u00e9s de <strong>View | Tool Windows | Python Packages<\/strong>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/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> es una biblioteca de Python utilizada para conectarse e interactuar con bases de datos PostgreSQL. Proporciona una interfaz Python para trabajar con PostgreSQL, un de los sistemas de gesti\u00f3n de bases de datos relacionales de c\u00f3digo abierto m\u00e1s populares. Psycopg 2 permite a los desarrolladores de Python realizar diversas operaciones con bases de datos, como insertar, actualizar y recuperar datos, as\u00ed como ejecutar consultas SQL y gestionar conexiones a bases de datos desde programas de Python.<\/p>\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1273\" height=\"455\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/03\/image-7.png\" alt=\"\" class=\"wp-image-452825\" \/><\/figure>\n<p>Antes de instalar <code>psycopg2<\/code>, deber\u00e1 instalar las dependencias a nivel de sistema, <code>brew install libpq<\/code> para macOS y <code>apt-get install libpq-dev<\/code> para Linux.<\/p>\n<p>Referencia: <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> es una biblioteca de cliente para PostgreSQL. Es una biblioteca de C que proporciona la funcionalidad necesaria para que las aplicaciones de cliente se conecten, interact\u00faen y gestionen servidores de bases de datos PostgreSQL.\u00a0<\/p>\n<p>Despu\u00e9s de completar las modificaciones particulares, actualice la secci\u00f3n dentro de <code>settings.py<\/code> relacionada con <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-1.png\" width=\"624\" height=\"220\"><\/p>\n<p>Aseg\u00farese siempre de pasar sus credenciales secretas a trav\u00e9s de variables de entorno.<\/p>\n<h3 class=\"wp-block-heading\">STATIC_ROOT<\/h3>\n<p>En Django, <code>STATIC_ROOT<\/code> es un ajuste de configuraci\u00f3n que se utiliza para especificar la ruta absoluta del sistema de archivos donde se almacenar\u00e1n los archivos est\u00e1ticos recopilados al ejecutar el comando de gesti\u00f3n <code>collectstatic<\/code>. Los archivos est\u00e1ticos suelen incluir CSS, JavaScript, im\u00e1genes y otros activos utilizados por su aplicaci\u00f3n web. La configuraci\u00f3n <code>STATIC_ROOT<\/code> constituye una parte esencial para servir archivos est\u00e1ticos en un entorno de producci\u00f3n.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/D-VP39aKKQITKIi2IG_T6hBWEvUCDzTaLfbrDofs-JlOHmFP51Vl2QYH6dmpufWRhgUTPoOtmyKBj155vIGL8DqWyiR79W3NdiYibTb228Yx2Tj0pwC5bPd5F6BCtbMbTvfKHJ6lDYBlmbLqv1jUmoA-1.png\" width=\"624\" height=\"323\"><\/p>\n<p>Establezca una variable de entorno para <code>STATIC_ROOT<\/code> en la l\u00ednea 127. Esta variable apuntar\u00e1 a una ruta de archivo que conduce a un volumen persistente de Kubernetes. M\u00e1s adelante se explicar\u00e1 c\u00f3mo configurar esta opci\u00f3n.<\/p>\n<p>Para recoger los archivos est\u00e1ticos, ejecute el siguiente comando:<\/p>\n<p><code>python manage.py collectstatic<\/code><\/p>\n<p>Este comando recopilar\u00e1 los archivos est\u00e1ticos y los colocar\u00e1 en el directorio <code>STATIC-ROOT<\/code>. Luego, puede servir estos activos directamente a trav\u00e9s de un servidor web Apache o NGINX, un enfoque m\u00e1s eficiente para entornos de producci\u00f3n.<\/p>\n<h3 class=\"wp-block-heading\">Dockerfile<\/h3>\n<p>Un Dockerfile es un documento textual directo que contiene directivas para construir im\u00e1genes de Docker.<\/p>\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"636\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/03\/image-4.png\" alt=\"\" class=\"wp-image-452658\" \/><\/figure>\n<p>1. <strong><code>FROM python:3.11<\/code><\/strong>: Esta l\u00ednea especifica la imagen base para la imagen de Docker utilizando la imagen de Python 3.11 oficial de Docker Hub. La aplicaci\u00f3n se compilar\u00e1 y ejecutar\u00e1 sobre esta imagen base, que ya tiene Python preinstalado.<\/p>\n<p>2. <strong><code>ENV PYTHONUNBUFFERED 1<\/code><\/strong>: Esta l\u00ednea establece una variable de entorno <code>PYTHONUNBUFFERED<\/code> a <code>1<\/code>. A menudo se recomienda establecer esta variable de entorno cuando se ejecuta Python dentro de contenedores de Docker para asegurar que Python no almacena en b\u00fafer el resultado. Esto ayuda a obtener registros en tiempo real e informaci\u00f3n de depuraci\u00f3n de la aplicaci\u00f3n.<\/p>\n<p>3. <strong><code>WORKDIR \/app<\/code><\/strong>: Esta l\u00ednea establece el directorio de trabajo dentro del contenedor de Docker a <code>\/app<\/code>. Todos los comandos posteriores se ejecutar\u00e1n en este directorio.<\/p>\n<p>4. <strong><code>COPY . \/app<\/code><\/strong>: Esta l\u00ednea copia el contenido del directorio actual (el directorio donde se encuentra el Dockerfile) al directorio <code>\/app<\/code> dentro del contenedor. Esto incluye el c\u00f3digo de su aplicaci\u00f3n y cualquier archivo necesario para la imagen de Docker.<\/p>\n<p>5. <strong><code>RUN pip install -r requirements.txt<\/code><\/strong>: Esta l\u00ednea ejecuta el comando <code>pip install<\/code> para instalar las dependencias de Python enumeradas en un archivo <code>requirements.txt<\/code> que se encuentra en el directorio <code>\/app<\/code>. Esto es una pr\u00e1ctica com\u00fan para las aplicaciones de Python, ya que le permite gestionar las dependencias de la aplicaci\u00f3n.<\/p>\n<p>6. <strong><code>EXPOSE 8000<\/code><\/strong>: Esta l\u00ednea informa a Docker que el contenedor escucha en el puerto 8000. En realidad no publica el puerto. Es una declaraci\u00f3n de metadatos que indica qu\u00e9 puerto puede utilizar el contenedor.<\/p>\n<p>7. <strong><code>CMD [\"gunicorn\", \"django_kubernetes_tutorial.wsgi:application\", \"--bind\", \"0.0.0.0:8000\"]<\/code><\/strong>: Esta l\u00ednea especifica el comando predeterminado que se ejecutar\u00e1 cuando se inicie el contenedor. Utiliza Gunicorn para servir la aplicaci\u00f3n de Django y enlaza Gunicorn para escuchar en todas las interfaces de red (<code>0.0.0.0<\/code>) en el puerto 8000 utilizando la aplicaci\u00f3n WSGI definida en <code>django_kubernetes_tutorial.wsgi:application<\/code>.<\/p>\n<h3 class=\"wp-block-heading\">DockerHub<\/h3>\n<p>Visite <a href=\"http:\/\/hub.docker.com\" target=\"_blank\" rel=\"noopener\">hub.docker.com<\/a> y proceda a iniciar sesi\u00f3n o a registrarse en la plataforma.<\/p>\n<p>Haga clic en <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-1.png\" width=\"624\" height=\"432\"><\/p>\n<p>A continuaci\u00f3n, indique el nombre del repositorio y haga p\u00fablica la visibilidad. Si est\u00e1 trabajando con informaci\u00f3n sensible o confidencial, establezca la visibilidad a <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-1.png\" width=\"624\" height=\"453\"><\/p>\n<p>Una vez creado el repositorio, necesitar\u00e1 compilar la imagen de Docker y enviarla al registro.<\/p>\n<p>Antes de ejecutar el comando, aseg\u00farese de que el archivo <code>requirements.txt<\/code> est\u00e9 actualizado ejecutando el siguiente comando:<\/p>\n<p><code>pip freeze &gt; requirements.txt<\/code><\/p>\n<p>Para construir una imagen, ejecute el siguiente comando:\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>Este comando variar\u00e1 seg\u00fan sus circunstancias espec\u00edficas y tendr\u00e1 que utilizar su nombre de usuario personal.<\/p>\n<p>A continuaci\u00f3n, debe autenticarse con Docker Hub para enviar la imagen al registro.<\/p>\n<p>Escriba el siguiente comando en el terminal:<\/p>\n<p><code>docker login<\/code><\/p>\n<p>Introduzca su nombre de usuario y contrase\u00f1a. Una vez que se han autenticado correctamente, puede enviar la imagen ejecutando este comando:<\/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>Una vez que la imagen se ha enviado correctamente, puede observar los cambios en Docker Hub.<\/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-1.png\" width=\"624\" height=\"239\"><\/p>\n<p>Si no tiene previsto enviar m\u00e1s im\u00e1genes al registro, puede iniciar sesi\u00f3n ejecutando el siguiente comando:<\/p>\n<p><code>docker logout<\/code><\/p>\n<p>Si quiere extraer esta imagen de forma local, visite <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\">Configuraci\u00f3n de Kubernetes: c\u00f3mo escribir archivos YAML<\/h2>\n<p><strong>Esta secci\u00f3n del tutorial describe la implementaci\u00f3n de aplicaciones en cl\u00fasteres de Kubernetes locales.<\/strong><\/p>\n<p>Para este tutorial, usaremos Docker Desktop, pero tambi\u00e9n puedes usar minikube o kind.<\/p>\n<h3 class=\"wp-block-heading\">Namespaces<\/h3>\n<p>En Kubernetes, <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/overview\/working-with-objects\/namespaces\/\" target=\"_blank\" rel=\"noopener\">namespaces<\/a> es una partici\u00f3n virtual dentro de un cl\u00faster que se utiliza para agrupar y aislar recursos y objetos. Es una manera de crear varios cl\u00fasteres virtuales dentro de un \u00fanico cl\u00faster f\u00edsico.\u00a0<\/p>\n<p>Puede crear y gestionar los espacios de nombres mediante <code><a href=\"https:\/\/kubernetes.io\/docs\/reference\/kubectl\/\" target=\"_blank\" rel=\"noopener\">kubectl<\/a><\/code>, la herramienta de l\u00ednea de comando de Kubernetes, o defini\u00e9ndolos en manifiestos YAML al implementar recursos.\u00a0<\/p>\n<ul>\n<li>Si ha elegido Docker Desktop como plataforma preferida para ejecutar Kubernetes, aseg\u00farese de habilitar Kubernetes en la configuraci\u00f3n haciendo clic en la casilla de verificaci\u00f3n <strong>Enable Kubernetes<\/strong>.<\/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-1.png\" width=\"624\" height=\"368\"><\/p>\n<p>Ejecute el siguiente comando en el terminal para crear el namespace:<\/p>\n<p><code>kubectl create ns django-app<\/code><\/p>\n<h2 class=\"wp-block-heading\">C\u00f3mo implementar bases de datos con K8s<\/h2>\n<p>Para comenzar, vamos a establecer una instancia PostgreSQL en nuestro cl\u00faster de Kubernetes en el entorno local.<\/p>\n<h3 class=\"wp-block-heading\">PersistentVolume<\/h3>\n<p>En Kubernetes, un <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/storage\/persistent-volumes\/\" target=\"_blank\" rel=\"noopener\">volumen persistente<\/a> (PV) es un trozo de almacenamiento en el cl\u00faster aprovisionado por un administrador. Al almacenar los datos en una manera independiente del ciclo de vida de un pod, los PV permiten una gesti\u00f3n y abstracci\u00f3n de los recursos de almacenamiento m\u00e1s desacoplada y flexible. Esto significa que los datos pueden persistir incluso si el pod que los utiliza se elimina o se reprograma en un nodo diferente del cl\u00faster.<\/p>\n<p>Creemos un volumen persistente y llam\u00e9moslo <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-1.png\" width=\"624\" height=\"631\"><\/p>\n<p>Esta configuraci\u00f3n YAML define un recurso PersistentVolume llamado <code>postgres-pv<\/code> con una capacidad de 1 gigabyte, montado utilizando el modo de acceso <code>ReadWriteOnce<\/code> y proporcionado por una ruta local en el sistema de archivos del nodo ubicado en <code>\/data\/db<\/code>. Este PV se puede utilizar para proporcionar almacenamiento persistente para los pods que necesitan acceso a un directorio en el sistema de archivos del nodo y es adecuado para aplicaciones como PostgreSQL u otros servicios con estado que necesitan almacenamiento persistente.<\/p>\n<p>Para producci\u00f3n, recomendamos utilizar soluciones en la nube como AWS RDS o Google CloudSQL, o utilizar <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/workloads\/controllers\/statefulset\/\" target=\"_blank\" rel=\"noopener\">StatefulSets<\/a> de Kubernetes.<\/p>\n<h3 class=\"wp-block-heading\">PersistentVolumeClaim<\/h3>\n<p>En Kubernetes, <a href=\"https:\/\/kubernetes.io\/docs\/tasks\/configure-pod-container\/configure-persistent-volume-storage\/#create-a-persistentvolumeclaim\" target=\"_blank\" rel=\"noopener\">PersistentVolumeClaim<\/a> (PVC) es un objeto de recurso utilizado por un pod para solicitar una cantidad concreta de almacenamiento con ciertas propiedades de un PV. Los PVCs sirven para que las aplicaciones reclamen recursos de almacenamiento sin necesitar saber los detalles de la infraestructura de almacenamiento subyacente.<\/p>\n<p>Al crear y utilizar los PVCs, Kubernetes proporciona una manera de asignar y gestionar recursos de almacenamiento para las aplicaciones al tiempo que abstrae la infraestructura de almacenamiento subyacente, lo que hace m\u00e1s f\u00e1cil trabajar con aplicaciones con estado en entornos de contenedores y gestionarlas.<\/p>\n<p>Creemos un PVC y llam\u00e9moslo <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-1.png\" width=\"624\" height=\"577\"><\/p>\n<p>Un PVC solicita recursos de almacenamiento y est\u00e1 vinculado a un PV que proporciona el almacenamiento real.\u00a0<\/p>\n<p>Esta configuraci\u00f3n YAML define un PersistentVolumeCLaim llamado <code>postgres-pvc<\/code> dentro del namespace <code>django-app<\/code>. Solicita un gigabyte de almacenamiento con el modo de acceso <code>ReadWriteOnce<\/code> y especifica expl\u00edcitamente la StorageClass <code>manual<\/code>. Este PVC est\u00e1 destinado a un PV existente con el nombre <code>postgres-pv<\/code>, y reserva efectivamente ese volumen para su uso por pods dentro del namespace <code>django-app<\/code> que hacen referencia a este PVC.<\/p>\n<h3 class=\"wp-block-heading\">ConfigMap<\/h3>\n<p>En Kubernetes, un <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/configuration\/configmap\/\" target=\"_blank\" rel=\"noopener\">ConfigMap<\/a> es un objeto de API que se utiliza para almacenar datos de configuraci\u00f3n de pares clave-valor. ConfigMaps ofrece una forma de desacoplar los datos de configuraci\u00f3n del c\u00f3digo de la aplicaci\u00f3n, lo que facilita la gesti\u00f3n y actualizaci\u00f3n de las configuraciones sin modificar y volver a implementar los contenedores. Son especialmente \u00fatiles para configurar aplicaciones, microservicios y otros componentes dentro de un cl\u00faster de Kubernetes.<\/p>\n<p>Creemos un ConfigMap y llam\u00e9moslo <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-1.png\" width=\"624\" height=\"524\"><\/p>\n<p>Aunque este tutorial utiliza ConfigMaps, por consideraciones de seguridad, se recomienda almacenar las credenciales sensibles en <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/configuration\/secret\/\" target=\"_blank\" rel=\"noopener\">Secrets<\/a> de Kubernetes o explorar alternativas como Bitnami Sealed Secrets, AWS Parameter Store o HashiCorp Vault.<\/p>\n<h3 class=\"wp-block-heading\">Deployment<\/h3>\n<p>En Kubernetes, <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/workloads\/controllers\/deployment\/\" target=\"_blank\" rel=\"noopener\">Deployment<\/a> es un objeto de recurso utilizado para gestionar la implementaci\u00f3n y el escalado de aplicaciones. Forma parte del grupo de la API de Kubernetes y ofrece una forma declarativa para definir y gestionar el estado deseado de su aplicaci\u00f3n.<\/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-1.png\" width=\"624\" height=\"735\"><\/p>\n<p>Un Deployment es un recurso de Kubernetes de nivel superior utilizado para gestionar y escalar pods de aplicaciones.\u00a0<\/p>\n<p>Esta configuraci\u00f3n YAML define un Deployment llamado <code>postgres<\/code> en el namespace <code>django-app<\/code>. Implementa una \u00fanica r\u00e9plica de una base de datos PostgreSQL (versi\u00f3n 16.0) con almacenamiento persistente. El pod de base de datos se etiqueta como <code>app: postgresdb<\/code> y el almacenamiento se proporciona por un PVC llamado <code>postgres-pvc<\/code>. La configuraci\u00f3n y las credenciales para el contenedor PostgeSQL se proporcionan a trav\u00e9s de un ConfigMap llamado <code>db-secret-credentials<\/code>.<\/p>\n<h3 class=\"wp-block-heading\">Service<\/h3>\n<p>En Kubernetes, <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/services-networking\/service\/\" target=\"_blank\" rel=\"noopener\">Service<\/a> es un objeto de recurso utilizado para exponer un conjunto de pods como un servicio de red. Los Services habilitan la comunicaci\u00f3n en red entre las diferentes partes de su aplicaci\u00f3n que se ejecutan en un cl\u00faster de Kubernetes y ofrecen un punto de conexi\u00f3n estable para que los clientes accedan a esas partes. Los Services abstraen la infraestructura de red subyacente, lo que facilita la conexi\u00f3n y el descubrimiento de los componentes de su aplicaci\u00f3n.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/p4NneUHgkfOqr2cp1bIZVYEH1weBKgZ5cWjPOgnATHQGdQwULM9BlzPRJXyPqf0v3FqHrztZ9rmL6P3RSInOE6vNC21UenOjGz-872-KzklWAQGm2Rr3uOKIQMRMlLvCIHiswccwGtI-eVeBI7b61EI-1.png\" width=\"624\" height=\"525\"><\/p>\n<p>Esta configuraci\u00f3n YAML define un NodePort Service llamado <code>postgres-service<\/code> dentro del namespace <code>django-app<\/code>. Expone el servicio PostgreSQL que se ejecuta en los pods indicados con \u00ab<code>app: postgresdb<\/code>\u00bb en el puerto 5432 dentro del cl\u00faster. Los clientes externos pueden acceder al Service en la direcci\u00f3n IP de cualquier nodo utilizando el puerto 30004. Este Service ofrece una forma de hacer que la base de datos PostgreSQL sea accesible desde fuera del cl\u00faster de Kubernetes.<\/p>\n<h2 class=\"wp-block-heading\">C\u00f3mo crear configuraciones YAML para una aplicaci\u00f3n de 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\/09\/FJCpL5-QEQHMI7w0j2XnboyV-y6NOoRZPzOd3GXJju2CLizk2kmnXEBcDaUSAOuvHfFrOcKel3VcVs0fimdgovM9NSn5aw31hDTYSkyAgYSK14EqO-bj2CgL2p-6h20IDY0Ei-szg63ZKYIr77kIOZs-1.png\" width=\"624\" height=\"525\"><\/p>\n<p>Esta configuraci\u00f3n YAML define un PersistentVolume llamado <code>staticfiles-pv<\/code> con una capacidad de almacenamiento de 1 GB, lo que permite a varios pods leer y escribir en \u00e9l de forma simult\u00e1nea. El almacenamiento se proporciona por una ruta de host local situada en <code>\/data\/static<\/code>. Los archivos est\u00e1ticos de Django se almacenar\u00e1n en esta ubicaci\u00f3n.<\/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-1.png\" width=\"624\" height=\"504\"><\/p>\n<p>Este YAML define un PVC llamado <code>staticfiles-pvc<\/code> en el namespace <code>django-app<\/code>. Solicita almacenamiento con una capacidad de al menos 1 GB por un PV con la StorageClass \u00abmanual\u00bb, y especifica que necesita acceso a <code>ReadWriteMany<\/code>. La reclamaci\u00f3n se vincula expl\u00edcitamente a un PV existente llamado <code>staticfiles-pv<\/code> para satisfacer sus necesidades de almacenamiento. Este permite a los pods en el namespace <code>django-app<\/code> utilizar este PVC para acceder y utilizar el almacenamiento proporcionado por el PVC asociado.<\/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-1.png\" width=\"624\" height=\"459\"><\/p>\n<p>Este YAML define un ConfigMap llamado <code>app-cm<\/code> en el namespace <code>django-app<\/code>, y contiene varios pares clave-valor que almacenan datos de configuraci\u00f3n. Este ConfigMap se puede utilizar por los pods u otros recursos dentro del namespace <code>django-app<\/code> para acceder a los ajustes de configuraci\u00f3n, como la informaci\u00f3n de conexi\u00f3n a la base de datos y las rutas de los archivos est\u00e1ticos.<\/p>\n<h3 class=\"wp-block-heading\">Deployment<\/h3>\n<figure class=\"wp-block-image size-full is-resized\"><img decoding=\"async\" loading=\"lazy\" width=\"1258\" height=\"1678\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/03\/deploy.png\" alt=\"\" class=\"wp-image-456835\" style=\"aspect-ratio:0.7497020262216925;width:582px;height:auto\" \/><\/figure>\n<p>Este YAML define un Deployment llamado <code>django-app-deploy<\/code> en el namespace <code>django-app<\/code>. Crea una r\u00e9plica (pod) que ejecuta un contenedor con una imagen y una configuraci\u00f3n espec\u00edficas de Docker. El pod est\u00e1 asociado a dos vol\u00famenes, <code>postgres-db-storage<\/code> y <code>staticfiles<\/code>, que son respaldados con los PVC. El contenedor est\u00e1 configurado para utilizar variables del entorno de un ConfigMap llamado <code>app-cm<\/code> y escucha en el puerto 8000. Los vol\u00famenes se montan en rutas espec\u00edficas dentro del contenedor para dar acceso al almacenamiento de base de datos y archivos est\u00e1ticos. Este Deployment es una forma com\u00fan de ejecutar una aplicaci\u00f3n de Django utilizando Kubernetes.<\/p>\n<p>Si le interesa c\u00f3mo extraer im\u00e1genes de un registro privado, lea <a href=\"https:\/\/kubernetes.io\/docs\/tasks\/configure-pod-container\/pull-image-private-registry\/\" target=\"_blank\" rel=\"noopener\">esto<\/a>.\u00a0<\/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-1.png\" width=\"624\" height=\"577\"><\/p>\n<p>El Service escucha en el puerto 8000 y dirige el tr\u00e1fico entrante a los pods indicados con <code>app: django-application<\/code>. Se trata de una configuraci\u00f3n habitual para exponer y equilibrar la carga de aplicaciones web en un cl\u00faster de Kubernetes donde se ejecutan varias instancias de la misma aplicaci\u00f3n. El Service asegura que el tr\u00e1fico se distribuya de manera uniforme entre ellas.<\/p>\n<h2 class=\"wp-block-heading\">NGINX<\/h2>\n<p><a href=\"https:\/\/www.nginx.com\/\" target=\"_blank\" rel=\"noopener\">NGINX<\/a> es un web de alto rendimiento y un servidor proxy inverso conocido por su velocidad, fiabilidad y escalabilidad. Gestiona con eficiencia el tr\u00e1fico web, el equilibrio de carga y la distribuci\u00f3n de contenidos, por lo que es una opci\u00f3n popular para servir sitios web y aplicaciones.<\/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-1.png\" width=\"624\" height=\"460\"><\/p>\n<p>Esta configuraci\u00f3n YAML define un ConfigMap de Kubernetes llamado <code>nginx-cm<\/code> en el namespace <code>django-app<\/code> y contiene un par clave-valor donde la clave es <code>default.conf<\/code> y el valor es un archivo de configuraci\u00f3n NGINX multil\u00ednea que redirige la solicitud al servidor de backend.\u00a0<\/p>\n<h3 class=\"wp-block-heading\">Deployment<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/4ErlDKYewor2Owj0YrtS7O01WkXzFkTBHoN5LGlEGBfvX_MGUzXgxF0ur0eDSIBD2HdJlbg4zpAE1v1OwT_LkSYR3RS4hQFnW3jwX_wEjE_L4cCIeuHI-wspyiTGaw6z8JnHXw8buX0yvbWsr3eSNDo-1.png\" width=\"624\" height=\"727\"><\/p>\n<p>Esta configuraci\u00f3n YAML define un Deployment que crea y gestiona pods que ejecutan un contenedor NGNX son vol\u00famenes y configuraciones espec\u00edficas. Ese Deployment asegura que una r\u00e9plica de este pod siempre est\u00e9 en ejecuci\u00f3n en el namespace <code>django-app<\/code>. Tambi\u00e9n anula la configuraci\u00f3n predeterminada de NGINX sustituy\u00e9ndola por un 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\/09\/PqinRZHVtGiapAjd5aD4-mA4sRmxTlRnfkSl5y6GRrPY4KpD2MsuMkkKspX1J-JHNwEdSlxb_Vtuex3SRd0caY4x-zI744KCZ-AKgjYc976FWHiEZVl9dM-oyJuPgE-DoEyU46RLokubkL-otadMZ40-1.png\" width=\"624\" height=\"631\"><\/p>\n<p>Esta configuraci\u00f3n YAML define un Kubernetes Service llamado <code>nginx-service<\/code> dentro del namespace <code>django-app<\/code>. Expone los pods indicados con <code>app:nginx<\/code> en el puerto 80 dentro del cl\u00faster y tambi\u00e9n hace que el Service sea accesible en NodePort 30005 en cada nodo del cl\u00faster. Esto permite que el tr\u00e1fico externo llegue a los pods que ejecutan la aplicaci\u00f3n de NGINX a trav\u00e9s del servicio NodePort.<\/p>\n<h2 class=\"wp-block-heading\">C\u00f3mo gestionar cargas de trabajo por lotes con trabajos de Kubernetes<\/h2>\n<p>En Kubernetes, <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/workloads\/controllers\/job\/\" target=\"_blank\" rel=\"noopener\">Job<\/a> es un objeto de recurso que representa una \u00fanica unidad o una tarea finita. Los Jobs son dise\u00f1ados para ejecutar tareas hasta su finalizaci\u00f3n, con un n\u00famero determinado de finalizaciones con \u00e9xito.\u00a0<\/p>\n<h3 class=\"wp-block-heading\">Migraci\u00f3n de bases de datos<\/h3>\n<figure class=\"wp-block-image size-full is-resized\"><img decoding=\"async\" loading=\"lazy\" width=\"1326\" height=\"1394\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/03\/migration.png\" alt=\"\" class=\"wp-image-456823\" style=\"aspect-ratio:0.9512195121951219;width:597px;height:auto\" \/><\/figure>\n<p>Esta configuraci\u00f3n YAML define un Kubernetes Job llamado <code>django-db-migrations<\/code> dentro del namespace <code>django-app<\/code>. Este Job ejecuta un contenedor utilizando una imagen de Docker personalizada para las migraciones de Django y monta un PVC para proporcionar almacenamiento para los archivos relacionado con la base de datos. Si el Job falla, puede reintentarse hasta 15 veces, y conservar\u00e1 su pod durante 100 segundos tras su finalizaci\u00f3n. Este Job crear\u00e1 nuevas tablas en PostgreSQL.<\/p>\n<h3 class=\"wp-block-heading\">Archivos est\u00e1ticos<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/41sZvQpth3_7rpCpoCuUY0k588q9aANJoVs6DxWJSGF2qvZQDo0u9jcxEbjjEb9IQ3oLUTNkboM61EoKbGOxsnsJFHfzLYjlwFqq8TXtuYNLZne2h358Yn-MyoNrk8JVGRpu0erDPr4yHqevTlXzxtY-1.png\" width=\"624\" height=\"643\"><\/p>\n<p>Esta configuraci\u00f3n YAML define un Kubernetes Job llamado <code>django-staticfiles<\/code> dentro del namespace <code>django-app<\/code>. El Job ejecuta un contenedor utilizando una imagen de Docker personalizada para recopilar archivos est\u00e1ticos para una aplicaci\u00f3n de Django y monta un PVC para proporcionar almacenamiento para los archivos est\u00e1ticos. Si el Job falla, puede reintentarse hasta tres veces, y conservar\u00e1 su pod durante 100 segundos tras su finalizaci\u00f3n a efectos de depuraci\u00f3n. Este Job copiar\u00e1 los archivos est\u00e1ticos en el mountPath, que es <code>\/data\/static<\/code>.<\/p>\n<h2 class=\"wp-block-heading\">C\u00f3mo lanzar la aplicaci\u00f3n<\/h2>\n<p>Para lanzar la aplicaci\u00f3n, vaya al directorio <code>k8s<\/code> y ejecute el siguiente comando:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/t7jeYgU4ZqFBXc-2WwudXN8V4cibZZt5M0Tob6-0zV570MXlHkql6QBw4Oxibl5WWdGnfB9510sYpfjnIhsjvs9AObRuhIrR91r8b3Q8Vu2pJYuLfFhm2ixDw7Oddkvh-5tP3nUADGAu5DX725cJ6YI-1.png\" width=\"624\" height=\"392\"><\/p>\n<p>Despu\u00e9s de implementar la aplicaci\u00f3n, utilice el siguiente comando para verificar el estado de los pods en ejecuci\u00f3n:<\/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-1.png\" width=\"624\" height=\"108\"><\/p>\n<h3 class=\"wp-block-heading\">C\u00f3mo crear un superusuario en Django<\/h3>\n<p>Una vez que todas sus aplicaciones se pongan en marcha, cree un superusuario para iniciar sesi\u00f3n en el administrador de Django.<\/p>\n<p>Ejecute el siguiente comando para obtener la lista de pods en ejecuci\u00f3n:<\/p>\n<p><code>kubectl get pods -n django-app<\/code><\/p>\n<p>Para entrar en el shell del contenedor, ejecute:<\/p>\n<p><code>kubectl exec -it  -n django-app -- sh<\/code><\/p>\n<p>A continuaci\u00f3n, ejecute:<\/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-1.png\" width=\"624\" height=\"197\"><\/p>\n<p>Una vez que haya creado correctamente el superusuario, abra <a href=\"http:\/\/127.0.0.1:30005\" target=\"_blank\" rel=\"noopener\">http:\/\/127.0.0.1:30005<\/a> en un navegador. Le dirigir\u00e1 a la p\u00e1gina de bienvenida predeterminada.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/tpozSD_EtSgHLFQ1ud5EV4_OJFdmgSUGlS6u4iEMI9rVrduVIlaJS1NHoD4D6WhjCdC7oASEobsfm9ar0cWUxEydoSVsTfuoOWTJw-5usNmJrusEyD50SGJYbKUWU_BLgdbipbfYeeKBcW1ecK8_gsQ-1.png\" width=\"624\" height=\"321\"><\/p>\n<p>A continuaci\u00f3n, dir\u00edjase al administrador de Django a trav\u00e9s de <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\/09\/WcwAvYrT3499Hr32HybiT6VuuanZh8keoS95n0N3-lasuJ8z4rsmQydIp4MLCGVORtQLZnECw2y3IKB9e2J8Mg8ScRF1HpvD-bu68MSYv_Ti_GBr3P4Y0gtc8B6aaUfg2kRF2VLj0NXUWLDRCiy3sjg-1.png\" width=\"624\" height=\"447\"><\/p>\n<p>Introduzca el nombre de usuario y contrase\u00f1a que acaba de crear.\u00a0<\/p>\n<p>Una vez autenticado, se le redirigir\u00e1 a la p\u00e1gina de administraci\u00f3n de Django.\u00a0<\/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-1.png\" width=\"624\" height=\"400\"><\/p>\n<p>Si intenta iniciar sesi\u00f3n a trav\u00e9s de localhost:30005\/admin, puede recibir un error <em>403 Forbidden<\/em> (CSFR).<\/p>\n<p>Puede resolverlo en el archivo <code>settings.py<\/code> bajo <code>CSFR_TRUSTED_ORIGINS<\/code>.<\/p>\n<p><code>CSRF_TRUSTED_ORIGINS<\/code> es una <a href=\"https:\/\/docs.djangoproject.com\/en\/4.2\/ref\/settings\/#std-setting-CSRF_TRUSTED_ORIGINS\" target=\"_blank\" rel=\"noopener\">configuraci\u00f3n<\/a> en Django que se utiliza para especificar una lista de or\u00edgenes de confianza para la protecci\u00f3n contra la falsificaci\u00f3n de petici\u00f3n en sitios cruzados (CSFR). El CSFR es una vulnerabilidad de seguridad que puede ocurrir cuando un atacante enga\u00f1a a un usuario para que, sin saberlo, realice una solicitud no deseada a una aplicaci\u00f3n web. Para evitarlo, Django incluye protecci\u00f3n CSRF integrada.<\/p>\n<p><code>CSFR_TRUSTED_ORIGINS<\/code> le permite definir una lista de los or\u00edgenes (sitios web) desde los que se aceptan solicitudes protegidas contra CSFR. Cualquier solicitud procedente de un origen no incluido en esta lista se considerar\u00e1 potencialmente maliciosa y debidamente bloqueada.<\/p>\n<p>Esta configuraci\u00f3n se puede utilizar para permitir ciertas solicitudes cruzadas a su aplicaci\u00f3n de Django, al tiempo que mantiene la seguridad contra ataques CSRF. Resulta especialmente \u00fatil cuando la aplicaci\u00f3n debe interactuar con otros servicios web o API alojados en dominios diferentes.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/DTDVeAkR8-rHFCbeoMqWHHSSCBDNjQ96OLDPcexK0TVmbzk9bRgHajXVqFiy4r_yTd6mE1GM7TGuCwYcTJ0owbKhhjLxaJlgE9_KjgEk6APxHsHsPXtdRtJwRbYgejaoHuxpWzUEsaUAt3oHjzrTvVM-2.png\" width=\"624\" height=\"428\"><\/p>\n<p>Si est\u00e1 utilizando las herramientas GUI como <a href=\"https:\/\/kubernetes.io\/docs\/tasks\/access-application-cluster\/web-ui-dashboard\/\" target=\"_blank\" rel=\"noopener\">Kubernetes Dashboard<\/a>, puede visualizar f\u00e1cilmente sus pods en ejecuci\u00f3n, implementaciones, vol\u00famenes persistentes, y m\u00e1s.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/2lssXclYX6wG01Kf5SX7hng9Yxd0JuqeFAYR-UDdEBIXJyzNZItFQFGMT1UxAifh3FywhRmaWzrwafuv0L9nciqBE7yf09hf7sYmpijHkrZoe_MXeBIow9q_CrlZAUHLmNHDzMTcO8XZqWHOxjZHcnw-2.png\" width=\"624\" height=\"325\"><\/p>\n<h2 class=\"wp-block-heading\">Compatibilidad con Kubernetes en PyCharm\u00a0<\/h2>\n<p>PyCharm ofrece un editor mejorado y compatibilidad con tiempos de ejecuci\u00f3n para Kubernetes, y aporta una gran cantidad de funcionalidades para simplificar su gesti\u00f3n de Kubernetes, como por ejemplo:<\/p>\n<ul>\n<li>Explorar los objetos del cl\u00faster, extraer y editar sus configuraciones y describirlos.<\/li>\n<li>Visualizar eventos.<\/li>\n<li>Visualizar y descargar los registros de los pods.<\/li>\n<li>Adjuntar la consola de los pod.<\/li>\n<li>Ejecutar shell en pods.<\/li>\n<li>Reenviar puertos a un pod.<\/li>\n<li>Aplicar configuraciones YAML de recursos desde el editor.<\/li>\n<li>Eliminar recursos del cl\u00faster.<\/li>\n<li>Finalizar entradas ConfigMap y Secret del cl\u00faster.<\/li>\n<li>Configurar rutas a <code>kubectl<\/code>.<\/li>\n<li>Configurar archivos <code>kubeconfig<\/code> personalizados a nivel global y por proyecto.<\/li>\n<li>Modificar contextos y namespaces.<\/li>\n<li>Utilizar el esquema de API (incluido CRD) del cl\u00faster activo para editar manifiestos de recursos.<\/li>\n<\/ul>\n<p>Vea este <a href=\"https:\/\/www.youtube.com\/watch?v=NqotF4kRvTc\" target=\"_blank\" rel=\"noopener\">v\u00eddeo<\/a> para aprender m\u00e1s sobre c\u00f3mo trabajar con Kubernetes en PyCharm Professional.<\/p>\n<p>\u00a1Pruebe PyCharm para sus tareas de Kubernetes gratis!<\/p>\n<div class=\"buttons\">\n<div class=\"buttons__row\">\n                                                <a href=\"https:\/\/www.jetbrains.com\/pycharm\/download\/\" class=\"btn\" target=\"\" rel=\"noopener\">DESCARGAR PYCHARM<\/a>\n                                                    <\/div>\n<\/p>\n<\/div>\n<h2 class=\"wp-block-heading\">Referencias<\/h2>\n<p>\u00bfYa conoce bien Kubernetes? A continuaci\u00f3n, d\u00e9 el siguiente paso en su viaje de programaci\u00f3n explorando las soluciones en la nube, y eche un vistazo a nuestros tutoriales en <a href=\"https:\/\/www.jetbrains.com\/pycharm\/guide\/tutorials\/fastapi-aws-kubernetes\/\" target=\"_blank\" rel=\"noopener\">AWS EKS<\/a> y <a href=\"https:\/\/www.jetbrains.com\/pycharm\/guide\/tutorials\/cloud-code-pycharm\/\" target=\"_blank\" rel=\"noopener\">Google Kubernetes Engine<\/a>.<\/p>\n\n\n<p>A<em>rt\u00edculo original en ingl\u00e9s de:<\/em><\/p>\n\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":1086,"featured_media":571317,"comment_status":"closed","ping_status":"closed","template":"","categories":[8377],"tags":[963,5635,154],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/pycharm\/571260"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/pycharm"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/types\/pycharm"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/users\/1086"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/comments?post=571260"}],"version-history":[{"count":6,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/pycharm\/571260\/revisions"}],"predecessor-version":[{"id":601104,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/pycharm\/571260\/revisions\/601104"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/media\/571317"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/media?parent=571260"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/categories?post=571260"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/tags?post=571260"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/cross-post-tag?post=571260"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}