Que es docker?
Docker es una aplicación que nos permite de manera sencilla correr procesos dentro de contenedores, que se comportan como si fueran maquinas virtuales, pero son mas portables y consumen menos recursos (y son mas dependientes del sistema operativo del host).
En este tutorial veremos como implementar docker en un servidor existente que lleva instalado Ubuntu 16.04.
Requisitos:
Para poder completar este tutorial necesitaremos:
- Acceso a un servidor que tenga instalado Ubuntu 16.04 de 64 bits.
- Un usuario de acceso «no root» con privilegios de sudo.
Paso 1: Instalar docker
El paquete de instalación de docker que viene disponible en Ubuntu 16.04 tiende a no ser la ultima versión disponible, para obtener la ultima versión instalaremos docker desde el repositorio oficial.
Empezaremos por actualizar la base de datos de repositorios:
sudo apt-get update
Continuaremos agregando la llave GPG del repositorio oficial de docker a nuestro sistema:
sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
Y agregaremos el repositorio de docker:
echo "deb https://apt.dockerproject.org/repo ubuntu-xenial main" | sudo tee /etc/apt/sources.list.d/docker.list
Actualizamos la base de datos de repositorios una vez mas:
sudo apt-get update
Por ultimo nos aseguraremos de bajar docker del repositorio oficial y no del de ubuntu:
apt-cache policy docker-engine
Tendriamos que ver algo similar a esto:
docker-engine:
Installed: (none)
Candidate: 1.11.1-0~xenial
Version table:
1.11.1-0~xenial 500
500 https://apt.dockerproject.org/repo ubuntu-xenial/main amd64 Packages
1.11.0-0~xenial 500
500 https://apt.dockerproject.org/repo ubuntu-xenial/main amd64 Packages
En la salida del comando vemos que docker-engine no esta instalado pero en caso de hacerlo lo haremos desde el repositorio de docker y no del de ubuntu.
Finalmente instalaremos docker:
sudo apt-get install -y docker-engine
Excelente! ya tenemos docker configurado, el daemon iniciado y configurado el inicio junto al sistema. Revisaremos que todo este corriendo:
sudo systemctl status docker
Lo que tendría que devolvernos algo similar a esto:
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2016-05-01 06:53:52 CDT; 1 weeks 3 days ago
Docs: https://docs.docker.com
Main PID: 749 (docker)
Al instalar docker no solo obtuvimos el servicio de docker sino también el cliente.
Paso 2: Usar los comandos de docker
Ahora que tenemos docker instalado y funcionando es tiempo de familiarizarnos con los comandos del cliente, estos responden a la siguiente sintaxis:
docker [opcion] [comando] [argumentos]
Si queremos ver todos los comandos disponibles escribiremos:
docker
A partir de docker 1.11.1 la lista de comandos disponibles es:
attach Attach to a running container
build Build an image from a Dockerfile
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes on a container's filesystem
events Get real time events from the server
exec Run a command in a running container
export Export a container's filesystem as a tar archive
history Show the history of an image
images List images
import Import the contents from a tarball to create a filesystem image
info Display system-wide information
inspect Return low-level information on a container or image
kill Kill a running container
load Load an image from a tar archive or STDIN
login Log in to a Docker registry
logout Log out from a Docker registry
logs Fetch the logs of a container
network Manage Docker networks
pause Pause all processes within a container
port List port mappings or a specific mapping for the CONTAINER
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart a container
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop a running container
tag Tag an image into a repository
top Display the running processes of a container
unpause Unpause all processes within a container
update Update configuration of one or more containers
version Show the Docker version information
volume Manage Docker volumes
wait Block until a container stops, then print its exit code
Para ver que parámetros debemos usar en cada comando utilizaremos:
docker nombre-del-comando --help
Para ver la información del sistema usaremos:
docker info
Paso 3: Trabajando con las imágenes de docker
Los contenedores de docker corren en base a imágenes, por default estas imágenes son descargadas de Docker Hub. Cualquiera puede armar y distribuir imágenes de docker en el Docker Hub, así que es muy probable que la aplicación que querramos correr ya este disponible en el Hub.
Para confirmar que podamos acceder y descargar imágenes desde el Hub de Docker usaremos el comando:
docker run hello-world
Este comando nos debería devolver algo similar a esto:
Hello from Docker.
This message shows that your installation appears to be working correctly.
...
Podemos buscar las imágenes disponibles en el Hub utilizando el comando search, por ejemplo para buscar imágenes de Ubuntu usaremos:
docker search ubuntu
El cliente automáticamente recorrerá el Hub de Docker y nos devolverá un listado de imágenes que contengan la palabra ubuntu en su nombre, este caso nos devuelve algo similar a esto:
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
ubuntu Ubuntu is a Debian-based Linux operating s... 3808 [OK]
ubuntu-upstart Upstart is an event-based replacement for ... 61 [OK]
torusware/speedus-ubuntu Always updated official Ubuntu docker imag... 25 [OK]
rastasheep/ubuntu-sshd Dockerized SSH service, built on top of of... 24 [OK]
ubuntu-debootstrap debootstrap --variant=minbase --components... 23 [OK]
nickistre/ubuntu-lamp LAMP server on Ubuntu 6 [OK]
nickistre/ubuntu-lamp-wordpress LAMP on Ubuntu with wp-cli installed 5 [OK]
nuagebec/ubuntu Simple always updated Ubuntu docker images... 4 [OK]
nimmis/ubuntu This is a docker images different LTS vers... 4 [OK]
maxexcloo/ubuntu Docker base image built on Ubuntu with Sup... 2 [OK]
admiringworm/ubuntu Base ubuntu images based on the official u... 1 [OK]
La columna OFFICIAL indica que es una imagen oficial y creada por la misma gente de docker. Una vez encontrada la imagen a utilizar la descargaremos utilizando el comando pull:
docker pull ubuntu
Una vez que la descarga haya finalizado, correremos el contenedor basado en esta imagen utilizando el comando run:
docker run ubuntu
Para listar las imagenes descargadas utilizaremos:
docker images
Lo que nos tendría que devolver algo asi:
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest c5f1cf30c96b 7 days ago 120.8 MB
hello-world latest 94df4f0ce8a4 2 weeks ago 967 B
Paso 4: Corriendo un contenedor
En el paso anterior corrimos el contenedor hello-world, este es un ejemplo de un contenedor que se ejecuta y luego se cierra (después de haber mostrado el mensaje). Los contenedores pueden ser mucho mas útiles y complejos que el de hello-world y a su vez pueden ser interactivos (como lo seria una maquina virtual).
Como ejemplo ejecutaremos un contenedor usando la imagen de Ubuntu que descargamos anteriormente. Usaremos los comandos -i y -t que nos brindaran acceso shell al contenedor:
docker run -it ubuntu
Notaremos como cambia la linea de comandos, lo que quiere decir que estamos trabajando dentro de un contenedor, por ejemplo ahora dirá:
root@d9b100f2f636:/#
Es importante tener en cuenta que el ID del contenedor se mostrara en la linea de comandos, por ejemplo en el ejemplo de arriba el ID es: d9b100f2f636.
Ya podemos correr cualquier comando que deseemos dentro del contenedor, por ejemplo actualizaremos el sistema y luego instalaremos NodeJS:
apt-get update
apt-get install -y nodejs
Paso 5: Guardando cambios que hicimos en un contenedor a una imagen
El sistema de archivos de docker es temporario por default, esto quiere decir que si iniciamos un contenedor desde una imagen, creamos, modificamos o borramos archivos, una vez que apaguemos el contenedor y lo volvamos a iniciar, todos los cambios se habrán perdido. Esto se debe a que las imágenes de docker son mas bien «templates» que imágenes como tendríamos en maquinas virtuales.
Para poder guardar los cambios que hicimos en nuestro contenedor tendremos que:
En el paso 4 instalamos NodeJS dentro de nuestro ubuntu, es decir que luego de hacer este cambio, nuestro contenedor difiere de la imagen original. Para guardar los cambios hechos a una nueva imagen primero debemos salir del contenedor, para eso usaremos el comando:
exit
Luego haremos un commit de estos cambios a una nueva imagen de docker:
docker commit -m "Descripcion de la imagen" -a "Nombre del dueño de la imagen" ID-DEL-CONTENEDOR repositorio/nuevo_nombre_de_la_imagen
Tener en cuenta que el ID-DEL-CONTENEDOR es el numero que anotamos anteriormente cuando nos conectamos al contenedor.
Por ejemplo:
docker commit -m "ubuntu con node.js" -a "Julio Barnils" d9b100f2f636 julio/ubuntu-nodejs
Una vez completada la operación, veremos la imagen al listar las imágenes de docker.
Julio Barnils