Herramientas de usuario

Herramientas del sitio


clase:smr:sr:1eval:docker

01 - Docker I

La virtualización es una tecnología que permite crear varias máquinas virtuales (VMs) sobre un único hardware físico. Cada VM funciona como una máquina independiente con su propio sistema operativo y aplicaciones. Los hipervisores, como VMware, Hyper-V o VirtualBox, gestionan estas VMs, permitiendo compartir los recursos físicos del servidor (CPU, memoria, almacenamiento) entre las VMs.

Docker es una plataforma de contenedorización que permite a los desarrolladores empaquetar aplicaciones y sus dependencias en contenedores. Los contenedores son ligeros, portátiles y se ejecutan de manera consistente en cualquier entorno que soporte Docker. A diferencia de las VMs, los contenedores comparten el núcleo del sistema operativo del host, lo que los hace más eficientes en términos de recursos.

En Docker hay que diferencias dos conceptos:

  • Imagen: Plantilla inmutable que define lo que contiene un contenedor. Incluye el sistema de archivos y las dependencias necesarias para ejecutar una aplicación. Las imágenes son estáticas y se utilizan para crear instancias de contenedores.
  • Contenedor: Instancia ejecutable de una imagen. Es una unidad ligera y portátil que puede ser ejecutada en cualquier entorno que tenga Docker instalado. Los contenedores contienen todo lo necesario para ejecutar una aplicación, pero a diferencia de las imágenes, los contenedores son dinámicos y pueden cambiar durante su ejecución (por ejemplo, guardando datos en su sistema de archivos).

Instalación

Puedes instalar Docker siguiendo las instrucciones de su web. Dependiendo del sistema operativo. Por ejemplo, para instalar Docker en Ubuntu:

https://docs.docker.com/engine/install/ubuntu/

Puedes comprobar que todo se ha instalado correctamente comprobando la versión instalada:

docker --version

Docker version 27.0.3, build 7d4bcd8

Imagenes

Las imágenes de Docker son archivos que contienen todo lo necesario para ejecutar una aplicación: código, bibliotecas, dependencias y el sistema de archivos. Actúan como plantillas a partir de las cuales se crean contenedores.

Las imágenes se pueden descargar de registros de Docker, siendo el más popular Docker Hub. Docker Hub es un repositorio público que permite a los usuarios buscar, compartir y gestionar imágenes de Docker.

Lo normal es buscar el nombre de la imagen que queremos descargar en Docker Hub, pero, ¿qué pasa si sólo podemos usar una terminal sin entorno gráfico? En ese caso, no tendríamos acceso a un navegador, con lo que no podríamos acceder a Docker Hub.

Afortunadamente, podemos utilizar la orden docker search <imagen> en la terminal para buscar imágenes con ese nombre.

Las principales ordenes para trabajar con imágenes de Docker son:

Comando Descripción
docker image pull Descarga una imagen desde un registro (por ejemplo, Docker Hub)
docker image ls Lista todas las imágenes disponibles en el sistema local
docker image rm Elimina una imagen del sistema local
docker image build Construye una imagen a partir de un Dockerfile situado en la ruta especificada
docker image push Sube una imagen a un registro de Docker

Descargar

Para descargar imágenes de Docker Hub usamos docker image pull <imagen>. Los nombres de imágenes de Docker generalmente siguen el patrón usuario/imagen:tag:

  • usuario: Opcional. Es el nombre de usuario o la organización que posee la imagen en el registro de Docker. Si se omite, se asume que la imagen es oficial de Docker.
  • imagen: Obligatorio. Es el nombre de la imagen.
  • tag: Opcional. Es una etiqueta que especifica una versión particular de la imagen. Si se omite, se utiliza la etiqueta por defecto latest.

Por ejemplo, si queremos bajarnos la versión 8.0.39 de la imagen mysql del usuario bitnami:

docker pull bitnami/mysql:8.0.39

Mientras que si quisiéramos bajarnos la última versión lts oficial de mysql:

docker pull mysql

Listar

Para listar las imágenes que tenemos descargadas en local usamos docker image ls (o alguno de sus alias como docker images):

docker images

