Docker, manual básico en español (2017)

docker-00-300[Actualizado, ampliado y corregido en noviembre de 2017.]

En 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 docker.io

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 (por ejemplo debian):

docker search debian

bajar una imagen:

docker pull debian

ver qué imágenes tengo en local:

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

(si intento arrancar una imagen que no tengo en local primero la descargará)

mirar qué contenedores tengo, su estado e información:

docker ps -a

arrancar un contenedor:

docker start ID (o nombre)

(un contenedor que esté detenido, pero ya antes creado, o sea que esté en STATUS Exited, podemos arrancarlo con docker start)

entrar en un contenedor:

docker attach ID (o nombre)

(si no tenemos una terminal abierta en un contenedor que esté corriendo, o sea en STATUS Up, podemos entrar en él con docker attach)

detener un contenedor:

docker stop ID (o nombre)

(esto no lo elimina, sólo lo detiene, lo pone en STATUS Exited, es lo mismo que teclear el comando exit desde una terminal suya)

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

amule en servidor – amuled, amulecmd y amuleweb en Raspberry Pi

amulecmd
amulecmd en una terminal conectada por ssh a la Raspberry Pi.

Por la noche es un momento ideal para poner a bajar en el Amule (el Emule de Linux) Juego de Tronos. Podemos aprovechar todo el ancho de banda sin perjudicar la calidad de navegación de la red y por la mañana tendremos todo bajadito y listo en el disco duro. Lo malo es dejar el Amule funcionando toda la noche y tener que aguantar el molesto ruido del ventilador del pc.

Por eso, una excelente solución, es correr la versión de Amule en consola, amuled (de amule daemon), que funciona como demonio sin tener que tener abierto el Amule y poder correrlo en algo tan silencioso como nuestra Raspberry Pi, que como no tiene ventilador es silenciosa y discreta.

Vamos allá. Tenemos una Raspberry (da igual el modelo) y podemos conectarnos a ella mediante ssh sin problema. Pues nos conectamos en un terminal a la Pi e instalamos el amule de consola:

sudo apt-get install amule-daemon

luego lanzamos el demonio para que cree los ficheros de configuración básicos, aunque no funcionará hasta que los modifiquemos nosotros. En el caso de que ya tuviésemos instalado el Amule normal estos ficheros ya están creados.

Puedes hacer un control+c para que cierre el proceso pero ya tendremos unos archivos para configurar.

Hacemos ls -a en nuestra home de la Pi para ver si tenemos un directorio .aMule y entramos en él:

ls -a

cd .aMule

aquí está el fichero de configuración amule.conf

Hay que tener en cuenta que este es el fichero de configuración general del Amule. En mi caso, como ya tenía instalado el Amule normal, con su GUI, pues ya está configurado con todos los datos de puertos abiertos en el router, las rutas de las carpetas de descargas, etc. Tal vez un buen truco para configurar fácilmente todo eso si no se quiere hacerlo directamente en el amule.conf es abrir el Amule normal vía ssh gráfico y configurarlo en él.

El caso es que aquí sólo añadiré los cambios que necesitamos para que funcione amuled. Serían estos:

primero hay que crear una contraseña de seguridad para poder trabajar con el amuled, se hace así:

echo -n contraseña | md5sum

Donde «contraseña» es la que tú pongas. La consola te responderá con una clave alfanumérica que es mejor copiar en un documento de texto aparte. Algo tipo «d41d8cd98f00b204e9800998ecf8427e –«

editamos el fichero amule.conf

nano amule.conf

buscamos «AcceptExternalConnections=»

cambiamos aceptar conexiones externas de 0 a 1.

AcceptExternalConnections=1

buscamos «ECPassword=» ahí es donde tenemos que copiar el código de antes, así:

ECPassword=d41d8cd98f00b204e9800998ecf8427e

(atención, NO copiar el espacio ni el guión que nos dio antes la consola)

un campo más a cambiar es «Password=»

Password=contraseña

(aquí la contraseña normal que pusimos al crear el código alfanumérico)

y ya de paso vamos a añadir también la configuración para poder usar la interfaz web que explico al final:

[WebServer]
Enabled=1
Port=4711

aquí autorizo a usar la interfaz web en ese puerto.

Y ya está, podemos guardar las modificaciones y salir de nano

control+o
control+x

para poder usarlo hay que arrancar el demonio así:

amuled &

(le ha colocado la «&» después para que lo ejecute en segundo plano y libere la terminal, porque si no, esa terminal se queda abierta ligada al proceso.)

Ahora que ya está funcionando el demonio podemos ejecutar el programa de control de Amule por consola:

amulecmd

vemos que responde:

***************************

This is amulecmd 2.3.1

Creating client...
Succeeded! Connection established to aMule 2.3.1

---------------------------------------
| aMule text client |
---------------------------------------

