Qué es Docker
Docker y la virtualización
Cuando desarrollamos una aplicación, es importante que tenga los requerimientos básicos para funcionar: sistema operativo, librerías, variables de entorno, paquetes, entre otras necesidades.
Cuando alguno de estos requerimientos no se cumple, la aplicación no puede funcionar como debe. Para evitar problemas de conflicto debemos asegurarnos de que se ejecute donde se ejecute, la aplicación siempre cuente con los requerimientos necesarios para funcionar.
Existen varias maneras para conseguir un entorno aislado. La más utilizada hasta ahora ha sido la virtualización, la cual consiste en crear un entorno aislado dentro de un dispositivo huésped. Podríamos ver la virtualización como una caja dentro de un sistema operativo que tiene acceso a los recursos de la máquina como CPU, disco o RAM y permite ejecutar aplicaciones dentro de ella.
Existen 3 maneras principales de llevar a cabo la virtualización:
¿Qué es un programador senior?
¿Quieres saber qué es un programador senior? En este post te contamos todo lo que debes saber sobre estos expertos del desarrollo de software.
Ver artículoMáquinas virtuales
Las máquinas virtuales son una simulación de un ordenador real. Es decir, cuando se arranca actúa como si fuera un dispositivo nuevo: tiene su propio sistema operativo, tiene recursos de memoria y disco, sus usuarios etc.
Un ejemplo es, cuando en un ordenador que tiene el sistema operativo de MacOS creamos una máquina virtual para instalar windows y poder ejecutar programas no disponibles para Mac. Existen varios programas que permiten crear máquinas virtuales. Algunos son:
- VirtualBox
- Parallels
- VMware Fusion
Las máquinas virtuales es el tipo de virtualización que se utiliza en los servidores en la nube para crear VPS (Virtual Private Server) y crear servidores con recursos y necesidades distintas.
No obstante, este tipo de virtualización tiene un problema. Requiere de una gran necesidad de recursos al ser ejecutado por encima de un sistema operativo. Este problema hizo que nacieran otras soluciones al aislamiento y virtualización.
Entornos virtuales
Los entornos virtuales es un tipo de virtualización que se usan mucho para ejecutar programas escritos en Python. Para cada entorno virtual (virtual environment) se usa una versión de Python y unas librerías en concreto. De esta forma podemos saber para cada proyecto que paquetes y librerías se necesita para ejecutarlo.
Otros posts que te gustarán
Normalmente, todos los paquetes y las librerías de Python necesarias se encuentran dentro del archivo requirements.txt que se crea a través del comando: pip freeze > requirements.txt.
Algunos ejemplos de herramientas que permiten crear entornos virtuales son:
- Conda
- Virtualenv
- Pipenv
Contenedores
Finalmente llegamos al sistema de virtualización que nos interesa en este artículo: los contenedores. Estos objetos son parecidos a las máquinas virtuales con la diferencia que son mucho más ligeros y no necesitan recursos de forma intensiva. Eso se debe a que no tienen un propio sistema operativo sino que hacen uso del SO de la máquina huésped.
El ejemplo más conocido es Docker aunque existen otras herramientas para crear contenedores como Vagrant o Ansible. Docker hace uso de un sistema de creación, eliminación y manejo de contenedores que recibe el nombre de containerd.
Contenerización en Docker
La mejor forma de entender cómo funciona Docker es imaginarse un container donde dentro tenemos todo lo necesario para ejecutar una aplicación: archivos, variables de entorno, librerías, compiladores, intérpretes…
Es importante mencionar que el sistema de contenedores funciona muy bien para sistemas UNIX por lo que si usas Windows seguramente necesites una máquina virtual donde ejecutar alguna distribución de Linux.
Resumiendo, Docker permite la generación de contenedores donde podemos aislar nuestras aplicaciones para que puedan ejecutarse en cualquier dispositivo ya que el contenedor alberga todas las dependencias y librerías necesarias para la ejecución.
Imágenes en Docker
Las imágenes son abstracciones que permiten crear los contenedores. Podríamos ver las imágenes como clases en un lenguaje de programación orientado a objetos (OOP). Usando este símil, los contenedores serían instancias (objetos) creados a partir de las imágenes (clases).
Normalmente, las instrucciones para construir una imagen se encuentran dentro de un archivo llamado Dockerfile. En las instrucciones encontramos la distribución de Linux, las librerías o el software necesario para la ejecución. También podemos especificar qué archivos tienen que ser copiados dentro del contenedor que generaremos a partir de la imágen de Docker.
Cómo funciona Docker
Normalmente, cuando trabajamos con contenedores y en concreto con la herramienta de Docker, usamos lo que se conoce como el cliente de Docker. Este componente contactará a través de una API con el componente encargado de generar, manejar y ejecutar tanto las imágenes como los contenedores.
Para poder manejar bien las imágenes y contenedores es importante saber ejecutar algunos de los comandos más básicos:
- docker -version
- docker pull
- docker push
- docker run
- docker ps
- docker exec
- docker stop
- docker kill
DockerHub
DockerHub es el repositorio oficial de Docker. Allí se encuentran todo tipo de imágenes para poder ejecutar contenedores: aplicaciones, bases de datos, software… Además, también te puedes crear tu repositorio y subir tus propias imágenes usando el comando docker push, parecido a como subiriamos nuestro código en Github o Gitlab.
Comunicación entre contenedores
Cuando creamos, por ejemplo, una aplicación web podemos tener diferentes servicios levantados en diferentes contenedores de Docker. Aunque sean sistemas aislados necesitan conectarse entre sí para transferir datos. Aquí es donde entra en juego el sistema de redes en Docker.
En Docker existen 3 tipos diferentes de redes:
- Red none : se usa para definir que dicho contenedor no tiene ninguna red asignada.
- Red bridge : la red bridge es la que viene configurada por defecto en todos los contenedores Docker. Esto permite la comunicación y envío de datos entre ellos a través de sus IPs (cada contenedor tiene asignada una IP desde el momento que se crea).
- Red host : este tipo de red no aísla los contenedores de la máquina huésped. Por lo que, si el contenedor tiene activo un servicio en el puerto número 80, la máquina huésped también dará ese servicio a través de este puerto.
Persistencia de datos
Los datos generados dentro de cada contenedor de Docker son eliminados una vez este está parado. Para poder persistir los datos independientemente de si paramos o arrancamos Docker, existe lo que se conoce como Volúmenes .
Los volúmenes son carpetas donde se guardan los datos que tienen que ser mantenidos. Estas carpetas se encuentran dentro de la máquina huésped, más concretamente en el directorio: /var/lib/docker/volumes .
Docker Compose
Docker Compose es un conjunto de herramientas que nos permiten lanzar varios contenedores a la vez. Cuando creamos una aplicación está puede tener varios componentes: bases de datos relacional, base de datos no relacional, servicios de manejos de colas…
Todos estos componentes tienen que ser lanzados en contenedores distintos. Levantar uno por uno sería muy tedioso. Es por eso que lo hacemos a través de un archivo de configuración llamado docker-compose.yml. Este fichero especifica las imágenes a usar, las variables de entorno, las especificaciones de red, los volúmenes donde se tienen que guardar los datos entre otras configuraciones.
En futuras publicaciones entraremos más en detalle en la parte técnica de Docker, especificando cómo deben ser los archivos y los comandos necesarios para lanzar los contenedores.
Además, también veremos como herramientas como Kubernetes o Docker Swarm nos permiten lanzar varios contenedores que interactúan entre sí de forma distribuida, es decir, en diferentes nodos, permitiendo una gran escalabilidad de las aplicaciones.