Todo sobre la contenerización de aplicaciones en Docker

contenerización

La mayoría de los proyectos de desarrollo implican una amplia gama de entornos. Existen los entornos de producción, desarrollo, control de calidad, staging y, por último, los entornos locales de cada desarrollador. Mantener estos entornos sincronizados para que un proyecto se ejecute igual (o se ejecute, simplemente) en cada uno de ellos puede ser todo un reto.

Hay muchas razones por las cuales puede existir una incompatibilidad, pero el uso de Docker te ayudará a eliminarlas en su mayoría. En este artículo, analizamos Docker, los contenedores de aplicaciones y cómo el uso de estas herramientas puede ayudarte a ejecutar aplicaciones en cualquier lugar donde puedas instalar Docker, evitando así problemas de compatibilidad.

¿Qué es un contenedor de aplicaciones?

Un contenedor de aplicaciones es un paquete ligero e independiente que incluye una aplicación y todas sus dependencias, como bibliotecas, entornos de ejecución y archivos de configuración. Un contenedor contiene todo lo que la aplicación necesita para ejecutarse eficazmente en un entorno aislado. Están diseñados para funcionar en cualquier sistema operativo y hardware compatibles al eliminar las diferencias en las distribuciones del sistema operativo (SO) y compartir el núcleo del sistema operativo del host.

Esto permite ejecutar varias aplicaciones o servicios aislados en un único host sin necesidad de un sistema operativo completo para cada aplicación.

Los contenedores de aplicaciones difieren de la virtualización tradicional en la asignación de recursos, el sistema operativo, el aislamiento y la escalabilidad. Los contenedores comparten recursos como CPU, memoria y almacenamiento a nivel de sistema operativo, por lo que consumen menos recursos que las máquinas virtuales (VM), que requieren un sistema operativo completo para cada instancia. Por ello, los contenedores se inician en segundos, en comparación con las máquinas virtuales, que pueden tardar minutos. Esta característica también hace que los contenedores sean más escalables que las máquinas virtuales.

Sin embargo, un aspecto en el que destacan las máquinas virtuales es que proporcionan un aislamiento entre instancias mucho mayor que los contenedores, ya que cada máquina virtual ejecuta su propio sistema operativo.

¿Por qué contenerizar las aplicaciones?

La contenerización de aplicaciones aporta una gran cantidad de ventajas que facilitan la gestión de algunos de los retos que plantean el desarrollo, la implantación y las operaciones de software. Algunas de las principales razones para contenerizar una aplicación son:

  • Portabilidad: la contenerización proporciona un entorno de ejecución coherente al empaquetar una aplicación junto con sus dependencias y configuración. Esto garantiza un comportamiento coherente tanto si el contenedor se ejecuta en la máquina de un desarrollador como en una plataforma en la nube.
  • Escalabilidad: los contenedores permiten desplegar, parchear y escalar aplicaciones con rapidez. Los orquestadores de contenedores pueden realizar una escalada inteligente, ejecutando la cantidad justa de instancias de aplicación necesarias para servir las cargas de aplicación actuales, teniendo en cuenta los recursos disponibles.
  • Productividad: los contenedores proporcionan un entorno predecible y coherente independientemente de dónde se ejecuten. En lugar de configurar cada entorno manualmente, los desarrolladores pueden ejecutar un único comando para iniciar un contenedor, que creará y lanzará el entorno por ellos.
  • Flexibilidad: la eficiencia de los contenedores facilita la división de una aplicación en microservicios más pequeños y desplegables sin la sobrecarga de recursos que supone ejecutar varios servidores físicos o incluso máquinas virtuales.

Introducción a Docker

Docker se lanzó en 2013 como una plataforma de código abierto que simplifica el proceso de creación, ejecución, gestión y distribución de aplicaciones mediante el uso de contenedores. Para muchos equipos de desarrollo, es una herramienta fundamental en sus flujos de trabajo de desarrollo y despliegue de software, ya que permite a los desarrolladores empaquetar aplicaciones con sus dependencias en contenedores ligeros y portátiles.

