Cuando un contenedor es borrado, toda la información contenida en él, desaparece. Para tener almacenamiento persistente en nuestros contenedores, que no se elimine al borrar el contenedor, es necesario utilizar volúmenes de datos (data volume). Un volumen es un directorio o un fichero en el docker engine que se monta directamente en el contenedor. Podemos montar varios volúmenes en un contenedor y en varios contenedores podemos montar un mismo volumen.

Tenemos dos alternativas para gestionar el almacenamiento en docker:

  • Usando volúmenes de datos
  • Usando contenedores de volúmenes de datos

Volúmenes de datos

Los volúmenes de datos tienen las siguientes características:

  • Son utilizados para guardar e intercambiar información de forma independientemente a la vida de un contenedor.
  • Nos permiten guardar e intercambiar información entre contenedores.
  • Cuando borramos el contenedor, no se elimina el volumen asociado.
  • Los volúmenes de datos son directorios del host montados en un directorio del contenedor, aunque también se pueden montar ficheros.
  • En el caso de montar en un directorio ya existente de un contenedor un volumen de datos , su contenido no será eliminado.

Añadiendo volúmenes de datos

Vamos a empezar creando una contenedor al que le vamos a asociar un volumen:

$ docker run -it --name contenedor1 -v /volumen ubuntu:14.04 bash

Como podemos comprobar con la opción -v hemos creado un nuevo volumen que se ha montado en el directorio /volumen del contenedor. Vamos a crear un fichero en ese directorio:

root@d50f89458659:/# cd /volumen/
root@d50f89458659:/volumen# touch fichero.txt
root@d50f89458659:/volumen# exit

Podemos comprobar los puntos de montajes que tiene nuestro contnedor con la siguiente instrucción:

$ docker inspect contenedor1
...
"Mounts": [
            {
                "Name": "c7665edfb4505d6ac85fb0f3db118f6c7bb63958157ec722d6d3ee15ca8f3427",
                "Source": "/mnt/sda1/var/lib/docker/volumes/c7665edfb4505d6ac85fb0f3db118f6c7bb63958157ec722d6d3ee15ca8f3427/_data",
                "Destination": "/volumen",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
...

Continue reading

machine

Docker Machine es una herramienta que nos ayuda a crear, configurar y manejar máquinas (virtuales o físicas) con Docker Engine. Con Docker Machine podemos iniciar, parar o reiniciar los nodos docker, actualizar el cliente o el demonio docker y configurar el cliente docker para acceder a los distintos Docker Engine. El propósito principal del uso de esta herramienta es la de crear máquinas con Docker Engine en sistemas remotos y centralizar su gestión.

Docker Machine utiliza distintos drivers que nos permiten crear y configurar Docker Engine en distintos entornos y proveedores, por ejemplo virtualbox, AWS, VMWare, OpenStack, …

Las tareas fundamentales que realiza Docker Machine, son las siguientes:

  • Crea una máquina en el entorno que hayamos indicado (virtualbox, openstack,…) donde va a instalar y configurar Docker Engine.
  • Genera los certificados TLS para la comunicación segura.

También podemos utilizar un driver genérico (generic) que nos permite manejar máquinas que ya están creadas (físicas o virtuales) y configurarlas por SSH.

Instalación de Docker Machine

Para instalar la última versión (0.7.0) de esta herramienta ejecutamos:

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

Y comprobamos la instalación:

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

Continue reading

Al igual que en la entrada anterior, sobre copias de seguridad de volúmenes en OpenStack, en esta entrada vamos a mostrar otra funcionalidad que nos ofrece OpenStack cuando trabajamos con volúmenes con su componente Cinder.

Transferencia de volúmenes

Esta operación nos permite transferir un volumen de un proyecto a otro.

Crear una transferencia

Vamos a trabajar con el usuario demo, que tiene creado un volumen.

$ source demo-openrc.sh	

$ cinder list
+--------------------------------------+-------------------+--------+------+-------------+----------+-------------+
|                  ID                  |       Status      |  Name  | Size | Volume Type | Bootable | Attached to |
+--------------------------------------+-------------------+--------+------+-------------+----------+-------------+
| 917ef4cc-784d-4803-a19a-984b847b9f1e | awaiting-transfer | disco1 |  1   | lvmdriver-1 |  false   |             |
+--------------------------------------+-------------------+--------+------+-------------+----------+-------------+

Vamos a crear una transferencia, con las siguientes instrucciones:

$ cinder transfer-create 917ef4cc-784d-4803-a19a-984b847b9f1e
+------------+--------------------------------------+
|  Property  |                Value                 |
+------------+--------------------------------------+
|  auth_key  |           408af7d4a1441587           |
| created_at |      2016-01-08T17:07:03.412265      |
|     id     | d24d5659-40e9-446c-9437-238fc8868571 |
|    name    |                 None                 |
| volume_id  | 917ef4cc-784d-4803-a19a-984b847b9f1e |
+------------+--------------------------------------+

$ cinder transfer-list
+--------------------------------------+--------------------------------------+------+
|                  ID                  |              Volume ID               | Name |
+--------------------------------------+--------------------------------------+------+
| d24d5659-40e9-446c-9437-238fc8868571 | 917ef4cc-784d-4803-a19a-984b847b9f1e | None |
+--------------------------------------+--------------------------------------+------+

Continue reading

En esta entrada voy a explicar una característica muy específica que nos proporciona el componente Cinder de OpenStack, que es el encargado de gestionar el almacenamiento persistente con el concepto de volumen. La característica a la que me refiero es la posibilidad de hacer copias de seguridad del contenido de nuestro volúmenes. El estudio de esta opción la hemos llevado a cabo durante la realización del último curso sobre OpenStack que he impartido con Alberto Molina. Además si buscas información de este tema, hay muy poco en español, así que puede ser de utilidad.

El cliente cinder proporciona las herramientas necesarias para crear una copia de seguridad de un volumen. Las copias de seguridad se guardar como objetos en el contenedor de objetos swift. Por defecto se utiliza swift como almacén de copias de seguridad, aunque se puede configurar otros backend para realizar las copias de seguridad, por ejemplo una carpeta compartida por NFS.

Configurando devstack de forma adecuada

Podemos configurar nuestra instalación de OpenStack con devstack para habilitar la característica de copia de seguridad de volúmenes. En artículo anteriores he hecho una introducción al uso de devstack para realizar una instalación de OpenStack en un entorno de pruebas: Instalar Open Stack Juno con devstack.

Al crear nuestro fichero local.conf, tenemos que tener en cuenta dos cosas:

  • Habilitar el componente de swift (almacenamiento de objetos) donde vamos a realizar las copias de seguridad.
 enable_service s-proxy s-object s-container s-account
 SWIFT_REPLICAS=1
 SWIFT_HASH=password
  • Habilitar la característica de copia de seguridad de los volúmenes.
enable_service c-bak

Continue reading

wordpress-mysql-db-merge-180x180

En los artículos anteriores hemos estudiado como trabajar con imágenes y contenedores docker. En todos los ejemplos que hemos mostrado, los contenedores han trabajado ofreciendo uno o varios servicios, pero no se han comunicado o enlazado con ningún otro. En realidad sería muy deseable trabajar con el paradigma de “microservicio” donde cada contenedor ofrezca un servicio que funcione de forma autónoma y aislada del resto, pero que tenga cierta relación con otro contenedor (que ofrezca también un sólo servicio) para que entre todos ofrezcan una infraestructura más o menos compleja. En esta entrada vamos a mostrar un ejemplo de como podemos aislar servicios en distintos contenedores y enlazarlos para que trabajen de forma conjunta.

Instalación de wordpress en docker

Más concretamente vamos a crear un contenedor con un servidor web con wordpress instalado que lo vamos a enlazar con otro contenedor con un servidor de base de datos mysql. Para realizar el ejemplo vamos a utilizar las imágenes oficiales de wordpress y mysql que encontramos en docker hub.

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
wordpress           latest              55f2580b9cc9        5 days ago          516.5 MB
mysql               latest              e13b20a4f248        5 days ago          361.2 MB
debian              latest              256adf7015ca        5 days ago          125.1 MB
ubuntu              14.04               14b59d36bae0        5 days ago          187.9 MB

Docker nos permite un mecanismo de enlace entre contenedores, posibilitando enviar información de forma segura entre ellos y pudiendo compartir información entre ellos, por ejemplo las variables de entorno. Para establecer la asociación entre contenedores es necesario usar el nombre con el que creamos el contenedor, el nombre sirve como punto de referencia para enlazarlo con otros contenedores.

Por lo tanto, lo primero que vamos a hacer es crear un contenedor desde la imagen mysql con el nombre servidor_mysql, siguiendo las instrucción del repositorio de docker hub:

$ docker run --name servidor_mysql -e MYSQL_ROOT_PASSWORD=asdasd -d mysql

En este caso sólo hemos indicado la variable de entrono MYSQL_ROOT_PASSWORD, que es obligatoria, indicando la contraseña del usuario root. Si seguimos las instrucciones del repositorio de docker hub podemos observar que podríamos haber creado más variables, por ejemplo:  MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD.

A continuación vamos a crear un nuevo contenedor, con el nombre servidor_wp, con el servidor web a partir de la imagen wordpress, enlazado con el contenedor anterior.

$ docker run --name servidor_wp -p 80:80 --link servidor_mysql:mysql -d wordpress

Para realizar la asociación entre contenedores hemos utilizado el parámetro --link, donde se indica el nombre del contenedor enlazado y un alias por el que nos podemos referir a él. Continue reading

dockerhub

En artículos anteriores hemos estudiado la generación de imágenes docker utilizando ficheros Dockerfile y construyendo la nueva imagen con el comando docker buid. Las imágenes generadas por este método se crean en nuestro servidor docker. si queremos desplegar la aplicación o el servicio “dockerizado” desde nuestro entorno de prueba/desarrollo a nuestro entorno de producción, es necesario llevarnos la imagen de un entono a otro. Para transferir la imagen de un equipo a otro tenemos dos posibilidades:

  • Podríamos guardar la imagen en un fichero tar, que podemos copiar al otro equipo para restaurarlo en él.
  • Podríamos guardar la imagen en un registro docker. Podemos instalar un registro en nuestra infraestructura o utilizar docker hub, que es una aplicación web que nos proporciona la posibilidad de guardar nuestras imágenes. Una vez que la imagen esta guardada en el registro podemos descargarla desde el entorno de producción.

Para ver las distintas opciones que tenemos a nuestra disposición vamos a partir de la siguiente imagen que hemos creado:

docker images 
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
josedom24/apache2   latest              04800781aed6        17 seconds ago      183.7 MB

Continue reading