Docker, manual en español

docker-00-300En una entrada de hace un par de años ya hablé de LXC, los contenedores Linux.

LXC (linux containers) linux dentro de linux.

Hoy hablaremos de Docker.

Docker, como LXC, utiliza el kernel de Linux para conseguir contenedores encapsulados, es lo que se llama virtualización a nivel del sistema operativo, hasta ahí son básicamente lo mismo, pero la “filosofía” de Docker es diferente.

Mientras LXC crea un contenedor Linux que es una sistema operativo completo, que puede correr múltiples servicios y que acumula los cambios que le hagamos, los contenedores Docker son versiones mínimas de una imagen Linux creada para una tarea específica, y que (aunque pueden hacerlo) se pretende que solo corran un único servicio. De ahí que el concepto de arquitectura de microservicios tenga mucho que ver con Docker.

Mientras un contenedor LXC es lo mismo que un servidor físico, o que una máquina virtual (VMware o VirtualBox) pero es virtualización a nivel de OS, Docker crea minicontenedores “apilables” para aplicaciones o servicios individuales. Simplificando la tarea de copiar, clonar, escalar y portar servicios. Es por eso ideal para la nube.

Para comprenderlo, hay que entender dos conceptos básicos en Docker:

Es muy importante distinguir las imágenes de los contenedores.

Las imágenes.

Una imagen de Docker, es una estructura de directorios y paquetes mínima, creada para una función básica. Se trata de que sea una plantilla, que se puede modificar, pero que ha sido pensada para una uso básico y específico. Por ejemplo, una imagen Debian con un Apache. De esta forma, para tener múltiples servidores web apache, cada uno encapsulado y aislado de los demás, sólo tendremos que crear contenedores desde ella, y cada uno será un servidor web distinto, con su propia IP, al que se puede configurar de manera independiente y que a su vez de puede clonar o mover donde se quiera.

Los contenedores.

Un contenedor, es una instancia generada desde una imagen, que ya es en sí un pequeño OS funcionando, y que podemos usarlo para una función concreta (como por ejemplo correr un Apache).

Por eso en Docker se trabaja primero con imágenes (las plantillas) y luego con contenedores (los minisistemas operativos funcionando). Veamos.
Instalamos Docker:

sudo apt install lxc-docker

sudo pacman -S docker

sudo emerge -a docker