REPOSITORY                                  TAG       IMAGE ID       CREATED         SIZE
ubuntu-dhcp-server                          latest    d884c8118af6   3 weeks ago     83.5MB
mysql                                       latest    5cde95de907d   4 weeks ago     586MB
mysql                                       8.0       6c54cbcf775a   4 weeks ago     572MB
linuxserver/dokuwiki                        latest    b72ff6b0d7fb   7 weeks ago     117MB
mariadb                                     latest    4486d64c9c3b   7 weeks ago     406MB
ubuntu                                      latest    35a88802559d   8 weeks ago     78.1MB
docker.cloudsmith.io/isc/docker/kea-dhcp4   2.6.0     2fe3592342d0   2 months ago    80.6MB
docker.cloudsmith.io/isc/docker/kea-dhcp4   latest    2fe3592342d0   2 months ago    80.6MB
docker.cloudsmith.io/isc/docker/kea-dhcp4   2.4.1     f65fe5a3c577   8 months ago    88MB
docker/getting-started                      latest    3e4394f6b72f   19 months ago   47MB
networkboot/dhcpd                           latest    e25c872f0fca   24 months ago   139MB
mariadb                                     10.7.1    67a24127bba8   2 years ago     411MB

La salida del comando incluye la siguiente información:

  • REPOSITORY: El nombre del repositorio de la imagen.
  • TAG: La etiqueta de la imagen, que usualmente indica la versión.
  • IMAGE ID: El identificador único de la imagen.
  • CREATED: Cuándo se creó la imagen.
  • SIZE: El tamaño de la imagen.

Eliminar

Para eliminar imágenes que tenemos descargadas en local usamos docker image rm (o su alias docker rmi):

docker rmi <image_id>

Puedes especificar el IMAGE ID o el REPOSITORY:TAG de la imagen que deseas eliminar:

REPOSITORY                                  TAG       IMAGE ID       CREATED         SIZE
ubuntu-dhcp-server                          latest    d884c8118af6   3 weeks ago     83.5MB

docker rmi d884c8118af6

docker image rm ubuntu-dhcp-server

La salida del comando de eliminación confirmará que la imagen ha sido eliminada. Si una imagen está siendo utilizada por algún contenedor, se deberá eliminar primero el contenedor asociado.

Si estás utilizando un proxy en tu entorno, es posible que necesites configurar Docker para que funcione correctamente a través de él. La configuración del proxy es necesaria para que Docker pueda acceder a Internet y a los registros de imágenes, entre otros servicios.

Para obtener instrucciones detalladas sobre cómo configurar el proxy para Docker, consulta la documentación oficial. Esta guía te proporcionará los pasos necesarios para ajustar la configuración del proxy según tus necesidades específicas.

Contenedores

Los contenedores de Docker son instancias ejecutables de imágenes. Mientras que las imágenes son plantillas estáticas que contienen todo lo necesario para ejecutar una aplicación, los contenedores son unidades en ejecución que proporcionan un entorno aislado y consistente para que las aplicaciones se ejecuten.

Puedes crear y gestionar contenedores utilizando una variedad de comandos. Aquí están los más importantes:

Comando Descripción
docker container run Crea y ejecuta un nuevo contenedor a partir de una imagen
docker container start Inicia un contenedor que ha sido detenido previamente
docker container stop Detiene un contenedor en ejecución
docker container rm Elimina un contenedor del sistema local
docker container ls Lista todos los contenedores en ejecución
docker container exec Ejecuta un comando en un contenedor en ejecución
docker container logs Muestra los registros de un contenedor
docker container cp Copia archivos o directorios entre el contenedor y el sistema de archivos del host

Ejecutar

Para ejecutar un contenedor a partir de una imagen, utilizamos el comando docker run. Este comando no solo crea un nuevo contenedor, sino que también lo inicia y, por defecto, ejecuta el comando especificado en la imagen (además, si no hemos descargado la imagen en local lo primero que haría sería descargarla).

El comando básico tiene el siguiente formato:

docker run [opciones] <imagen> [comando]
Donde:

  • <imagen>: Es el nombre de la imagen a partir de la cual se creará el contenedor. Puede incluir una etiqueta opcional (por ejemplo, ubuntu:latest).
  • [comando]: Es el comando que se ejecutará dentro del contenedor. Si no se especifica, se usará el comando por defecto definido en la imagen.

Algunas opciones comunes que se pueden usar con docker run incluyen:

  • -d: Ejecuta el contenedor en segundo plano (modo “detached”).
  • -p <puerto_host>:<puerto_contenedor>: Mapea puertos del contenedor al host. Por ejemplo, -p 8080:80 mapea el puerto 80 del contenedor al puerto 8080 del host.
  • - -restart always : Añadiremos este flag si queremos que se vuelva a iniciar el contenedor si acaba dicho contenedor. Es útil ya que se iniciará el contenedor si se reinicia la máquina real.
  • - -name <nombre>: Asigna un nombre al contenedor, facilitando su gestión.
  • -v <volumen_host>:<volumen_contenedor>: Monta un volumen desde el host en el contenedor, permitiendo persistir datos.
  • -e <variable=valor>: Define variables de entorno en el contenedor.