Echemos un vistazo rápido a algunos componentes clave de Docker para hacernos una idea de cómo funciona.

Dockerfile

Un Dockerfile es un archivo de texto que contiene las instrucciones para construir una imagen de Docker. Especifica qué imagen de Docker se utilizará como base, la ubicación del código fuente de la aplicación que se incluirá con la imagen y las bibliotecas, paquetes y otras dependencias necesarias para ejecutar la aplicación. Docker lee este archivo y ejecuta las instrucciones que contiene para construir la imagen de Docker.

Imágenes de Docker

Una imagen de Docker es una plantilla de sólo lectura que contiene el código fuente y las dependencias de la aplicación y sirve de base para los contenedores Docker. Las imágenes de Docker se crean con un Dockerfile y pueden versionarse, almacenarse en registros y compartirse con otros. Las imágenes de Docker utilizan una arquitectura en capas, donde cada capa representa un cambio en la imagen. Dado que la estratificación está vinculada directamente a cada comando de un Dockerfile, cada instrucción puede producir una nueva capa

Contenedores Docker

Un contenedor Docker es una instancia en ejecución de una imagen de Docker. Al igual que otros contenedores, se ejecutan en entornos aislados en un sistema anfitrión y son ligeros, se inician rápidamente y ofrecen un comportamiento coherente independientemente del sistema anfitrión en el que se ejecuten.

Cómo contenerizar una aplicación mediante Docker

Muchos tipos de aplicaciones pueden contenerizarse, incluidas las aplicaciones frontend y backend. A continuación, veremos cómo se puede contenerizar una sencilla aplicación web Python Flask. Aunque existen otros lenguajes y aplicaciones que pueden empaquetarse con Docker, utilizaremos Python Flask para nuestros ejemplos.

Requisitos previos para la contenerización Docker

Debido al hecho de que la contenerización de una aplicación empaqueta todo su código y dependencias en un contenedor, realmente no hay muchos requisitos aparte de los siguientes:

  • Necesitas tener instalado Docker. Encontrarás paquetes de instalación para Linux, Mac o Windows aquí.
  • Crea una carpeta de proyecto para guardar todos los archivos de la aplicación. En nuestro ejemplo, sólo utilizaremos tres archivos.
  • Es posible que quieras instalar los lenguajes de programación y las bibliotecas que utilizas localmente para probar la aplicación antes de contenerizarla. Sin embargo, esto no es del todo necesario ya que los instalarás en el contenedor de la aplicación y Docker se encargará de esa parte.

Comprender el código de la aplicación y sus dependencias

Para nuestro ejemplo, crearemos una aplicación Python Flask sencilla. Este es el aspecto que tendrá la carpeta del proyecto:

my_flask_app/
    - app.py
    - requirements.txt

Nuestra aplicación consta de dos archivos: app.py, que contiene el código de la aplicación web, y requirements.txt, que es un archivo que Python utiliza para instalar dependencias. Aquí está el contenido de app.py con algunos comentarios explicando lo que hace cada parte:

# Importar el módulo Flask Python
from flask import Flask


# El constructor de Flask utiliza el nombre del módulo actual
app = Flask(__name__)


# La función route() es un decorador,
# Vincula una URL a una función asociada
@app.route('/')
def hello_world():
return 'Hello World'


# Si el archivo se ejecuta directamente
# ejecuta la aplicación Flask
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')

No hay mucho en el archivo requirements.txt. Simplemente lista Flask como dependencia:

Flask==2.3.2

Guía paso a paso para contenerizar una aplicación

Ahora que tenemos una aplicación para contenerizar, el siguiente paso es crear un Dockerfile que contenga las instrucciones para crear la imagen de Docker. 

Creación del archivo Dockerfile

En primer lugar, crea un Dockerfile vacío en el proyecto. Este archivo no tiene extensión. La carpeta de tu proyecto debería tener este aspecto:

my_flask_app/
    - app.py
    - Dockerfile
    - requirements.txt

Este es el contenido delDockerfile:

FROM python:3.10


COPY . /app
WORKDIR /app


RUN pip install -r requirements.txt
EXPOSE 5000


CMD ["python3", "app.py"]

Esto es lo que significa todo esto:

  • FROM: define qué contenedor usaremos como contenedor base. Puedes encontrar una amplia selección de contenedores base para empezar en Docker Hub.
  • COPY: cuando se construya el contenedor, los archivos de nuestro proyecto, representados por el punto, se copiarán en un directorio/app dentro del contenedor.
  • WORKDIR: esto le dice a Docker dónde ejecutar el comando en la parte inferior de nuestro archivo, que es la carpeta en la que copiamos nuestro proyecto.
  • RUN: la instrucción RUN indica a Docker un comando que debe ejecutar al construir el contenedor. Este comando se ejecuta durante la creación de la imagen, no cuando se inicia el contenedor. Aquí le decimos que instale los requisitos de nuestro archivo requirements.txt.
  • EXPOSE: esto le indica a Docker el puerto en el que escuchará el contenedor, que es el puerto en el que se ejecutará nuestra aplicación Flask.
  • CMD: esto le indica a Docker los comandos que se ejecutarán cuando se inicie el contenedor y se ejecute la aplicación Flask. La instrucción CMD proporciona valores por defecto para ejecutar un contenedor y puede ser anulada durante la ejecución de Docker.

Crear una imagen de Docker

Ahora que hemos creado el Dockerfile podemos construir la imagen de Docker ejecutando este comando en el directorio de nuestro proyecto:

docker build -t flask-app .

En el comando,-t significa etiqueta y etiqueta la imagen con un nombre, flask-app es el nombre que le daremos a la imagen, y el comando . define el contexto de compilación, que es el directorio actual.

Una vez que ejecutes el comando, Docker construirá tu imagen, y verás una salida como esta:


Salida de imagen de Docker

Ejecutar el contenedor Docker

Ahora que se ha creado la imagen de Docker, puedes ejecutar el contenedor con el siguiente comando en el directorio del proyecto:

docker run -it -p 5000:5000 flask-app

En el comando anterior,-it le indica a Docker que ejecute el contenedor en modo interactivo, lo que significa que puedes interactuar con el shell del contenedor y asignar un tty al contenedor, lo que te proporciona una consola basada en texto. Sin embargo, el uso de -it al ejecutar la aplicación Flask no siempre es necesario, ya que no es una herramienta de línea de comandos que requiera un terminal interactivo. La bandera-p especifica la asignación de puertos del contenedor.

El primer 5000 es el puerto de la máquina host que tendrás que asignar al puerto del contenedor. El segundo 5000 es el puerto de contenedores. Yflask-app es el nombre de la imagen que acabamos de crear y queremos ejecutar.

La salida en el terminal después de ejecutar el comando será algo parecido a esto:


Imagen de ejemplo de contenedor

Y cuando te dirijas a http://localhost:5000/verás la aplicación básica de Flask. 

Prácticas recomendadas para la utilización de contenedores Docker

Aunque contenerizar una aplicación con Docker ofrece innumerables ventajas para el desarrollo y despliegue de aplicaciones, es importante seguir algunas prácticas recomendadas para aprovecharlas.

He aquí algunas reglas importantes que debes seguir:

  • Utiliza una imagen de base mínima: elige la imagen base más ligera que te sea posible, como Alpine Linux, para reducir el tamaño de la imagen final, disminuir el consumo de recursos y acelerar las compilaciones.
  • Utiliza construcciones multietapa: construye y compila en una sola etapa y, a continuación, copia sólo los artefactos necesarios en la etapa final para reducir el tamaño final de la imagen.
  • Minimiza las capas: reduce el número de capas de tu imagen combinando comandos en una única operación RUN porque cada capa añade overhead.
  • Limpia los archivos innecesarios: elimina archivos temporales, cachés y artefactos de compilación después de instalar dependencias o compilar la aplicación para reducir el tamaño de la imagen.
  • Ejecuta contenedores sin estado: almacena los datos persistentes fuera del contenedor en bases de datos, almacenamiento de objetos u otro sistema de almacenamiento externo para poder apagar el contenedor sin perder datos.
  • Etiqueta tus imágenes: las etiquetas ayudan a gestionar las versiones de tus imágenes. El uso de etiquetas únicas para las implantaciones permite escalar rápidamente un clúster de producción a muchos nodos.
  • Parchea tus contenedores: parchear y actualizar los contenedores es una forma proactiva de mejorar la seguridad y reducir las amenazas.

