Docker Machine: Como crear y administrar multiples hosts

En este post les mostrare como crear y administrar múltiples hosts, ya sean máquinas virtuales o servidores físicos de Docker Engine.

Docker Machine es una muy buena herramienta que permite de manera remota instalar y administrar Docker Engine en cualquier máquina virtual, servidor físico e incluso en servicios de la nube como lo pueden ser Amazon Web Services, Azure,  Digital Ocean, entre otros, para ello Docker Machine utiliza distintos driver que permiten interactuar con los antes mencionados servicios y proveedores, se puede encontrar una lista de drivers con los servicios soportados en la siguiente dirección: Supported Drivers for Docker Machine.

El funcionamiento de Docker Machine permite que desde tu computador personal, instalar, actualizar y provisionar cualquier nodo creado con Docker Engine y luego administrarlo de manera remota, tan solo tendremos que tener instalado Docker Machine en nuestro computador. Es muy importante mencionar que Docker Machine genera los certificados TLS para que la comunicación entre nuestro computador y los hosts o nodos sea segura.

 

Instalando Docker Machine:

Para instalar Docker Machine en nuestro computador, tan solo tendremos que ejecutar lo siguiente en nuestra línea de comandos:

$ curl -L https://github.com/docker/machine/releases/download/v0.7.0/docker-machine-`uname -s`-`uname -m` > /usr/bin/docker-machine
$ chmod +x /usr/bin/docker-machine

Con lo anterior ejecutado instalamos y luego asignamos permisos de ejecución al script. Para verificar la instalación ejecutamos:

$ docker-machine version
docker-machine version 0.7.0, build a650a40

 

Crear una VM de Docker Engine con VirtualBox:

Para ello, deberemos contar con la ultima versión de VirtualBox instalada y funcionando correctamente en nuestro computador. En la línea de comandos ejecutamos lo siguiente:

$ docker-machine create --driver virtualbox testing-01

Lo anterior ejecutado generar una salida parecida a la siguiente:

Creating CA: /home/$USER/.docker/machine/certs/ca.pem
Creating client certificate: /home/$USER/.docker/machine/certs/cert.pem
Running pre-create checks...
(testing-01) Image cache directory does not exist, creating it at /home/$USER/.docker/machine/cache...
(testing-01) No default Boot2Docker ISO found locally, downloading the latest release...
(testing-01) Latest release for github.com/boot2docker/boot2docker is v1.12.1
(testing-01) Downloading /home/$USER/.docker/machine/cache/boot2docker.iso from https://github.com/boot2docker/boot2docker/releases/download/v1.12.1/boot2docker.iso...
(testing-01) 0%....10%....20%....30%....40%....50%....60%....70%....80%....90%....100%
Creating machine...
(testing-01) Copying /home/$USER/.docker/machine/cache/boot2docker.iso to /home/$USER/.docker/machine/machines/testing-01/boot2docker.iso...
(testing-01) Creating VirtualBox VM...
(testing-01) Creating SSH key...
(testing-01) Starting the VM...
(testing-01) Check network to re-create if needed...
(testing-01) Found a new host-only adapter: "vboxnet0"
(testing-01) Waiting for an IP...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env testing-01

Lo que ha realizado Docker Machine es crear los certificados TLS y luego descargar una imagen .iso del proyecto boot2docker que sera usada como sistema operativo GNU/Linux base para iniciar Docker Engine.

Si nos encontramos con un problema al estilo de:

(testing-01) 0%....10%....20%....30%....40%....50%....60%....70%....80%....90%....100%
Error with pre-create check: "VirtualBox is configured with multiple host-only adapters with the same IP \"192.168.100.1\". Please remove one."

Para solucionar este inconveniente, tendremos que abrir la interfaz gráfica para VirtualBox y seguir la ruta:

VirtualBox => File => Preferences => Network => Host-only networks

Y remover las interfaces de red duplicadas.

Adicional a esto, si queremos que esa máquina virtual o host configurado cuente con un numero determinado de cpu o asignarles un numero determinado de RAM o espacio en disco, ejecutaremos lo siguiente:

$ docker-machine create --driver virtualbox --virtualbox-disk-size "15000" --virtualbox-memory "1024" --virtualbox-cpu-count 2 --virtualbox-hostonly-cidr "192.168.66.1/24" testing-01

Se puede encontrar mas información de los parámetros soportados por Docker Machine para VirtualBox en el siguiente enlace. Para verificar que nuestro host se ha creado correctamente, deberemos ejecutar en la línea de comandos:

$ docker-machine ls
NAME         ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER    ERRORS
testing-01   -        virtualbox   Running   tcp://192.168.99.100:2376           v1.12.1 

Otra manera de verificar que la máquina virtual o host ha sido creado recientemente, ejecutamos:

$ VBoxManage list runningvms
"testing-01" {4428c552-b582-4f43-a3d3-c8167172f53c}

Con Docker Machine contamos con una serie de comandos que nos permiten administrar este nodo o host creado recientemente. Para ellos vamos a explicar algunos.

Si ejecutamos, docker-machine inspect testing-01 nos mostrara información relacionada con el host o nodo creado.

Por otro lado si luego ejecutamos, docker-machine ip testing-01 nos devolverá la IP asignada al host o máquina virtual creada con VirtualBox.

Por otro lado si ejecutamos los parametros stop, start, restart, status podremos ver y administrar los distintos estados de la máquina virtual o host.

Si nos queremos conectar a la máquina virtual o host creado, ejecutaremos: docker-machine ssh testing-01 .

Otra forma de acceder es utilizando nuestro cliente SSH, tan solo deberemos conocer que el usuario es docker y el password por default es tcuser , ejecutamos lo siguiente:

$ ssh -p22 [email protected]$(docker-machine ip testing-01)

Si queremos actualizar el Docker Engine en nuestra máquina virtual o host, ejecutaremos docker-machine upgrade testing-01 .

También si contamos con el cliente de Docker instalado en nuestro computador, es posible conectarse al host o máquina virtual creada y ejecutar cualquier comando de Docker, para ello ejecutamos:

eval $(docker-machine env testing-01)

Luego de lo anterior, ejecutaremos cualquier comando de Docker, ya sea hacer un docker ps -a o bien un docker images .

En algunos casos si se recibe un error de:

Cannot connect to the Docker daemon. Is the docker daemon running on this host?

Ejecutaremos el cliente de Docker de la siguiente forma:

$ docker $(docker-machine config testing-01) ps -a

$ docker $(docker-machine config testing-01) images

Por ultimo si queremos eliminar la máquina virtual o host, ejecutaremos docker-machine rm testing-01 . Pueden ver el resto de los comandos ejecutando docker-machine -h . Adicional a esto se pueden encontrar los archivos de configuración de las máquinas creadas o host en la ruta /home/$USER/.docker/machine .

 

Administrar con Docker Machine una VM remota con Docker Engine ya instalado.

Para este caso se cuenta con un servidor físico o máquina virtual que contiene la ultima versión de Docker Engine funcionando en un CentOS 7 y que se accede utilizando el protocolo SSH a través de una dirección ip publica 54.64.32.22, por lo que si se quiere gestionarla con Docker Machine, usaremos el driver generic que realizara lo siguiente:

  • Si en el host o la máquina virtual no se encuentra instalado la mas reciente versión de Docker Engine, Docker Machine lo instalará y luego lo configurará.
  • Generara los certificados TLS para la comunicación segura entre tu computador y el host o máquina virtual.
  • Docker Machine también reiniciará el daemon para Docker Engine.
  • Docker Machine cambiara el hostname del host o máquina virtual para que coincida con el hostname que le hemos asignado desde Docker Machine.

Primero, en nuestro servidor o máquina virtual remota, deberemos realizar los siguientes cambios, tendremos que agregar un usuario con el cual nos conectaremos por SSH (por favor no usen root) por ejemplo utilizaremos el usuario userdocker y que cuanta con los permisos para ejecutar comandos root y ya se encuentra en el grupo wheel, por ello, realizaremos el siguiente cambio, editaremos el archivo /etc/sudoers y reemplazamos lo siguiente:

%wheel  ALL=(ALL)       NOPASSWD: ALL

Lo que hemos hecho anteriormente permitirá al usuario userdocker ejecutar comandos root sin necesidad de introducir la password.

También es posible conectarnos utilizando Public-Private Key Pair o claves RSA para conectarnos por SSH, primero generaremos una y la agregaremos a nuestro host o máquina virtual:

$ ssh-keygen -t rsa -b 4096

Luego de generarla, la enviaremos al usuario userdocker de nuestro host o máquina virtual remota, ejecutamos:

$ ssh-copy-id -i /home/$USER/.ssh/id_rsa.pub [email protected]

Verificamos que nos podemos conectar con el usuario userdocker: ssh -p22 [email protected] .

Luego de esto, ejecutamos Docker Machine, con los siguientes parámetros:

$ docker-machine create --drive generic --generic-ip-address 54.64.32.22 --generic-ssh-key $HOME/.ssh/id_rsa --generic-ssh-user userdocker --generic-ssh-port 22 testing-02

Es necesario mencionar que Docker Machine solamente funciona con la ultima versión de CentOS y aun se encuentra en modo experimental, es decir, que al momento de escribir este post la versión 7 es la única soportada, se puede encontrar mas información siguiendo este enlace.

