Skip to main content

Compartiendo Imágenes

Bien, ya hemos aprendido cómo crear una imagen de container, ya sea vía dockerfile o a través de la modificación de un container, y conocemos algunos comandos interesantes, como "docker build" y "docker commit".

Ahora vamos a aprender a compartir estas imágenes, ya sea en un registry local o en el registry del propio Docker Hub.

9.1. ¿Qué es Docker Hub?

Docker Hub es un repositorio público y privado de imágenes que proporciona diversos recursos, como por ejemplo, sistema de autenticación, build automático de imágenes, gestión de usuarios y departamentos de su organización, entre otras funcionalidades.

Personas y empresas se juntan, crean sus containers siguiendo las mejores prácticas, prueban todo correctamente y después lo ponen a disposición para que lo uses sin tener ningún trabajo. Esto es una gran ayuda, ya que no vas a tener que perder tiempo instalando cosas. También puedes usarlo para aprender cómo configurar determinado servicio. Para eso, basta con ir a Docker Hub y buscar; probablemente alguien ya creó un container que podrás usar al menos como base.

A pesar de esta facilidad de encontrar cosas listas, probablemente no vas a querer descargar de internet, aunque sea del registry del propio Docker (en serio), y subir a tu ambiente de producción algo que no tienes certeza de cómo funciona, qué es, etc.

Para resolver este problema, Docker proporciona algunas funcionalidades, como el comando "docker image inspect", que ya vimos antes, cuando hablábamos de volúmenes, ¿recuerdas? En aquel momento usamos el flag "-f" y especificamos un campo de búsqueda, pues la intención era mostrar solamente la parte que estaba siendo discutida en aquel capítulo. Pero "docker image inspect" va mucho más allá de eso; sin pasar el "-f", va a retornar todas las informaciones contenidas en aquella imagen, desde la imagen base que fue utilizada hasta puntos de montaje, configuraciones, en fin, muchas cosas. Prueba:

root@linuxtips:~# docker image inspect debian
[
{
"Id": "sha256:f50f9524513f5356d952965dc97c7e831b02bb6ea0619da9bfc1997e4b9781b7",
"RepoTags": [
"debian:8",
"debian:latest"
],
"RepoDigests": [],
"Parent": "",
"Comment": "",
"Created": "2016-03-01T18:51:14.143360029Z",
"Container": "557177343b434b6797c19805d49c37728a4445d2610a6647c27055fbe4ec3451",
"ContainerConfig": {
"Hostname": "e5c68db50333",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": null,
"Cmd": [
"/bin/sh",
"-c",
"#(nop) CMD ["/bin/bash"]"
],
"Image": "d8bd0657b25f17eef81a3d52b53da5bda4de0cf5cca3dcafec277634ae4b38fb",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"DockerVersion": "1.9.1",
"Author": "",
"Config": {
"Hostname": "e5c68db50333",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": null,
"Cmd": [
"/bin/bash"
],
"Image": "d8bd0657b25f17eef81a3d52b53da5bda4de0cf5cca3dcafec277634ae4b38fb",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"Architecture": "amd64",
"Os": "linux",
"Size": 125110803,
"VirtualSize": 125110803,
"GraphDriver": {
"Name": "aufs",
"Data": null
}
}
]

root@linuxtips:~#

A veces se proporcionará junto con la imagen su respectivo dockerfile y ahí queda mucho más fácil: basta leer ese archivo para saber exactamente cómo fue creada. :)

Un comando bastante interesante, que nos hace entender cómo una imagen está dividida en capas (y, principalmente, qué fue hecho en cada capa), es "docker history".

root@linuxtips:~# docker history linuxtips/apache:1.0

IMAGE CREATED CREATED BY SIZE COMMENT
4862def18dfd 36 minutes ago /bin/sh -c #(nop) EXPOSE 80/tcp 0 B
06210ac863da 36 minutes ago /bin/sh -c #(nop) VOLUME [/var/www/html/] 0 B
fed9b6bc7ad9 36 minutes ago /bin/sh -c #(nop) LABEL description=Webserver 0 B
68f6e8de3df3 36 minutes ago /bin/sh -c #(nop) ENV APACHE_LOG_DIR=/var/log 0 B
1a129e753d1e 36 minutes ago /bin/sh -c #(nop) ENV APACHE_RUN_GROUP=www-da 0 B
f0f9d7be7c70 36 minutes ago /bin/sh -c #(nop) ENV APACHE_RUN_USER=www-dat 0 B
3dafea4a403a 36 minutes ago /bin/sh -c #(nop) ENV APACHE_PID_FILE=/var/ru 0 B
f31eb176ecc8 36 minutes ago /bin/sh -c #(nop) ENV APACHE_LOCK_DIR=/var/lo 0 B
0bbefd91da05 36 minutes ago /bin/sh -c apt-get update && apt-get install 68.29 MB
f50f9524513f 12 days ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B
<missing> 12 days ago /bin/sh -c #(nop) ADD file:b5393172fb513d 125.1MB

root@linuxtips:~#

Observa que las primeras líneas de la salida del comando anterior son referentes a las informaciones que pedimos para agregar a la imagen en el dockerfile. Las demás capas son originales de la imagen que obtuvimos del Docker Hub a través de la instrucción "FROM".

Existe también un sitio llamado "ImageLayers": hace exactamente lo mismo que "docker history", pero no necesitas descargar la imagen -- y, bueno, es web. ImageLayers puede ser accedido en: https://imagelayers.io/.

Docker Hub, como ya hablamos, tiene muchos componentes, entre ellos el responsable del repositorio de imágenes: el registry.

Es posible utilizar un registry local en lugar de uno en la nube, como Docker Hub u otros registries que son fácilmente encontrados en internet. Hablaremos de eso con detalles más adelante. :P

Para que puedas utilizar Docker Hub para gestionar tus imágenes, es necesario crear una cuenta.

9.2. ¿Vamos a crear una cuenta?

Para que logres realizar la creación de tu cuenta, es necesario acceder a la URL https://hub.docker.com. Antes era posible a través del comando "docker login". Hoy, el comando "docker login" solamente se utiliza para autenticar en Docker Hub después de la creación de la cuenta.

A partir de la confirmación de tu correo electrónico, ya es posible autenticarse y comenzar a hacer uso de Docker Hub.

root@linuxtips:~# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.

Username: linuxtips01
Password:
Login Succeeded

root@linuxtips:~#

Puedes crear repositorios públicos a voluntad, pero en la cuenta free solamente tienes derecho a un repositorio privado. En caso de que necesites más de un repositorio privado, es necesario el upgrade de tu cuenta y el pago de una mensualidad. :)