(yo he instalado Docker en Gentoo y hay que tener en cuenta que en Gentoo hay que recompilar el núcleo con la configuración adecuada para que funcione Docker, véase https://wiki.gentoo.org/wiki/Docker)

Docker tiene dos partes, un demonio que debe arrancarse de fondo, y el cliente Docker que usamos para trabajar con él en consola.

Por lo tanto arrancamos el demonio (casi seguro que será con Systemd)

sudo systemctl start docker

si no usas Systemd:

/etc/init.d/docker start

y el demonio de Docker ya estará funcionado de fondo.

Si no queremos tener que estar siempre poniendo sudo, podemos meter a nuestro usuario en el grupo “docker”:

sudo gpasswd -a tu-usuario docker

newgrp docker

Y ya podremos usar Docker sin sudo.

Puedo ver información de Docker mediante:

docker version

y

docker info

Y ahora podemos buscar en remoto una imagen así:

docker search debian

o docker searh arch, docker search ubuntu, docker searh busybox, docker search apache, docker search wordpress, etc, etc.

(aquí podemos ver en la web las imágenes disponibles: https://hub.docker.com/explore/ )

Vemos que nos muestra un listado de imágenes listas para usar, diferentes distros, versiones, servidores web como Apache o Nginx, bases de datos, WordPress, etc, etc.

Bajemos una imagen de Busybox (un pequeño Linux para probar)

docker pull busybox

tras esto, si todo ha ido bien, ya tenemos una imagen de Busybox en local.

Podemos ver nuestras imágenes así:

docker images

y ahora ha llegado el momento de correr nuestro primer contenedor Docker, vamos allá:

docker run -it busybox sh

vemos que aparece el prompt y estamos dentro de nuestro contenedor.

podemos hacer

ls

o

ifconfig

y trabajar dentro como en cualquier distro Linux.

Dejamos esa terminal con Busybox y abrimos una nueva terminal.

Podemos ver en esta segunda terminal que el contenedor está funcionando:

docker ps -a

Si abrimos una segunda instancia desde la imagen Busybox, tendremos otro contenedor, idéntico pero distinto, veamos, otra vez:

docker run -it busybox sh

ya estamos en el segundo contenedor, abrimos una tercera terminal y lo vemos:

docker ps -a

docker-01
los dos contenedores busybox funcionando

vemos que ahora hay dos contenedores funcionando, cada uno tiene su propia ID, los dos están creados desde la imagen “busybox”, y al final vemos que Docker le asigna a cada uno un simpático nombre automáticamente.

Puedo hacer un “ifconfig” en ambos y hacer un ping de uno a otro, con lo que comprobaré que se comunican perfectamente como si fuesen dos máquinas reales y distintas en dos puntos cualquiera del planeta. 🙂
O podría conectar de uno a otro mediante SSH. ¿Alucinante no?

Puedes bajar las imágenes que quieras y crear desde ellas múltiples contenedores.

docker pull debian

docker pull ubuntu

docker pull archlinux

y luego:

docker run -it debian sh

docker run -it ubuntu bash

docker run -it archlinux /bin/bash

(en sucesivas terminales)
(obsérvese que en algunos casos arranco en contenedor con el comando al final “sh” un shell genérico, aunque normalmente, como estará instalado Bash, utilizo su propio comando con o sin ruta “bash” o “/bin/bash”

con lo cual ya tendríamos funcionando dos instancias de Busybox, un Debian, un Ubuntu y un Arch. Todo un cluster propio.

Cada instancia tiene su propia ID, su propio nombre, su propia interfaz de red y funciona de forma autónoma.

Por supuesto en Debian y en Ubuntu puedo usar APT, y en Arch Pacman, para instalar software.

Y aquí encontramos una gran diferencia entre Docker y LXC. Si en un contenedor LXC, supongamos que un Debian, hago apt-get update & atp-get upgrade, el contenedor guarda los cambios, es un contenedor persistente. Si embargo, los contenedores Docker no lo son. Esto quiere decir que si lo cerramos, no guardará los cambios, pues son contenedores no persistentes. Han sido pensado así, para la persistencia tenemos las imágenes.

Pero, lo que sí puedo hacer es crear un contenedor desde una imagen original, luego hacerle los cambios que yo quiera, y generar desde él una nueva imagen, esta ya sí, con nuestros cambios. Veamos un ejemplo.

Ya tenemos una imagen Debian que hemos bajado antes, pues primero la corremos si no lo habíamos hecho, si ya la tenemos corriendo simplemente nos vamos a la terminal que la controla:

docker run -it debian bash

Ya estamos dentro.

Hacemos:

apt-get update & apt-get upgrade

para actualizar el sistema.

Instalamos tres paquetes básicos:

apt-get install nano htop screenfetch

El editor nano, el visor de procesos de sistema htop y screenfetch para embellecer nuestra terminal.

editamos con nano el archivo de configuración de bash:

nano /root/.bashrc

y le añadimos la línea:

screenfetch

ctl+o y ctl+x para guardar y salir de nano.

Resumo, hemos actualizado nuestro contenedor Debian mediante APT y hemos instalado 3 paquetes y configurado nuestra terminal. Pero si ahora saliésemos y cerrásemos el contenedor perdería los cambios, por lo que voy a guardar una imagen nueva desde él para poder usarla como nueva plantilla (imagen) de mi Debian. Esto se hace así:

Abro otra terminal:

docker ps -a

miro la ID del contenedor que he modificado y hago:

docker commit -m "Debian actualizado y con nano, htop y screenfetch" -a essau 831e2760f30b deb

Lo explico, “docker commit” es el comando que se encarga de crear una nueva imagen desde un contenedor, “-m” es comentario para saber qué he hecho, “-a” es el autor de la modificación, y luego va la ID del contenedor y finalmente el nombre que le doy a esta nueva imagen modificada por mí, en ente caso la he llamado “deb”.

Si ahora miro qué imágenes tengo:

docker images

puedo ver que además de la Debian original, tengo una nueva que se llama “deb”. Si creo contenedores desde la original estarán “vírgenes”, pero si creo uno desde la nueva:

docker run -it deb bash

docker-02
Un contenedor Debian, actualizado y personalizado por mí, funcionado.

Vemos que al arrancar un contenedor desde ella, aparece la terminal con screenfetch, tal y como habíamos modificado 🙂
Ya para terminar una lista de los comandos de Docker más importantes:
ayuda:

docker

buscar imágenes:

docker search debian

bajar una imagen:

docker pull debian

ver qué imágenes tengo:

docker images

historial de una imagen:

docker history ID o nombre de la imagen

eliminar una imagen:

docker rmi “ID de la imagen”

arrancar un contenedor desde una imagen:

docker run -it debian bash
mirar qué contenedores tengo, su estado e información:

docker ps -a

arrancar un contenedor:

docker start ID (o nombre)

entrar en un contenedor:

docker attach ID (o nombre)

(no sé aún porqué, docker start y docker attach dan a veces problemas, en caso de duda lo que siempre funciona es docker run -it nombre-imagen bash)

detener un contenedor:

docker stop ID (o nombre)

eliminar un contenedor:

docker rm ID (o nombre)

guardar una imagen nueva desde un contenedor modificado:

docker commit -m “comentario” -a autor ID nuevo-nombre

docker-arch
Varias imágenes y un contenedor docker corriendo en mi host Gentoo.

 


Apéndice:

Lo fascinante de Docker es que no sólo puedo crear contenedores en mi máquina para jugar, sino que puedo crear contenedores de la nube para tener mis propios servidores que corran mis microservicios.
Para ello, lo más fácil es usar AWS (Amazon Web Services) que te da un año gratis para trastear y aprender:

http://aws.amazon.com/es/docker/

o también en Google, que da gratis hasta cinco nodos:

https://cloud.google.com/container-engine/


Ampliar información, en inglés 😦 :

https://www.docker.com/

http://prakhar.me/docker-curriculum/

docker-04

Anuncios

3 comentarios en “Docker, manual en español”

  1. Hola Essau, con docker run se crean contenedores desde una imagen o plantilla. De esta forma se crearan tantos contenedores como comandos “docker run” hayamos ejecutado. Lo idea es una vez creado el contenedor, usar el comando “docker start -a -i”. Muchas gracias por la info, estoy usando docker en Gentoo, en realidad estoy trasteando con docker. Saludos.

  2. Muchas gracias por el articulo, muy claro todo!.. Una pregunta, cual es el comando para detener el demonio de Docker?..

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s