Un problema con el que me encontré al usar CentOS 7 fue que al momento de crear el host o nodo, me generaba el siguiente mensaje de error: Error creating machine: Error running provisioning: exit status 6 y si consultaba la información del host o nodo me generaba la siguiente salida:

$ docker-machine ls
NAME         ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER    ERRORS
testing-02   -        generic      Running   tcp://54.64.32.22:2376              Unknown   Unable to query docker version: Unable to read TLS config: open /home/$USER/.docker/machine/machines/testing-01/server.pem: no such file or directory

Lo solucione de la siguiente forma, y que creo que no es la correcta, pero fue como lo solucione; como anteriormente ya teníamos creado un host o nodo, copie los archivos faltantes desde ese nodo o host hacia mi nuevo host o nodo llamado testing-02 por lo que ejecutaremos las siguientes instrucciones:

$ cp -vr ~/.docker/machine/machines/testing-01/server* ~/.docker/machine/machines/testing-02

Realizado lo anterior ya podremos ejecutar los comandos de gestión de Docker Machine, asi como también usar el cliente de Docker con este nuevo host o nodo creado tan solo deberemos ejecutar:

$ eval $(docker-machine env testing-02)

Realizado lo anterior, ya podremos administrar y crear contenedores en nuestro host o nodo llamado testing-02.

 

Administrar con Docker Machine instancias creadas en Amazon Web Services.

Del mismo modo que hemos creado un host o nodo usando VirtualBox, o hemos tomado un host o nodo con Docker Engine ya instalado, podemos hacerlo usando los servicios de Amazon Web Services para ello usaremos el driver llamado amazonec2 y que nos permitirá crear instancias e instalar la ultima versión de Docker Engine en ellas. Debemos tener en cuenta que Docker Machine acepta ciertas versiones de sistemas operativos bases y que pueden ser consultados en el siguiente enlace.

Deberemos contar con una cuenta en AWS asi como también las access key y secret key del usuario que usaremos. Primero crearemos un archivo en la ruta ~/.aws/credentials para no exponer nuestros datos en la línea de comandos, el archivo contendrá lo siguiente:

[default]
aws_access_key_id = ACCESS-KEY
aws_secret_access_key = SECRET-KEY

Como sistema operativo base usaremos Ubuntu en su versión 16.04 LTS de arquitectura x86_64, la ubicación de la instancia estaría en us-east-1, y el tipo de instancia sera una hvm con ebs-ssd de storage, por ello, buscaremos el ID de la AMI que vamos a utilizar en el Ubuntu AMI locator. Posterior, ejecuraremos las siguientes instrucciones:

$ docker-machine create --driver amazonec2 --amazonec2-region us-east-1 \
   --amazonec2-vpc-id vpc-45332712 --amazonec2-subnet-id subnet-9086cdffa9 \
   --amazonec2-zone e --amazonec2-instance-type "t2.micro" --amazonec2-ami ami-4f680658 \
   --amazonec2-ssh-keypath $HOME/.ssh/id_rsa testing-03

Ejecutado lo anterior, se creara la instancia en AWS en la zona us-east-1. Es obligatorio utilizar los parámetros --amazonec2-vpc-id
--amazonec2-subnet-id con sus debido identificadores, por lo que en el Dashboard de AWS deberemos configurar una VPC y extraer estos identificadores que nos proporcionan luego de creadas la VPC y la subnet, asi como también setear con el parámetro --amazonec2-zone la zona donde sera generada la instancia y donde se encuentra creada la subnet, en mi caso es la zona e.

Ejecutado lo anterior , verificamos que se ha creado correctamente la instancia con el nodo o host de nuestro Docker Machine, para verfificar esto ejecutamos docker-machime ls veremos la instancia recién creada:

$ docker-machine ls
NAME                         ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER    ERRORS
testing-03                -        amazonec2    Running   tcp://51.34.131.90:2376             v1.12.1 

Si al estar creando la instancia se les presenta el siguiente mensaje de error:

Error getting ssh command 'exit 0' : Permissions 0700 for '/home/$USER/.docker/machine/machines/testing-03/id_rsa' are too open

Ejecutaremos la siguiente instrucción:

$ chmod 600 /home/$USER/.docker/machine/machines/testing-03/id_rsa

Por ultimo, si el mensaje de error esta relacionado con las llaves .pem, ejecutaremos lo siguiente:

$ cp -vr ~/.docker/machine/machines/testing-01/server* ~/.docker/machine/machines/testing-03

Luego ejecutaremos el parámetro regenerate-certs para recrear los certificados TLS:

$ docker-machine --debug regenerate-certs testing-03

Hasta aca este sencillo post, por lo que si tienes alguna duda, dejala en la caja de comentarios.