Ejemplo de uso:

docker run -d -p 8080:80 --name mi_web nginx

En este ejemplo, el contenedor se ejecutará en segundo plano, exponiendo el puerto 80 del contenedor en el puerto 8080 del host, y se le asignará el nombre mi_web. La imagen utilizada es nginx, y se ejecutará el comando por defecto definido en esta imagen (iniciar el servidor web Nginx).

Otro ejemplo:

docker run --name mysql_web -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql

En este caso, el contenedor se ejecutará en segundo plano con el nombre mysql_web. La opción -e se usa para definir variables de entorno; en este ejemplo, se establece la variable MYSQL_ROOT_PASSWORD con el valor my-secret-pw, que configura la contraseña de root para la base de datos MySQL. La imagen utilizada es mysql, y se ejecutará el comando por defecto definido en esta imagen (iniciar el servidor MySQL).

El comando docker run es fundamental para crear y ejecutar contenedores a partir de imágenes, permitiendo la configuración de múltiples aspectos del contenedor en el momento de su creación.

Volumenes

Los volúmenes en Docker son una forma de persistir datos generados o utilizados por los contenedores. A diferencia de los datos almacenados dentro de un contenedor, que se perderán si el contenedor se elimina, los volúmenes permiten que los datos persistan incluso si el contenedor se detiene o se elimina.

Para persistir datos y asegurar que se mantengan entre reinicios o recreaciones de contenedores, Docker ofrece dos formas principales de manejar volúmenes:

  • Volúmenes Nombrados: Se crean y gestionan utilizando Docker. Estos volúmenes son independientes del ciclo de vida de un contenedor y pueden ser compartidos entre varios contenedores.
  • Volúmenes con Path: Basados en rutas del sistema de archivos del host. Esto permite montar un directorio local en el contenedor.

Crear un volumen nombrado:

docker volume create nombre_volumen

Inspeccionar un volumen:

docker inspect volume nombre_volumen

[
    {
        "CreatedAt": "2024-07-08T11:33:46+02:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/datos-todo/_data",
        "Name": "datos-todo",
        "Options": null,
        "Scope": "local"
    }
]

La salida del comando docker inspect muestra detalles como el punto de montaje del volumen y su nombre.

Utilizar un volumen nombrado con un contenedor:

docker run -dp 3000:3000 --name app-cambios -v nombre_volumen:/etc/todos app-cambios

En este ejemplo, el contenedor app-cambios montará el volumen nombre_volumen en el directorio /etc/todos. Los datos almacenados en este directorio persistirán incluso si el contenedor se elimina y se vuelve a crear, siempre y cuando el volumen no sea eliminado.

Montar un directorio local en un contenedor:

docker run -dp 3000:3000 -v ./datos-todo:/etc/todos app-cambios

En este ejemplo, el directorio local ./datos-todo se monta en /etc/todos dentro del contenedor. Los datos guardados en este directorio local se reflejarán dentro del contenedor y viceversa.

¿Cuándo usar cada tipo?

  • Volúmenes Nombrados: Ideal para compartir datos entre varios contenedores o para mantener datos persistentes que no están ligados a una ubicación específica en el host.
  • Volúmenes con Path: Útil cuando necesitas vincular un directorio específico del host con un contenedor, o cuando cada contenedor debe tener acceso a datos específicos del host.

Ejecutar comandos en el contenedor

La orden docker container exec permite ejecutar comandos en un contenedor en funcionamiento. Esta funcionalidad es útil para realizar tareas como la depuración, administración o inspección de un contenedor en tiempo real.

El formato básico del comando es:

docker exec [opciones] <contenedor> <comando> [argumentos]

Donde:

  • <contenedor>: Es el nombre o ID del contenedor en el que se desea ejecutar el comando.
  • <comando>: Es el comando que se ejecutará dentro del contenedor. Puede ser cualquier comando que el contenedor soporte.
  • [argumentos]: Son los argumentos opcionales que se pasan al comando.

La opción más comun es -it, la cual ejecuta el comando en modo interactivo y asigna un terminal. Esto es útil para ejecutar shell interactivos, como bash o sh.

Por ejemplo, ejecutar bash dentro de un contenedor para abrir una sesión de shell bash dentro de él, permitiendo interacturar con él directamente.

docker exec -it mi_contenedor /bin/bash