En caso de que quieras especificar otro registry en lugar de Docker Hub, basta pasar la dirección como parámetro, como sigue:

# docker login registry.seilaqual.com

9.3. Ahora vamos a compartir estas imágenes en la interwebs

Una vez que ya creamos nuestra cuenta en Docker Hub, ¡podemos comenzar a utilizarla!

Como ejemplo, vamos a utilizar la imagen que montamos con el dockerfile en el capítulo anterior llamada "linuxtips/apache". Cuando realicemos el upload de esta imagen para Docker Hub, el repositorio tendrá el mismo nombre de la imagen, o sea, "linuxtips/apache".

¡Una cosa muy importante! Tu imagen deberá tener el siguiente patrón, para que logres hacer el upload para Docker Hub:

tuusuario/nombredelaimagen:versión

Así, sabemos que "linuxtips/apache:1.0" significa:

  • linuxtips -- Usuario de Docker Hub.

  • apache -- Nombre de la imagen.

  • 1.0 -- Versión.

Ahora vamos a utilizar el comando "docker push", responsable de hacer el upload de la imagen de tu máquina local para el registry de Docker Hub, como se muestra en el ejemplo a continuación:

root@linuxtips:~# docker push linuxtips/apache:1.0
The push refers to a repository [docker.io/linuxtips/apache]
b3a691489ee1: Pushed
5f70bf18a086: Layer already exists
917c0fc99b35: Pushed
1.0: digest: sha256:c8626093b19a686fd260dbe0c12db79a97ddfb6a6d8e4c4f44634f66991d93d0 size: 6861

root@linuxtips:~#

Accediendo a la URL https://hub.docker.com/ podrás visualizar el repositorio que acabas de crear, conforme a la imagen a continuación:

REPOSITORIO EN DOCKER HUB

Por defecto, crea el repositorio como público. ;)

En caso de que quieras visualizar tu nuevo repositorio por la línea de comando, basta utilizar el comando "docker search" seguido de tu usuario de Docker Hub:

root@linuxtips:~# docker search <seu_usuario>

NAME DESCRIPTION STARS OFFICIAL AUTOMATED
linuxtips/apache 0

Ya que poseemos la imagen en el registry de Docker Hub, vamos a probarla haciendo el pull de la imagen y en seguida vamos a ejecutarla para saber si realmente todo esto funciona de forma simple y fácil así. :)

Primero vamos a detener los containers que utilizan la imagen "linuxtips/apache":

# docker container ls | grep seu_usuario/sua_imagem
# docker container stop CONTAINERID

No es posible eliminar una imagen si algún container está en ejecución utilizándola como imagen base. Por eso es necesario detener los containers como hicimos antes.

