Mostrando entradas con la etiqueta docker run. Mostrar todas las entradas
Mostrando entradas con la etiqueta docker run. Mostrar todas las entradas

miércoles, 27 de julio de 2016

CREANDO UNA APLICACIÓN MULTICONTENEDOR CON DOCKER COMPOSE

Para utilizar Docker compose, creamos un directorio y creamos un fichero con el nombre docker-compose.yml que es donde introducimos la receta de lo que debe realizar.

$ mkdir composewp
$ cd composewp/
composewp $ nano docker-compose.yml

En nuestro caso nuestro fichero quedaría de esta forma:

wp:
  image: wordpress
  links:
    - mysql:mysql
  ports:
    - "80"
mysql:
  image: mysql
  environment:
    - MYSQL_ROOT_PASSWORD=miclaverootmysql

La receta es muy sencilla, su funcionamiento sería similar al ejemplo del apartado anterior, estamos creando un contenedor en base a la imagen de wordpress donde le especificamos que esté vinculado al contenedor mysql que definimos más adelante, podemos comprobar que no exponemos ningún puerto del contenedor mysql y definimos la variable de entorno que corresponde a la contraseña del usuario root del servicio mysql. Vamos a ver si todo esto funciona. Primero simplemente vamos a ejecutar la composición mediante el parámetro up y el parámetro -d que significa que se debe ejecutar como servicio.

$ docker-compose up -d
Creating composewp_mysql_1
Creating composewp_wp_1

Vemos que ha creado dos contenedores correctamente, ahora mediante el parámetro ps vamos a ver si están en ejecución.

$ docker-compose ps
      Name                     Command               State           Ports        
----------------------------------------------------------------------------------
composewp_mysql_1   /entrypoint.sh mysqld            Up      3306/tcp             
composewp_wp_1      /entrypoint.sh apache2-for ...   Up      0.0.0.0:32768->80/tcp

Como podemos comprobar, ha iniciado correctamente los dos contenedores, no obstante vamos a ver que nos dice el demonio docker mediante el comando docker ps.

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
77061ae8c289        wordpress           "/entrypoint.sh apach"   18 seconds ago      Up 16 seconds       0.0.0.0:32768->80/tcp   composewp_wp_1
c22cd4fa76d8        mysql               "/entrypoint.sh mysql"   18 seconds ago      Up 17 seconds       3306/tcp                composewp_mysql_1

Según esto, todo parece funcionar correctamente, aún así nos vamos a ir a nuestro navegador a comprobar si realmente se ha iniciado. Como me indica que se ha expuesto el puerto 80 de wordpress al puerto 32768 del anfitrión, ése será el puerto que debo comprobar. Y como podemos ver en la figura, todo funciona perfectamente.


Fuente: Elaboración propia

Ahora vamos a realizar otra prueba con docker compose, vamos a intentar manejar 3 servidores wordpress vinculados al mismo servidor mysql, lo cual resulta francamente sencillo con docker compose, mediante el parámetro scale, le especificamos cual de los contenedores queremos escalar y en qué cantidad.

$ docker-compose scale wp=3
Creating and starting 2 ... done
Creating and starting 3 ... done

En nuestro ejemplo le hemos dicho que queremos 3 contenedores funcionando de wordpress y como ya teníamos uno en ejecución, nos ha ejecutado 2 más, ahora vamos a comprobar que todo funciona perfectamente mediante el parámetro ps.

$ docker-compose ps
      Name                     Command               State           Ports        
----------------------------------------------------------------------------------
composewp_mysql_1   /entrypoint.sh mysqld            Up      3306/tcp             
composewp_wp_1      /entrypoint.sh apache2-for ...   Up      0.0.0.0:32768->80/tcp
composewp_wp_2      /entrypoint.sh apache2-for ...   Up      0.0.0.0:32769->80/tcp
composewp_wp_3      /entrypoint.sh apache2-for ...   Up      0.0.0.0:32770->80/tcp


Y podemos ver como tenemos funcionando los 3 contenedores en 3 puertos distintos.

martes, 26 de julio de 2016

CONECTANDO CONTENEDORES DOCKER A TRAVÉS DE ENLACES

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.

viernes, 10 de junio de 2016

RESUMEN DE COMANDOS DOCKER


Resumen de comandos Docker.


Actividad
Comando
Ejemplo
Contenedores


Arrancar o comenzar contenedor
docker start <id o nombre>
docker start micontenedor
Reiniciar contenedor
docker restart <id o nombre>
docker restart micontenedor
Parar contenedor
docker stop <id o nombre>
docker stop micontenedor
Eliminar contenedor
docker rm <id o nombre>
docker rm micontenedor
Crear y ejecutar contenedor interactivo
docker run –i –t <image> /bin/bash
docker run –i –t Ubuntu /bin/bash
Crear y ejecutar contenedor como servicio o demonio
docker run –d <image> <cmd>
docker run –d Ubuntu ping docker.com
Listar todos los contenedores en ejecución
docker ps