Ejecutar un comando no interactivo:

docker exec mi_contenedor ls /app

Aquí, el comando ls /app se ejecuta dentro del contenedor mi_contenedor. Este comando no requiere interacción y muestra el contenido del directorio /app en el contenedor.

Si el contenedor no está en ejecución, docker exec no podrá ejecutar el comando. Asegúrate de que el contenedor esté activo utilizando docker ps antes de intentar ejecutar un comando en él.

La orden docker exec es esencial para la administración y mantenimiento de contenedores en ejecución, permitiendo realizar tareas sin necesidad de detener o reiniciar el contenedor.

Ejercicios

Ejercicio 1

  • Instala Docker en tu ordenador
  • Comprueba que todo se ha instalado correctamente

Ejercicio 2

  • Busca por terminal la imagen de Docker hello-world
  • ¿Cuál de todas las imágenes es la oficial?
  • Haz lo mismo, pero en DockerHub. Marca a la izquierda la casilla Docker Official Image y comprueba que coincide con tu elección del punto anterior
  • Descarga y ejecuta la imagen elegida en tu ordenador
  • Haz lo mismo con la imagen hello-seattle
  • Muestra las imágenes descargadas en tu ordenador
  • Intenta borrar la imagen hello-seattle ¿Por qué te está dando error?
  • Lista los contenedores de tu ordenador con la opción ls sin parámetros ¿Ves algún contenedor de la imagen hello-seattle?
  • Vuelve a listar los contenedores con la opción ls -a ¿Por qué ahora sí que se muestra el contenedor de la imagen hello-seattle? ¿Para qué sirve la opción -a?
  • Elimina el contenedor que usa hello-seattle y la imagen
  • Vuelve a listar las imágenes y comprueba que se ha borrado correctamente

Ejercicio 3

  • Descarga la imagen oficial de mysql
  • Con la imagen que te has descargado, crea un contenedor con nombre mysql_smr y smr como password del usuario root
  • Ejecuta desde la terminal la orden:

docker exec -it mysql_smr mysql -u root -p

  • Comprueba que puedes conectarte al Mysql del contenedor
  • Ejecuta la siguiente orden dentro de Mysql para crear una nueva base de datos:

CREATE DATABASE prueba;

No te olvides del ; final
  • Comprueba que se ha creado la bbdd con la orden:

show databases;

Ejercicio 4

  • Para el contenedor mysql_smr y vuelve a iniciarlo
Para salir de mysql y del contenedor ejecuta la orden exit
  • Conéctate de nuevo a Mysql y comprueba que la bbdd prueba sigue estando
  • Elimina el contenedor mysql_smr
  • Vuelve a crearlo con los mismos parámetros y comprueba que la bbdd prueba no existe
  • Sal del contenedor y elimínalo

Ejercicio 5

  • Crea un directorio llamado mysql_data
  • Vuelve a crea el contenedor mysql con los mismos parámetros anteriores pero indicando que la carpeta del contenedor /var/lib/mysql se guardará en el directorio recién creado (mysql_data)
  • Crea de nuevo la bbdd pruebas dentro del Mysql del contenedor
  • Sal y elimina el contenedor
  • Crea de nuevo el contenedor sin mapear ninguna carpeta (sin utilizar volúmenes) y comprueba que la bbdd prueba no existe
  • Vuelve a salir y eliminar el contendor
  • Crea de nuevo el contenedor pero mapeando la carpeta igual que antes (la carpeta /var/lib/mysql del contenedor se guardará en mysql_data)
  • Comprueba que la bbdd sigue estando en Mysql

Ejercicio 6

  • Crea un directorio llamado php_data
  • Crea un archivo llamado index.php en el directorio recién creado con el siguiente contenido:

<?php
phpinfo();

  • Arranca un contenedor con la imagen php:8.0-apache y nombre php_smr indicando que la carpeta del contenedor /var/www/html se guardará en la carpeta creada en el primer punto. Además, el puerto 80 del contenedor se mapeará al puerto 11211 de la máquina real
  • Abre un navegador accede a http://localhost:11211. Comprueba que se muestra una página similar a ésta:

  • Reinicia la máquina real
  • Comprueba que accediendo a la anterior url se produce un error
  • Borra el contenedor
  • Vuelve a crear el contenedor pero ahora añade que siempre se reinicie
  • Reinicia la máquina real
  • Comprueba que navegando a la anterior url ahora si que funciona
clase/smr/sr/1eval/docker.txt · Última modificación: 2024/08/13 11:59 por cesguiro