Para que puedas eliminar una imagen es necesario utilizar el comando "docker image rm", responsable de eliminar imágenes del disco local.

Es importante mencionar que, en caso de que poseas containers detenidos que utilizan esa imagen como base, es necesario forzar la eliminación de la imagen utilizando el parámetro "-f":

# docker image rm -f linuxtips/apache:1.0
Untagged: linuxtips/apache:1.0

¡Listo! ¡Eliminamos la imagen!

Ahora vamos a realizar el pull de la imagen directamente del registry de Docker Hub para que tengamos la imagen nuevamente en nuestro disco local y así podamos levantar un container utilizándola.

root@linuxtips:~# docker pull linuxtips/apache:1.0
1.0: Pulling from linuxtips/apache
fdd5d7827f33: Already exists
a3ed95caeb02: Already exists
11b590220174: Already exists
Digest: sha256:c8626093b19a686fd260dbe0c12db79a97ddfb6a6d8e4c4f44634f66991d93d0
Status: Downloaded newer image for linuxtips/apache:1.0

root@linuxtips:~#

Podemos nuevamente visualizarla a través del comando "docker image ls".

root@linuxtips:~# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
linuxtips/apache 1.0 4862def18dfd About an hour ago 193.4 MB

root@linuxtips:~#

Para crear el container utilizando nuestra imagen:

root@linuxtips:~# docker container run -d linuxtips/apache:1.0

Simple como volar, ¿no?

9.4. No confío en internet; ¿puedo crear mi registry local?

Como muchas empresas no les gusta mantener sus datos en la nube en servicios de terceros, existe la posibilidad de que configures un registry local. Así, no necesitas utilizar el registry de Docker Hub, por ejemplo. Esto te permite compartir tus imágenes con otras personas de tu empresa, funcionando como repositorio de imágenes Docker. ¡Sensacional!

La URL del proyecto está en https://github.com/docker/distribution. Docker Distribution es un registry que sirve para guardar y compartir tus imágenes. Sustituye al Docker Registry, que se volvió obsoleto.

Para que podamos tener Docker Distribution de forma simple y totalmente funcional, guardando y distribuyendo nuestras imágenes Docker localmente, ¡basta ejecutarlo como un container! :D

root@linuxtips:~# docker container run -d -p 5000:5000 --restart=always --name registry registry:2
Unable to find image 'registry:2' locally
2: Pulling from library/registry
fdd5d7827f33: Already exists
a3ed95caeb02: Pull complete
a79b4a92697e: Pull complete
6cbb75c7cc30: Pull complete
4831699594bc: Pull complete
Digest: sha256:20f5d95004b71fe14dbe7468eff33f18ee7fa52502423c5d107d4fb0abb05c1d
Status: Downloaded newer image for registry:2
4f8efc8a71531656dc74e99dea74da203645c0f342b0706bc74200ae0a50cb20

root@linuxtips:~#

Con el comando anterior, creamos un container llamado "registry" que utiliza la imagen "registry:2" como base y usamos la opción "--restart=always". En caso de que ocurra cualquier problema con el container o con Docker, será iniciado automáticamente. Pasamos también que el puerto de comunicación con el container será el 5000, que también utilizará el puerto 5000 del host con el mismo propósito. Vamos a ver sobre el parámetro "-p" en breve, en el capítulo relacionado a redes. ;)

Puedes verificar el container del registry en ejecución, así como su imagen:

# docker container ls
# docker image ls

Muy bien, ¡nuestro registry ya está en ejecución! Ahora vamos a probarlo intentando realizar un push de nuestra imagen hacia él.

Primeramente, tendremos que agregar una nueva tag en nuestra imagen mencionando la dirección del nuevo registry en lugar del nombre del usuario que utilizábamos cuando queríamos hacer el push para Docker Hub. Para eso, vamos a utilizar nuevamente el comando "docker tag":

# docker tag IMAGEMID localhost:5000/apache
# docker image ls

Ahora basta hacer el push para nuestro registry local de la siguiente forma:

root@linuxtips:~# docker push localhost:5000/apache
The push refers to a repository [localhost:5000/apache]
b3a691489ee1: Pushed
5f70bf18a086: Pushed
917c0fc99b35: Pushed
latest: digest: sha256:0e69b8d5cea67fcfedb5d7128a9fd77270461aa5852e6fe9b465565ec8e4e12f size: 925

root@linuxtips:~#

¡Listo! ¡Ahora poseemos un registry local!

Hicimos un registry totalmente funcional, pero simple. En caso de que quieras utilizar recursos como control de usuarios, certificados, otras opciones de storage, etc., visita la página del proyecto en GitHub: https://github.com/docker/distribution.