Use 'Help' for command list

aMulecmd$

***************************

pues ya estamos dentro, podemos teclear un help para conocer los comandos.

Lo básico es esto:

buscar:
search global juego de tronos 6×01

ver los resultados de búsqueda:

results

lo que nos muestra los resultados de búsqueda con un número delante

descargar lo que queramos:

download [el número que sea]

ver lo que se está descargando:

show dl

Se puede pausar, cambiar prioridades de descarga, etc, etc, te dejo a ti que investigues un poco.

***************************

Otra posibilidad, es manejar amuled mediante una interfaz web con amuleweb

Recuerda que en el amule.conf ya autorizamos la interfaz web.

Así que ya puedes activar la interfaz web así:

amuleweb --write-config --host=localhost --password=contraseña --admin-pass=contraseña

amuleweb &

(recuerda que «contraseña» tiene que ser tu contraseña normal, la que pusiste en «Password=contraseña» del fichero amule.conf

Entonces, en el navegador de cualquier equipo de tu intranet, si pones:

http://192.168.0.15:4711 (suponiendo que 192.168.0.15 es la IP de la Raspberry con el puerto que habíamos autorizado, el 4711 es por defecto)

entrarás en la interfaz web de Amule, te pedirá tu contraseña y ya podrás usar la interfaz web que, como puedes ver en la imagen de abajo, es muy parecida a la GUI normal del Amule.

Pues espero que lo disfrutes y puedas bajar tus cositas del Amule sin las molestias de tener que dejar tu pc funcionando durante horas.

amuleweb
amuleweb, la interfaz web de amuled.

Todo sobre el kernel en Gentoo

larryEsta entrada pretende ser un resumen de todo lo más importante sobre el kernel en Gentoo.
Se trata de tener una guía accesible en un sólo lugar cuando se nos haya olvidado algo sobre la abundante documentación sobre el núcleo (y otros núcleos alternativos) que hay en el Handbook oficial de Gentoo.

Empecemos:
¿Cómo se llama el paquete del kernel oficial en Gentoo?

gentoo-sources

nombre completo:  sys-kernel/gentoo-sources

***********************

Ver qué versión del kernel se está corriendo:

uname -rm

***********************

¿Dónde están los ebuilds disponibles de los kernels del árbol de Portage?

/usr/portage/sys-kernel/*.*

y las versiones disponibles del kernel oficial:

/usr/portage/sys-kernel/gentoo-sources/

***********************

¿Cómo saber qué versiones tengo disponibles para instalar con Portage desde consola?

equery m gentoo-sources

Esto nos dará todo un listado de las versiones que hay así como para qué arquitecturas están disponibles.

Podría hacer lo mismo para otros tipos de kernels, como los «vanilla», por ejemplo:

equery m vanilla-sources

***********************

Instalar la última versión estable disponible oficial del kernel:

primero actualizamos el árbol de Portage:

sudo emerge --sync

y luego:

sudo emerge -a gentoo-sources

Esto siempre instalará la última versión estable del kernel oficial, si deseamos que por defecto se instale siempre la última versión de la rama testing (más moderna) hay que añadir a nuestro archivo

/etc/portage/package.accept_keywords

las líneas:

# KERNEL LINUX TESTING
sys-kernel/gentoo-sources ~amd64

***********************

¿Cómo instalar un kernel concreto más antiguo en Portage?

miramos los kernels disponibles:

equery m gentoo-sources

e instalamos el que queramos de la siguiente manera:

sudo emerge -a =sys-kernel/gentoo-sources-3.10.100

en este caso instalamos la versión 100 de la rama del kernel 3.10 (LTS). Obsérvese que para que funcione hay que poner un signo igual (=) antes del nombre y ruta del kernel, pues si no, Portage no nos dejará.

***********************

Todo gentucito sabe que Portage no «instala» realmente el kernel, sino que se limita a descargar sus fuentes para permitirnos instalarlo de facto a nosotros. Digamos que Portage «emerge» un kernel, pero luego hay que configurarlo, compilarlo, instalarlo e integrarlo en el gestor de arranque (normalmente grub2).

Algunas cosas sobre esto:

¿Dónde están las fuentes de los kernels disponibles emergidos por Portage?

en

/usr/src/

están ahí, cada uno en su directorio con su número de versión.

Además hay un enlace simbólico llamado «linux» (/urs/src/linux/) que enlaza normalmente al último kernel compilado e instalado:

podemos ver desde línea de comandos las fuentes de kernel disponibles así:

eselect kernel list

lo cual nos lista los kernels disponibles. Observemos que uno de ellos al final tiene un asterisco (*) lo que indica a cual apunta el enlace simbólico /usr/src/linux/

Este enlace simbólico es importante, pues al instalar un nuevo kernel emergido con Portage, debemos hacerlo apuntar al nuevo kernel que nos interese configurar, compilar e instalar. Se hace así:

sudo eselect kernel set 2

(suponiendo que sea al kernel número 2 el que vamos a instalar). Lo cual cambia la ruta del enlace simbólico /urs/src/linux/ al nuevo (y por lo tanto también el asterisco ante un «eselect kernel list».

***********************

¿Cómo se instala un nuevo kernel?

su
cd /usr/src/linux/
make menuconfig
make
make modules_install
make install

(sudo emerge -a genkernel)
(genkernel –install initramfs)

estos dos pasos entre paréntesis no son necesarios si no queremos/necesitamos «initramfs»

grub-mkconfig -o /boot/grub/grub.cfg
exit
sudo reboot

Lógicamente esta parte es más complicada y por eso se explicó en su propia entrada:

Construcción y compilación manual del kernel en Gentoo (make menuconfig)

***********************

¿Dónde se guarda el fichero de configuración del kernel que hemos compilado?

siempre se encuentra en /usr/src/linux/.config (y en el directorio de cada kernel específico)

y normalmente también en /boot/config-4.4.5-gentoo (en este ejemplo el de mi versión 4.4.5)

Si al configurar el kernel hemos habilitado:

File systems —>
Pseudo filesystems —>
<*> /proc file system support

también podremos encontrar la configuración del kernel en:

/proc/config.gz

En los últimos tiempos, cuando actualizas a un nuevo kernel, Gentoo suele recuperar la configuración del anterior, con lo que no hay que activar cada vez todos los módulos de tarjeta gráfica, wifi, etc. Esto sólo será necesario si hay alguna nueva funcionalidad del kernel o se quiere cambiar algún parámetro de configuración.

***********************

¿Cómo eliminar kernels antiguos?

Se puede hacer con –depclean y con eclean-kernel, pero yo prefiero hacerlo de una manera manual, pues es más seguro.

Imaginemos que queremos eliminar un kernel antiguo que tenemos instalado, por ejemplo el linux-4.3.5-gentoo

Lo primero lo «sumergimos» 🙂 de Portage, así:

sudo emerge -Ca sys-kernel/gentoo-sources-4.3.5

de esta manera ya no está instalado «a efectos de Portage» pero hay que eliminarlo manualmente del sistema:

Primero eliminamos sus fuentes así:

sudo rm -r /usr/src/linux-4.3.5-gentoo

Segundo, eliminamos sus módulos del directorio pertinente, así:

sudo rm -r /lib/modules/4.3.5-gentoo

Tercero, eliminamos todos los archivos de esa versión del kernel en nuestro directorio /boot/ así:

sudo rm /boot/vmlinuz-4.3.5-gentoo
sudo rm /boot/System.map-4.3.5-gentoo
sudo rm /boot/config-4.3.5-gentoo

y finalmente, no nos olvidemos de actualizar grub2 para borrar la entrada del kernel eliminado:

sudo grub-mkconfig -o /boot/grub/grub.cfg

Y ya podemos rebootear tras la limpieza.

***********************

Y un pequeño truco/consejo para terminar.

Para que no se esté actualizando el kernel en cada actualización del sistema, pues a mí me gusta hacer todos los lunes un:

sudo emerge --sync && sudo emerge -uaDN --with-bdeps=y world

con lo que tengo cada semana el sistema actualizado, se puede fijar una versión del kernel  para que no se actualice hasta la siguiente que tú desees. Yo tengo la costumbre de sólo actualizar de una versión que termine en 5 hasta la siguiente que termine en 5. Por ejemplo, ahora tengo la 4.4.5 y no actualizaré hasta la 4.5.5 (así me garantizo cinco subversiones y correcciones de errores en cada nueva versión del kernel. Para esto, lo que hago es enmascarar el kernel en el directorio package.mask, por lo que creo un archivo de texto dentro:

/etc/portage/package.mask/gentoo-sources

y le agrego lo siguiente:

# NO ACTUALIZAR EL KERNEL HASTA:
<sys-kernel/gentoo-sources-4.5.5

como veis lo que he hecho es decirle a Portage que toda versión menor de la 4.5.5 está enmascarada, y por lo tanto no puede actualizarla. Así, me puedo olvidar del kernel hasta que se actualice a esa versión. Cuando esto ocurra, editaré este fichero cambiando sólo 4.5.5 por 4.6.5, o si es el caso por 5.0.5. o la que yo desee. Y ya está.

Chulo, ¿verdad?

***********************

Pues espero que esta sea una guía para tener delante cuando se necesite consultar las cosas básicas sobre el kernel en Gentoo.

Puede interesarte además:

Manual de genkernel en Gentoo (construcción automática del kernel)

y:

Manual-guía (casi) fácil para instalar GENTOO paso a paso

 

gentoo_wallpaper-36186