Este enfoque para conectar contenedores se basa en una
abstracción que Docker llamada link (enlaces). Éste era el método preferido
para conectar los contenedores antes de Docker 1.9 y sólo se recomienda si
estamos utilizando una versión anterior de Docker. La vinculación de un
contenedor a otro es un proceso simple que implica nombres de contenedor. Vamos
a comenzar por crear un contenedor.
$ docker run
-d --name mysql2 -e MYSQL_ROOT_PASSWORD=miclave123 mysql
Podíamos haber utilizado el contenedor creado anteriormente
o si usamos el mismo nombre, debemos recordar que el nombre de contenedor debe
ser único y si queremos crearlo con el mismo nombre, debemos borrarlo primero
con el comando “docker rm”.
Hemos ejecutado una instancia de un nuevo contenedor mysql.
Lo hemos nombrado mysql2 utilizando el parámetro –name. También podemos
observar que no hemos publicado ningún puerto en el contenedor, vamos a ver
enseguida el por qué.
Vamos a ejecutar un
contenedor con wordpress en él y enlazamos nuestro nuevo contenedor mysql2.
$
docker run --name wordpress1 -p 8081:80 --link mysql2:mysql -ti wordpress
/bin/bash
root@ba2cf804e098:/var/www/html#
Este comando hace muchas cosas, estamos publicando el puerto
8081 utilizando el parámetro –p para que podemos acceder a nuestra aplicación
web. Hemos utilizado un nuevo parámetro denominado –link. El parámetro –link
crea un vínculo cliente-servicio entre dos contenedores. El parámetro tiene dos
argumentos: el nombre del contenedor de enlace y un alias para el enlace. En
este caso, estamos creando una relación con el cliente, nuestro contenedor
wordpress1 es el cliente, con el contenedor mysql2, que es el “servicio”. También
hemos añadido un alias para ese “servicio” de mysql. El alias nos permite
acceder a la información expuesta constantemente sin necesidad de preocuparse
por el nombre del contenedor subyacente. El enlace le da al contenedor de
servicios la capacidad de comunicarse con el contenedor cliente y comparte
algunos detalles de la conexión con ella, para ayudarle a configurar las
aplicaciones para hacer uso de la conexión. También recibimos un beneficio
relacionado con la seguridad de esta vinculación. Cuando lanzamos nuestro
contenedor mysql2 no publicamos el puerto de mysql con el parámetro –p. No lo
necesitamos, al vincular los contenedores juntos, estamos permitiendo que el
contenedor de cliente pueda comunicarse con cualquier puerto publicado sobre el
contenedor de servicios. Pero aún mejor, sólo los contenedores vinculados
explícitamente a este contenedor que utilicen el parámetro –link pueden
conectarse a este puerto. Teniendo en cuenta que el puerto no se publica en el
host local, ahora tenemos un modelo de seguridad muy fuerte para limitar la
superficie de ataque y la exposición a la red de una aplicación en
contenedores.
Si nosotros lo deseamos por razones de seguridad, por
ejemplo, podemos forzar a Docker para permitir sólo la comunicación entre los
contenedores si existe un enlace. Para ello, se puede iniciar el demonio Docker
con el parámetro --icc=false. Esto desactiva las comunicaciones entre todos los
contenedores, a menos que exista una relación. Podríamos enlazar varios
contenedores juntos. Por ejemplo, si se quiere utilizar nuestra instancia
mysql2 para múltiples aplicaciones web, podríamos vincular cada contenedor de
aplicaciones web para el mismo contenedor mysql.
También podemos especificar el parámetro --link varias veces
para enlazar a varios contenedores. Docker no puede vincular entre contenedores
en hosts Docker separados. Para la creación de redes multi-host, debemos
utilizar las redes Docker o Docker Networking.
Por último, en lugar de ejecutar el contenedor como un
demonio, hemos lanzado una sesión interactiva. Hemos hecho esto para poder ver
como nuestros contenedores están vinculados. Los vínculos de Docker pueblan
información sobre el contenedor de servicios en dos lugares:
·
En el archivo /etc/hosts
·
En las variables de entorno que contienen
información de conexión.
Vamos a ver el archivo host:
root@ba2cf804e098:/var/www/html#
cat /etc/hosts
172.17.0.4 ba2cf804e098
127.0.0.1 localhost
. . .
172.17.0.2 mysql
7b8bff74363c mysql2
Podemos ver que tenemos algunas entradas útiles aquí. La
primera de ellas, es la dirección de nuestra propia IP de contenedor y el
nombre de host (en este caso el ID corto de contenedor). La segunda entrada que
ha sido generada por el parámetro --link, es la dirección IP, el nombre y la
identificación del contenedor mysql, con el nombre de host adicional
especificado como alias en el enlace. Vamos a tratar de hacer ping a ese
contenedor ahora.
root@ba2cf804e098:/var/www/html#
ping mysql
PING
mysql (172.17.0.2): 56 data bytes
64
bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.119 ms
64
bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.147 ms
64
bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.147 ms
. . .
El nombre de host de contenedor no tiene por que ser el ID
corto, podríamos utilizar el parámetro –h o --hostname con el comando docker
run para especificar un nombre de host especifico para el contenedor.
También podemos agregar entradas adicionales al fichero /etc/hosts
cuando ejecutamos un contenedor utilizando el parámetro --add-host. Por ejemplo,
podríamos querer añadir el nombre de host y la dirección IP del host que
ejecuta Docker en nuestro contenedor.
$ docker
run -p 80 --add-host=docker:10.0.0.1 --name web2 --link mysql:mysql2 …
Esto añadiría una entrada para un host llamado docker con
una dirección IP 10.0.0.1 dentro del fichero /etc/hosts de nuestro contenedor.
Las direcciones IP de los contenedores cambian cuando se
reinicia un contenedor, pero docker actualizará el fichero /etc/hosts del
contenedor vinculado con la nueva IP.
Ahora ya tenemos conectividad con nuestro servidor mysql2,
pero antes de usarlos vamos a ver más información de conexión contenida en
nuestras variables de entorno. Vamos a ejecutar el comando env para ver las
variables de entorno.
root@ba2cf804e098:/var/www/html# env
HOSTNAME=ba2cf804e098
MYSQL_ENV_MYSQL_ROOT_PASSWORD=miclave123
TERM=xterm
PHP_INI_DIR=/usr/local/etc/php
PHP_FILENAME=php-5.6.16.tar.xz
MYSQL_PORT_3306_TCP_PORT=3306
MYSQL_PORT_3306_TCP=tcp://172.17.0.2:3306
WORDPRESS_VERSION=4.4
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
GPG_KEYS=0BD78B5F97500D450838F95DFE857D9A90D90EC1
6E4F6AB321FDC07F2C332E3AC2BF0BC433CFC8B3
PWD=/var/www/html
MYSQL_ENV_MYSQL_VERSION=5.7.10-1debian8
HOME=/root
SHLVL=1
PHP_SHA256=8ef43271d9bd8cc8f8d407d3ba569de9fa14a28985ae97c76085bb50d597de98
WORDPRESS_SHA1=d647a77c63f2ba06578f7747bd4ac295e032f57a
MYSQL_PORT_3306_TCP_PROTO=tcp
MYSQL_NAME=/wordpress1/mysql
MYSQL_PORT_3306_TCP_ADDR=172.17.0.2
PHP_EXTRA_BUILD_DEPS=apache2-dev
MYSQL_ENV_MYSQL_MAJOR=5.7
MYSQL_PORT=tcp://172.17.0.2:3306
PHP_VERSION=5.6.16
PHP_EXTRA_CONFIGURE_ARGS=--with-apxs2
_=/usr/bin/env
Podemos ver un montón de variables de entorno aquí, entre
ellas algunas con el prefijo MYSQL. Docker crea automáticamente estas variables
cuando vinculamos los contenedores wordpress y mysql. Comienzan con MYSQL, ya
que es el alias que usamos cuando creamos nuestro enlace.
Las variables de entorno creadas automáticamente incluyen
una variedad de información:
• El nombre de host del contenedor.
• El protocolo, IP y puerto del servicio que se ejecuta en
el contenedor.
• Los protocolos específicos, IP, y los puertos de varios
servicios que se ejecutan en el contenedor.
• Los valores de las variables de entorno especificadas al
iniciar el contenedor.
Las variables precisas variarán de un contenedor a otro,
dependiendo de lo que esté configurado en ese contenedor (por ejemplo, lo que
se ha definido por la instrucción ENV y EXPOSE en el fichero Dockerfile del
contenedor). Incluyen información que podemos usar dentro de nuestras
aplicaciones para vincular consistentemente entre los contenedores.
Nuestra aplicación entonces tiene dos formas de conectar
wordpress a mysql:
·
El uso de parte de la información de conexión en
nuestras variables de entorno.
·
El uso de DNS y la información del fichero
/etc/hosts
Veamos el primer método, nuestra aplicación podría leer de
las variables de entorno MYSQL_PORT y podría usar la salida de host y puerto
resultante para configurar la conexión mysql. Nuestra aplicación puede ahora
utilizar esta información de conexión para encontrar mysql en un contenedor
vinculado. Éste abstrae la necesidad de codificar una dirección IP y el puerto
para proporcionar conectividad.
Alternativamente, existe el DNS local que es más flexible,
que es la solución más habitual.
También podríamos configurar los servidores DNS para
nuestros contenedores, utilizando el parámetro -dns y --dns-search en el
comando docker run. Esto nos permite establecer la ruta de resolución de DNS y
dominios de búsqueda locales. Si no se especifica, Docker utilizará la
resolución de DNS que tenga configurada el anfitrión Docker.
No hay comentarios:
Publicar un comentario