Docker: una herramienta esencial para el desarrollo moderno

La contenerización Docker ha revolucionado el desarrollo de aplicaciones. Las aplicaciones en contenedores ofrecen importantes ventajas, como portabilidad, escalabilidad, productividad, eficiencia y flexibilidad. Docker ha simplificado este proceso proporcionando un enfoque estandarizado y fácil de usar para la contenerización.

Adoptar Docker, asegurándote de seguir las prácticas recomendadas para la contenerización, puede mejorar el desarrollo, despliegue y gestión de las aplicaciones modernas. Al proporcionar un entorno de ejecución coherente, los contenedores permiten a los desarrolladores crear aplicaciones una sola vez y ejecutarlas en cualquier lugar, lo que simplifica el proceso en distintos entornos. La escalabilidad de los contenedores permite desplegar y escalar rápidamente las aplicaciones en microservicios más pequeños y desplegables.

Docker, como plataforma líder de contenerización, simplifica el proceso de creación, ejecución, gestión y distribución de aplicaciones en contenedores, lo que la convierte en una herramienta esencial para el desarrollo de software moderno.

Próximos pasos

La creación de un equipo de TI próspero y eficaz requiere contar con una solución centralizada que se convierta en tu principal herramienta de prestación de servicios. NinjaOne permite a los equipos de TI supervisar, gestionar, proteger y dar soporte a todos tus dispositivos, estén donde estén, sin necesidad de complejas infraestructuras locales.

Obtén más información sobre NinjaOne Endpoint Management, echa un vistazo a un tour en vivocomienza tu prueba gratuita de la plataforma NinjaOne.

También te puede gustar

¿Listo para simplificar los aspectos más complejos de las TI?
×

¡Vean a NinjaOne en acción!

Al enviar este formulario, acepto la política de privacidad de NinjaOne.

Términos y condiciones de NinjaOne

Al hacer clic en el botón “Acepto” que aparece a continuación, estás aceptando los siguientes términos legales, así como nuestras Condiciones de uso:

  • Derechos de propiedad: NinjaOne posee y seguirá poseyendo todos los derechos, títulos e intereses sobre el script (incluidos los derechos de autor). NinjaOne concede al usuario una licencia limitada para utilizar el script de acuerdo con estos términos legales.
  • Limitación de uso: solo podrás utilizar el script para tus legítimos fines personales o comerciales internos, y no podrás compartirlo con terceros.
  • Prohibición de republicación: bajo ninguna circunstancia está permitido volver a publicar el script en ninguna biblioteca de scripts que pertenezca o esté bajo el control de cualquier otro proveedor de software.
  • Exclusión de garantía: el script se proporciona “tal cual” y “según disponibilidad”, sin garantía de ningún tipo. NinjaOne no promete ni garantiza que el script esté libre de defectos o que satisfaga las necesidades o expectativas específicas del usuario.
  • Asunción de riesgos: el uso que el usuario haga del script corre por su cuenta y riesgo. El usuario reconoce que existen ciertos riesgos inherentes al uso del script, y entiende y asume cada uno de esos riesgos.
  • Renuncia y exención: el usuario no hará responsable a NinjaOne de cualquier consecuencia adversa o no deseada que resulte del uso del script y renuncia a cualquier derecho o recurso legal o equitativo que pueda tener contra NinjaOne en relación con su uso del script.
  • CLUF: si el usuario es cliente de NinjaOne, su uso del script está sujeto al Contrato de Licencia para el Usuario Final (CLUF).