Listar todos los contenedores
docker ps –a

Abrir una ventana de comandos o Shell en un contenedor en ejecución
docker exec –i –t <id o nombre> bash
docker exec –i –t micontenedor bash
Mostrar detalles de un contenedor
docker inspect <id o nombre>
docker inspect micontenedor
Mostrar eventos de un contenedor
docker events <id o nombre>
docker events postgres
Mostrar los puertos a exponer de un contenedor
docker port <id o nombre>
docker port postgres
Mostrar ficheros modificados
docker diff <id o nombre>
docker diff micontenedor
Mostrar los procesos de un contenedor
docker top <id o nombre>
docker top micontenedor
Mostrar registro de eventos o log de un contenedor
docker logs <id o nombre>
docker logs micontenedor
Ver el registro de eventos interactivo (tipo tail –f)
docker logs –f <id o nombre>
docker logs –f micontenedor
Copiar ficheros de un contenedor
docker cp ‘<id>’:<origen> <destino>
docker cp micontenedor:/etc/hosts /tmp/hosts
Exportar contenedor
docker export <id o nombre>
docker export micontenedor >micontenedor.tar
Guardar cambios de contenedor como imagen nueva
docker commit <id o nombre> <nombre de imagen>
docker commit micontenedor jalapuente/imagen2
Imágenes


Listar todas las imágenes locales
docker images

Obtener una imagen del repositorio oficial
docker pull <nombre>
docker pull ubuntu
Obtener una imagen no oficial
docker pull <espacio de nombres>/<nombre>
docker pull jalapuente/mysql
Subir una imagen a un repositorio oficial (Docker Hub)
docker push <espacio de nombres>/<nombre>
docker pull jalapuente/mysql
Crear una imagen de un fichero Dockerfile
docker build <path>
docker build .
Borrar una imagen
docker rmi <nombre>
docker rmi Ubuntu
Mostrar historial de una imagen
docker history <nombre>
docker history Ubuntu
Mostrar detalles de una imagen
docker inspect <nombre>
docker inspect postgres
Nombrar una imagen y establecer versión de una imagen
docker tag <id> <espacio de nombres>/<nombre>:<version>
docker tag 65f515144e5f jalapuente/mysql:version1
Buscar una imagen
docker search <consulta>
docker search django
Fuente: Elaboración propia.


jueves, 9 de junio de 2016

FUNCIONAMIENTO DE NUESTRO PROPIO REGISTRO DOCKER

Tener un registro público de las imágenes Docker es de gran utilidad. A veces, sin embargo, vamos a querer construir y almacenar las imágenes que contienen información o datos que no queremos hacer públicos. 

Hay dos opciones en esta situación:
• Hacer uso de repositorios privados sobre  Docker Hub.
• Ejecutar nuestro propio registro detrás del cortafuegos o firewall.

El equipo de Docker, Inc., tiene el código fuente que utilizan para ejecutar un registro Docker de código abierto, lo que nos permite construir nuestro propio registro interno. El registro no tiene actualmente una interfaz de usuario y sólo está disponible como un servicio API.

Crear un registro desde un contenedor

Crear un registro en un contenedor Docker es muy simple. Simplemente hay que ejecutar el contenedor provisto por Docker, así:

$ docker run -p 5000:5000 registry:2

Esto ejecutará un contenedor que utiliza la versión 2.0 de la aplicación de registro y comunica por el puerto 5000 de la máquina local.

Probando el nuevo registro

Vamos a probar el nuevo registro y ver como podemos hacer uso del mismo. Vamos a intentar subir una de nuestras imágenes “jalapuente/apache2” a nuestro nuevo registro. En primer lugar, vamos a identificar el ID de la imagen utilizando el comando “docker images”.

$ docker images jalapuente/apache2
REPOSITORY           TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
jalapuente/apache2   latest              1316d227367f        2 weeks ago         223.7 MB

Después apuntamos nuestro ID de imagen, 1316d227367f, será la etiqueta del nuevo registro. Para especificar el nuevo destino del registro, hay que prefijar el nombre de la imagen con el nombre de host y el puerto de nuestro nuevo registro. En nuestro caso, nuestro nuevo registro tiene un nombre de host de midocker.

$ docker tag 1316d227367f midocker:5000/jalapuente/apache2

Después de etiquetar nuestra imagen, podemos enviarla al nuevo registro con el comando docker push :

$ docker push midocker:5000/jalapuente/apache2 .

La imagen se publica entonces en nuestro registro local y estará disponible para poder construir nuevos contenedores, utilizando el comando “docker run”.

$ docker run –t –i midocker:5000/jalapuente/apache2 /bin/bash


Ésta es la implementación más simple del Registro de Docker detrás de un cortafuegos.