PROYECTO DE CONTENERIZACION CON DOCKER DE LA
APLICACION APACHE-PHP-MYSQL TOO v0.1
El proyecto consiste en contenerizar con Docker una aplicación extensa (Too v0.1) desarrollada
por Jose de Frías en PHP y Mysql sobre Apache.
1. - En una primera fase crearemos la aplicación y la probaremos sobre una plataforma php-
apache.
2. - Crearemos una imagen/Dockerfile que contenga Apache, PHP, la librería Smarty , otras
librerias y el código fuente de la aplicación.
3. - Crearemos una imagen/Dockerfile con mysql y un volumen asignado con los datos.
4. - Crearemos el archivo docker-compose para iniciar los contenedores y probaremos que
funciona correctamente la aplicación.
5 .- Red Bridge creada automáticamente por docker-compose.
6.- Seguidamente estableceremos una pipeline de integración continua basada en Github y
CircleCI.
7.- Subiremos el proyecto a producción.
8.- Montaremos un Custer de Docker Swarm y correremos la pliacación en dicho cluster.
1 CREAR APLICACION
1 CREAMOS LA APLICACION EN UN ENTORNO DE DESARROLLO
CON PHP 7, APACHE 2, MYSQL, Y LIBRERIAS: SMARTY,
PHPEXCEL, PHP_MAILER, ETC
Sobre Apache con PHP7, Mysql y las librerias: Smarty, Phpmailer, Phpexcel, Dompdf, y redist
para pasarelas de pago.
Aplicación de gestión para mayoristas de viaje: TOOBACK (togethere BackOffice)
La probamos sobre una base de datos Mysql en un Cloud (AWS) datos de prueba.
La dejamos configurada y funcionando.
2 CREANDO IMAGEN APACHE – PHP
1 Usamos la imagen php:7.2-apache de docker hub para crear un
contenedor
Cargamos la imagen de docker hub php:7,2-apache
Esta imagen tiene apache y php instalados sobre ubuntu.
Usamos el Dockerfile que viene con la imagen cuyo contenido es el siguiente:
FROM josedefrias/php-apache:v0.5
# Para instalar extensiones ej: docker-php-ext-install mysqli
# Para ver que extensiones tenemos php -m
# Carpeta de extensiones /usr/src/php/ext/
COPY src/ /var/www/html/
Creamos las carpetas que usaremos para guardar todos los ficheros necesarios.
Es muy importante crear estas carpetas con el usuario con el que vayamos a
trabajar o nos dará problemas de permisos posteriormente.
$ mkdir php-apache
$ mkdir php-apache/src
copiamos la aplicación en src
generamos la imagen josedefrias/php-apache:v0.1 usando el fichero Dockerfile
$ docker build -t josedefrias/php-apache:v0.1 .
Llegamos a la parte de armar nuestro contenedor y ponerlo en funcionamiento. Correrá en modo
interactivo con lo que podremos ver los logs y compartirá el puerto WEB/HTTP(80). Usaremos
nuestra imágen recién creada.
Iniciamos el contenedor
$ docker run it –name phpapache -p 80:80 josedefrias/php-apache:v0.1
Podemos entrar a trabajar dentro del contenedor con:
Ya tenemos el contenedor iniciado pero la aplicación aun no funcionará ya que debemos copiar
las librerias al directorio var/www/ dentro del contenedor y configurar los ficheros php.ini,
httpd.conf y sendmail.ini:
usr/local/etc/php/php.ini
usr/local/etc/httpd.conf
var/www sendmail/senmail.ini (cuando hayamos copiado esta librería)
el proyecto esta cargado en var/www/html/
Tenre siempre estos ficheros de otro proyecto para ver los cmabios que hay que hacer en cdaa
fichero.
En php.ini muy importante paths an directories y habilitar las extendiones.
Notas a tener en cuenta durante la configuración de php y apache
Permisos de escritura en la carpeta de trabajo: Al crear el directorio dentro del proyecto donde
vamos a ir modificando nuestro código en nuestra máquina (por ejemplo www o apdd) hay que
entrar y dar permisos de lectura y escritura a esa carpeta y todas las que tenga dentro y tdos los
ficheros.
Esto es para que cuando se cree la imagen con el Dockerfile, en el nuevo contenedor, el usuario
pueda escribir en ellos. Muy importante por ejemplo para smarty.
Puede ser necesario instalar extensiones en php:
Dependiendo de la imagen de php: Si es la oficial vienen con unos comandos de docker para
instalarlas.
Docker-php-ext-install mysqli
las extendiones estan en usrsrc/php/ext/
con php -m podemos ver las que enemos instaladas
Creamos la imagen v1.0 con la que iniciaremos el trabajo de
desarrollo e integración continua posteriormente
Usando docker commit y cuando hayamos terminado de configurar el contenedor inicial
crearemos ya la primera imagen de trabajo.
Esta la imagen la usaremos para todos los procesos posteriores.
docker commit php-apache josedefrias/php-apache:v0.1
Inicialmente usamos una conexión a una base de datos en la nube de AWS pero crearemos una
una imagen de mysql con la base de datos y un volumen con los datos para completar los
procesos de aprendizaje de docker. De momento y para que funcione le damos la conexión a una
base de tados que tengamos disponible en la nube.
Es importante que nos aseguramos que podemos iniciar la imagen sin -it y con -d para que
dockercompose pueda iniciarla posteriormente. docker run d--name phpmysql -p 80:80
josedefrias/php-apache:v0.1 (por esto tuve que cambiar de un proyecto con xampp a empezar
de nuevo con php y apache).
3 CREANDO IMAGEN PARA MYSQL
Usamos la imagen mysql:latest y un volumen asignado con los
datos
Descargamos y creamos la imagen de mysql
docker run -d --name mysql-too -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d
mysql:latest
En php7 los cientes de MySQL no tan modernos, más antiguos que la versión de MySQL no
pueden usar el plugin de autenticación activo. Como es algo bastante común, MySQL ya deja la
siguiente información comentada en el archivo de configuración /etc/mysql/my.cnf:
[mysqld]
[...]
# Remove leading # to revert to previous value for default_authentication_plugin,
# this will increase compatibility with older clients. For background, see:
# https://dev.mysql.com/doc/refman/8.0/en/server-system-
variables.html#sysvar_default_authentication_plugin
#default-authentication-plugin=mysql_native_password
Hay que habilitarla entrando en el contenedor
Docker exec -it mysql-too bash
entrando el el fichero my.cfd y descomentandola (o añadiendola si no esta)
Tras reiniciar MySQL, el funcionamiento debería ser correcto. Eso sí, tened en cuenta que si los
usuarios los habéis creado antes de cambiar el plugin de autenticación, probablemente
siga fallando, simplemente volved a regenerar los usuarios.
Ahora creamos nuestra imagen propia de mysql
docker commit mysql-too josedefrias/mysql-too:v0.1
despues reiniciar el contenedor.
Creamos un volumen para la base de datos mysql-too
Debemos crear un volumen y asignarselo a la imagen antes de acceder a la base de datos
para crear nuestros usuarios y cargar la base de datos del proyecto.
Para crear nuestro volumen usaremos la el comando
# docker volume create mysql_too
con docker volumen inspect vemos la información del volumen. Ubicacion, etc
Despues iniciamos el contenedor especificando este volumen
docker run -d -it --name mysql-too -p 3306:3306 -v mysql_too:/var/lib/mysql
josedefrias/mysql_too:v0.1
Y accedemos a la base de datos con un gestor, preferiblemente heifdie puede acceder:
Desde el propio host: host:localhost user:root pass:root puerto: 3306
Desde fuera: ip del servidor: 192,168,1,106 user:root pass:root puerto: 3306
Ahora es el momento de crear nuestro usuario too (con los privilegios necesarios) y de crear la
base de datos too e importarla de alguna copia nuestra.
Yo hice esto en accediendo con heidi desde otro equipo, ya que no encontre heidi para linux e
importe la base de datos limpia para toogethere. Esto es muy importante para que no hay
aarchivos grandes o nos fallara la subida al repositorio de GitHub.
Una vez tengamos la base de datos configurada y con los usuarios, privilegios y el esquema que
necesitemos creamos la imagen definitiva.
docker commit mysql-too josedefrias/mysql-too:v0.2
4 CREANDO DOCKER-COMPOSE PARA EL PROYECTO
Creamos el archivo docker-compose.yml para iniciar los dos
contenedores en la misma red
Creamos el archivo de tipo yaml docker-compose.yml con el siguiente código
version: "3.0"
services:
php-apache:
build: .
ports:
- "80:80"
depends_on:
- mysql-too
mysql-too:
image: josedefrias/mysql-too:v1.0
ports:
- "3306:3306"
volumes:
- mysql_too:/var/lib/mysql
Notas importantes:
1 - No es necesario indicar el puerto en el servicio mysql ya que docker creara una red con ambos
servicios conectados. Yo lo hago para poder acceder con heidi desde fuera a la base de datos.
En produccion nunca se debe hacer ya que estaremos exponiendo la base de datos. Una ventaja
de docker compose es que aisla del exterior los servicios que queramos incrementando así la
seguridad con redes propias que crea en el momento de inicar los contenedores.
2 - En la etiqueta volumenes podemos indicar la ruta y el nombre donde se creo el volumen
mysql-too utilizando así el volumen donde esta y sin tocar nada:
- mysql_too:/var/lib/mysql
O bien podemos indicar una ruta para que docker cree un nuevo volumen con los datos dentro de
nuestra carpeta de proyecto d ella siguiente manera:
- ./mysql_too:/var/lib/mysql
Si hacemos esto último habra que volver a cargar los usuarios y esquemas y además dar
permisos de escritura a la nueva carpeta que se creará y todo su contenido.
Despues ejecutamos la orden docker-compose up -d crear e iniciar los contenedores con las
dependencias entre ellos dentro de la red, los puertos indicados
docker-compose up -d
Se iniciaran ambos contenedores y nuesttra aplicación debe funcionar. Podemos acceder desde
el navegador con : localhost/
Nota importante: Si hacemos cambios en las imagenes que usamos en el docker-compose
habra que reconstruirlas con el comando docker-compose build
Si da error de permisos los solucionamos dando permisos sobre la carpeta o fichero que
nos indicque el mensaje de error en la consola
sudo chown -R oracle /home/oracle/php-apache/mysql_too/
sudo chown -R oracle /home/oracle/php-apache/mysql_too/auto.cnf
Lógicamente si estamos trabajando con el usuario root esto no pasa.
5 RED BRIDGE CREADA POR DOCKER
DOCKER NETWORK POR DEFECTO
Red Bridge es el tipo de red predeterminados.
Todos los contenedores en una red Bridge estan conectados entre si y se pueden conectar a
internet a traves de la red Bridge.
Con docker network ls veremos las redes de nuestro host local
docker network ls
Veremos que hay creada una red de docker llamada bridge creda por docker al iniciar el ic.
Con docker network inspect bridge podemos ver detalles de la red
[root@ServidorLinux7 ~]# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "5e09c396b098f62bef5be4c75a0bb0b949507f9d07f224f7efc23323f44ba263",
"Created": "2020-04-17T18:04:41.855693454+02:00",
"Scope": "local",
"Driver": "bridge",
...
No hemos puesto –network bridge porque es el tipo de red que se asigna automáticamente al
contenedor si no especificamos ninguna. Para oytra serís –network none o --network hots, ...
Ejecutemos ifconfig dentro del contenedor
docker exec -it container_1 ifconfig
Pata ver los interfaces creados
Hay dos interfaces de red.
Una interfaz loopback (que es una red None para aplicaciones internas)
Una interfaz de red privada privada (para conectarse al exterior con rango de ip) Con la ip
172.17.0.2
Los contenedores dentro de la red estarán dentro del mismo rango de ip’s.
Si qusieramos crera una red lo haríamos con
docker network create --driver bridge my_bridge_network
Indicando el driver y el nombre de la red
Despues podriamos iniciar un contenedor con esta red
docker run -d--name container_3 --net my_bridge_network busybox sleep 1000
o conectar una contenedor que este en otra red
docker network connect bridge container_3
DEFINIENDO REDES DE CONTENDORES CON DOCKER COMPOSE
6 PIPELINE DE INTEGRACION CONTINUA
ESCRIBE Y EJECUTA PRUEBAS UNITARIAS DENTRO DE
CONTENEDORES
Pruebas unitarias
docker-compose run
En el proyecto del curso James Lee creo un nuevo fichero test.py para ejecutar pruebas
llamandolo con el comando docker-compse run dockerapp python test.py
Yo usare el proyecto php-web (reduciendo el peso de la base de datos para que github no de
error al no permitir ficheros de más de 100 MB)
Y no haré pruebas en un principio.
Tansolo dejare que Circle CL revise el código y poco más. (ya habrá tiempo de complicarse…)
Usar docker para nuestra integración continua
El proceso de integración ciontinua con Docker tendría los siguientes pasos:
En negrita los pasos en los que entra docker, resto es el proceso normal de integración
continua.
1 - Los desarrolladores revisarán el código de forma loca.
2 - Cuando terminene de programar alguna funcionalidad enviaran los cambios al repositorio
central
3 - El servidor de integración continua estará supervisando el repositorio central
4 - Al registrar un cambio, normalmente, provoca que se ejecute una compilación en el servidor
de integración.
5 - El proceso de compilación puede variar de una aplicación a otra pero normalmemte implicaria.
- Revisar la ultima versión del código base.
- Compilar la aplicación.
- Ejecutar las pruebas unitarias y de integración.
6 - El servidor de IC creará la imagen de docker
7 - La aplicación va dentro de una imagen y el servidor IC envía la imagen a un registro
8 – Despues el servidor de IC podrá extraer la imagen del registro para ejecutarla en otro
host ya sea para desarrollo , puesta en marcha o producción.
GitHub – Agregar key SSH a cuenta GitHub
Seguir las instrucciones del video 5.35 (al final) del curso Udemy de Docker ó estas:
URL de la cuenta Github para hacer fork:
https://github.com/jleetutorial/dockerapp
Chequeo para keys SSH existentes:
https://help.github.com/articles/checking-for-existing-ssh-keys/
Genera una nueva key SSH y agrégala al agente ssh:
https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/
Agrega una nueva key SSH a tu cuenta GitHub:
https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/
Preparar nuestro proyecto para vincularlo desde GitHub con la
cuenta de CircleCI y establecer así un flujo de trabajo
Los pasos de compilacion de CircleCI se definen en un archivo de configuración -yml dentro de un
directorio llamado .circleci que debe ubicarse en el directorio raiz del repositorio Git.
Nosotros crearemos este directorio y añadiremos dentro el fichero config.yml
Este fichero tendra
Version 2 indica la version de circleci más recientes
- En jobs: Cada archivo de configuración debe tener un trabajo de compilación. Este es el trabajo
que es ejecutado automáticamente pot circleci
-Build: Para construir nuestra imagen)
- Despues un directorio de trabajo para todo el trabajo
- Despues la imagenes docker primario. Aqui definimos el entorno de circle ci que es donde
se ejecutarán nuestros pasos. En circleci todas las pruebas se ejecutarán en contenedores
y este contenedor creará nuestros contenedores dockerapp y redis y tambien ejecutará
nuestras pruebas. Así es que básicamente son contenedores dentro de un contendor
primario.
- En resumen, lo que queremos es una imagen que instale dockery tenga git. Estos r
equisitos se satisfacen usando la imagen: docker:17.05.0-ce-git Usando esta
imagen te aseguras de usar el úlrtimo cliente docker y con git preinstalado.
Steps: (pasos dentro del trabajo de compilacion)
- checkout: Creará e inspeccionará el código fuente desde github al directorio de
trabajo que ya hemos definido arriba.
- setup_remote_docker: para crear imagenes para despliege debemos usar un
conjunto especial de claves remotas docker que crearna un entorno separado para
cada compilación por seguridad. Este entorno es remoto completamente aislado y
será configurado para ejecutra comandos docker.
- run: Instalamos docker-compose en el entorno CI a raves de un gestor de paquetes
basado en python llamado pip, que tambien tenemos que instalar aquí.
-run: Ahora ya podemos iniciar nuestros contenedores y ejecutar nuestras pruebas
dentro de esos contenedores.
Comentamos las lineas donde luego enviaremos la imagen a docker hub
Subimos el proyecto a GitHub
Usaremos nuestra cuenta de GitHub para subir nuestro repositorio y la enlazaremos con nuestra
cuenta de CircleCI donde tendremos nuestro servidor de.
Nos situamos en la carpeta del proyecto
Subir un repositorio a Git Hub
echo "# php-apache" >> README.md
git init
git add README.md (opcionale)
git add .
git commit -m "first commit"
git remote add origin git@github.com:josedefrias/php-apache.git
git push -u origin master
Nuestro repositorio quedará subido a GitHub
NOTAS PARA HACER CAMBIOS EN EL REPOSITORIO Y SUBIRLO A GITHUB
unos cambios en el codigo fuente y los enviaremos al repositorio central para probar esto.
Esperamos ver una nueva compilacion automáticamente. Esta vez compilará bien porque no
pondremos la opción de publicar en dockerHub en una nueva rama de v0.6
1 Hacemos chekout en v0.6
git checkout v0.6
2 Creamos una nueva rama desde nuestro repositorio local llamandola test-ci
git checkout -b test-ci
3 agregamos un archivo ficticio y hacemos un commit de este a git
touch dummy.txt
git add dummy.txt
git commit -m "add dummy file to test circle build" (puede darnos un error al haber
puesto el correo real cuando generamos la key de SSH. Si ocurre con ejecutar los dos
comandos que nos da el error se arregla).
Necesitamos configurar la rama superior para la rama local que acabamos de crear
git push --set-upstream origin test-ci (Una vez configurada nos bastará con git push)
REALIZAR LA COMPILACION DESDE CIRCLECI
VAMOS A LA PAGINA DE CIRCLECI CON LA SESION INICIADA EN GITHUB
Entramos en la página de circleci, le damos a login y despues inicar sesion en github
niciando sesion en github se iniciará sesion automáticamente en circleci (Menos la primera vez
que te preguntará un par de cosas)
Entramos y hacecemos click en el boton de proyecto y despues en add proyecto
Despues seleccionamos el setup del proyecto dockerapp
Le damos a manually y Start Building.
Iniciará la compilación pero dará un error de falta de un fichero json...
Nos preocuparemos de esto más adelante, ya que el proyecto es grande y hay que revisar bien .
PUBLICAR IMAGENES DOCKER DESDE CIRCLECI
Yatenemos vinculadas nuestras cuentas de CircleCI y GitHub para que se envíen
automáticamente los cambios del repositorio central de GibHub al Servicor de IC de CircleCI.
Es decir el proceso se dirige a acabar subiendo a preproduccion y producción nuestros proyectos
según vayan recibiendo mejjoras testeadas y autorizadas.
Agregando credenciales de GitHub en las variables de entorno de CircleCI
Vamos a la página de Circle ci.
Vamos al panel de workflows.
Despues accemos click en el repositorio dockerapp
En la esquina superior derecha pulsamos la rueda de configuración del proyecto
Y despues en Enviroment variable
Añadimis dos variable:
DOCKER_HUB_USER_ID (para indicar el usuario) josedefrias
DOCKER_HUB_PWD (para la password) Dacasale219
DOCKER_HUB_EMAIL (para el correo) josedefrias@ipsotravel.com
De esta manera hemos guardado nuestras credenciales de DockerHub en CircleCI
Acontinuación agregaremos las instrucciones en el archivo circle.yml para la
publicación de imágenes docker.
Primero verificamos el código fuente
git stash && git checkout v0.6
Ahora creamos una nueva rama llamada circle_ci_publish (usando la opcion -b con git)
git checkout -b circle_ci_publish
Descomentamos las lineas del config.yml de .circleci para que despues de la compilación se
publique la imagen en docker file pero solo si el resultado es exitoso.
Ahora hacemos un commit en nuestros cambios y enviarlos al repositorio central de Github
git add .circleci/config.yml
git commit -m "push to docker hub from circleCI"
git push
OJO aquí al poner git push nos sugiereuna accion:
[oracle@ServidorLinux7 dockerapp]$ git push
fatal: You are not currently on a branch.
To push the history leading to the current (detached HEAD)
state now, use
git push origin HEAD:<name-of-remote-branch>
[oracle@ServidorLinux7 dockerapp]$ git push origin HEAD:<name-of-remote-branch>
bash: error sintáctico cerca del elemento inesperado `newline'
Y entonces ejecutamos:
dockerapp]$ git push origin circle_ci_publish
[oracle@ServidorLinux7 dockerapp]$ git push origin circle_ci_publish
Total 0 (delta 0), reused 0 (delta 0)
remote:
remote: Create a pull request for 'circle_ci_publish' on GitHub by visiting:
remote: https://github.com/josedefrias/dockerapp/pull/new/circle_ci_publish
remote:
To git@github.com:josedefrias/dockerapp.git
* [new branch] circle_ci_publish -> circle_ci_publish
[oracle@ServidorLinux7 dockerapp]$
Y una nueva compilacion ha sido acyivada en circleCI
Y si todo va bien ademas se habrá añadido una nueva imagen a Docker Hub.
Con dos etiquetas.
DESPLEGANDO EL PROYECTO EN PRODUCCION
La forma más popular de desplegar contendores en producción es configurar máquinas virtuales y
luego desplegar contenedores en estas máquinas.
Se usan máquinas virtuales para considerar los problemas de seguridad. Es fundamental
garantizar que un cliente no podrá acceder al la red de otro cliente.
DOCKER MACHINE
La forma más sencilla de configurar nueva máquinas virtuales y ejecutar contendores en ellas es
mediante DOCKER MACHINE. Docker Machine puede configurar nuevas másuinas virtuales
instalar las herramientas docker en ellas y vincular el cliente Docker con las máquinas docker
remotas .
Docker machine proporciona soporte para varios controladores de proveedores de servicios en la
nube como AWS, Digital Ocean o Google app engine.
SUBIREMOS EL PROYECTO A UN DROPLET DE DIGITAL OCEAN
(Un droplet es se llaman las maquinas virtuales en Digital Ocean)
CREAMOS LA CUENTA EN DIGITAL OCEAN (SI AUN NO LA
TENEMOS)
He creado una cuenta de Digital Ocean para este proyecto. Dan 100 euros gratis para
gastar antes de dos meses. Asi es que aprovechamos ese tiempo para practicar este y
otros proyectos.
Aunque yo ya tengo token para conectar pongo la explicacion de como crearlo:
Para acceder a la cuenta de digital Ocean a traves de su api y gestionar una máquina
virtual necesitamos generar un token de acceso personal.
Los token de acceso personal funcionan como los token ordinarios de acceso que pueden
usarse para permitirnos acceder a los recursos de nuestra cuenta en DO sin necesidad de
alguna contraseña.
Hacemos click en API y despues en Generate New Token
Le damos un nombre al token por ejemplo: dockerapp
Y clickeamos en Generate Token
Ahora veras el token. Haz click en el portapapeles y copialo a un archivo y guardalo en otro lugar
donde puedas acceder a el ya que lo usaremos posteriormente.
CREAMOS LA MAQUINA VIRTUAL USANDO DOCKER-MACHINE
Para ver si tienes instalado docker machine (sino en el documento que hice del curso esta como
instalarlo)
docker-machine ls
Con docker machine podemos crear una máquina virtual en Digital Ocen con el comando docker
create con los siguiente argumentos:
driver del proveedor: --driver digitalocean
token de acceso: digitalocean-access-token
69492d79cf0cba6d3f96804ecb0895130f86da0f2a6a49ac08be782f7a4db9ac
nombre de la maquina: docker-app-machine
Y empezará el proceso de solicitud a digital ocean, instalación del docker engine en la máquina
virtual y generar los certificados:
el comando sería así.
docker-machine create --driver digitalocean --digitalocean-access-token
69492d79cf0cba6d3f96804ecb0895130f86da0f2a6a49ac08be782f7a4db9ac php-apache-
machine
Una vez termine:
Si hacemos docker-machine ls veremos nuestra máquina creada
Ahora ay que configurar el entorno del cliente docker
docker-machine env php-apache-machine
Estos mostrará los comandos necesarios para configurar el entorno de cliente docker
[oracle@ServidorLinux7 ~]$ docker-machine env php-apache-machine
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://134.209.37.149:2376"
export DOCKER_CERT_PATH="/home/oracle/.docker/machine/machines/php-apache-machine"
export DOCKER_MACHINE_NAME="php-apache-machine"
# Run this command to configure your shell:
# eval $(docker-machine env php-apache-machine)
[oracle@ServidorLinux7 ~]$
Cuando termine nos sugiere un comando para configurar las variables de entorno que deben
configurar nuestro cliente docker y este logreconectarse a la máquina virtual que acabamos de
provisionar.
Lo ejecutamos:
eval $(docker-machine env php-apache-machine)
Con esto establecemos la maquina como activa para trabajar con ella. Ejecutamos docker-
machine ls y veremos que es la que tiene el asterisco.
ahora con.
docker info
veremos informacion de la máquina virtual
[oracle@ServidorLinux7 dockerapp]$ docker info
Con esto ya tenemos nuestra máquina virtual provista.
DESPLEGAMOS LA APLICACION EN DIGITAL OCEAN USANDO
DOCKER-MACHINE
Desplegaremos la aplicación usando el comando docker-compose
Podemos hacerlo usando otro .yml para producción
docker-compose -f prod.yml up -d
o el mismo con el que hemos estado trabajando.
docker-compose up -d
MUY IMPORTANTE ASEGURARNOS QUE ESTAMOS EN EL ENTORNO DE LA MAQUINA.
(NO SE SI LO MEJOR ES QUE LAS IMAGENES QUE HEMOS PUESTO EN EL prod.yml
ESTEN EN DOCKER-HUB )
Hacemos docker-machine ls para asegurarnos de que el asterisco este en la máquina donde
queremos desplegar el proyecto.
Se desplegará la plicación en la máquina virtual remota y podremos ver el resultado
accediendo desde el browser http://165.227.189.83/
A partir de aquí controlaremos esta máquina con los comandos de docker-machine
COMANDOS DOCKER-MACHINE
docker-machine create --driver digitalocean --digitalocean-access-token
69492d79cf0cba6d3f96804ecb0895130f86da0f2a6a49ac08be782f7a4db9ac php-apache-
machine
docker info
docker-machine ls Ver las máquinas
docker-machine stop id_maquina Parar la máquina
docker-machine startid_maquina Iniciar la máquina
docker-machine env php-apache-machine para establecer el entorno en esta :
eval $(docker-machine env php-apache-machine) es la que recomienda docker
docker-machine env –unset) Volver a la maquina anfitrion
eval $(docker-machine env --unset) es la que recomienda docker
docker-machine ssh php-apache-machine Entrar en la máquina
https://picodotdev.github.io/blog-bitix/2015/07/usar-docker-con-docker-machine-en-linux-windows-
o-mac/
Para usar Docker Machine debemos descargar el binario, darle permisos de ejecución y si
queremos añadirlo a la variable PATH del sistema.
1 $ docker-machine --version
Con los siguientes comandos podemos crear una máquina virtual para los contenedores docker,
listar las máquinas virtuales creadas, hacer SSH a ella, ejecutar un contenedor en ella, parala y
eliminar una máquina virtual además de obtener la IP asignada.
1 $ docker-machine create --driver virtualbox dev
2 $ docker-machine ls
Estableciendo las variables de entorno de la máquina virtual podemos usar el comando docker
como si de la máquina anfitrión fuera, todos los comandos de docker que lancemos se ejecutarán
contra el contenedor docker de la máquina virtual. En el siguiente caso se ejecuta el contenedor
de busybox en la máquina virtual dev. Con --unset podemos reiniciar la configuración a la
máquina anfitrión.
1 $ docker-machine env dev
2 $ eval "$(docker-machine env dev)"
3 $ docker run busybox echo "hello world"
4 $ eval "$(docker-machine env --unset)"
Podemos detener, volver a iniciar, hacer SSH y eliminar la máquina virtual con:
1 $ docker-machine start dev
2 $ docker-machine ssh dev
3 $ docker-machine stop dev
4 $ docker-machine rm dev
El directorio por defecto donde se guardarán los archivos de las máquinas virtuales es
~/.docker/machine, si queremos cambiarlo podemos utilizar el parámetro --storage-path en cada
uno de los comandos anteriores de la siguiente forma, el orden de los parámetros es importante:
1 $ docker-machine --storage-path "/run/media/picodotdev/BMOVE_ROJO/docker/machine" create --
DOCKER SWARM Y CONFIGURACION DE UN CLUSTER SWARM
DOCKER SWARM
Docker Swarm es el administrador de clusteres de Docker entre el cliente docker y estos hosts.
Cuando quieres ejecutar un servicio sera el administrador Swarm quien decida donde ejecutar
ese servicio.
Solo tienes que direccionar tu cliente docker al administrador Swarm en lugar de hacerlo en todos
y cada uno de los dockers daemonds.
Básicamente Docker Swarm puede agrupar varios Host en un cluster y distribuir contenedores
docker en estos Hosts.
CONFIGURACION
- PASO 1 Creacion de las dos máquinas virtuales
Las podemos crear utilizando el mismo comando docker-machine create que utilizamos
anteriormente.
NODO ADMINISTRADOR
docker-machine create --driver digitalocean --digitalocean-access-token
69492d79cf0cba6d3f96804ecb0895130f86da0f2a6a49ac08be782f7a4db9ac php-apache-
manager
Una vez este creada
Debemos permitir que nuestro cleinte se conecte a la máquina virtual swarm-manager con:
docker-machine env swarm-manager
Luego copiamos el comando que se nos muestra en pantalla para configurar nuestro shell. Con
esto activamos la máquina.
eval $(docker-machine env php-apache-manager)
NODO DE TRABAJO
docker-machine create --driver digitalocean --digitalocean-access-token
69492d79cf0cba6d3f96804ecb0895130f86da0f2a6a49ac08be782f7a4db9ac php-apache-node
Ahora ya tenemos las dos máquinas virtuales
- PASO 2 Nombra la primera máquina como administrador
Swarm e inicia el cluster
Nombrar la primera máquina virtual como un administrador swarm. Esto se puede hacer a traves
del comando docker swarm init que inicializará un swarm.
El docker engine modificado por este comando se convertirá en un nodo administrador en
el swarm de un solo nodo recientemente creado
Antes de ejecutar el comando asegurémonos que el entorno apunta ala máquina virtual del
administrador swarm
docker swarm init
Da un error porque dice que esta máquina tiene múltiples interfaces de red y docker swarm no
sabe cual usar para comunicarse.
[oracle@ServidorLinux7 dockerapp]$ docker swarm init
Error response from daemon: could not choose an IP address to advertise since this system has multiple addresses
on interface eth0 (64.225.56.180 and 10.17.0.6) - specify one with –advertise-addr
Por defecto, la máquina virtual viene con dos ip’s una es una ip pública y la otra una ip privada.
Aquí usaremos la ip pública para iniciar nuestro docker swarm ejecutando:
docker swarm init --advertise-addr 64.225.56.180
[oracle@ServidorLinux7 dockerapp]$ docker swarm init --advertise-addr 64.225.56.180
Swarm initialized: current node (nqit2ah2vlsk45nk0ji2il9sm) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-52758ju5982a9zjyaqij72jmjlu3hh9o2zjx5sn5chxo3kbp3j-
5uxo6l299lf98vuglt4z4wsm0 165.227.109.90:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
[oracle@ServidorLinux7 dockerapp]$
Ahora el cluster swarm se inicializa exitosamente
- PASO 3 Dejar que la segunda máquina se una al cluster
Swarm como un nodo de trabajo
Swarm tambien nos proporciona un comando para ejecutar si queremos agregar un nodo al
cluster swarm.
Es importante tener en cuenta que este comando debe ejecutarse en el nodo de trabajo.
Asi que aquí en lugar de cambiar la máquina virtual activa podemos ejecutar. Docker-machine ssh
en la máquinavirtual del nodo de trabajo
docker-machine ssh php-apache-node
Con esto entramos a la máquina virtual del nodo de trababajo
root@swarm-node:~#
Cuando creamos el nodo administrador nos informo de la orden que debemos dar para crear
nodos de trabajo.
Ejecutamos esa orcen dentro del nodo de trabajo
docker swarm join --token SWMTKN-1-52758ju5982a9zjyaqij72jmjlu3hh9o2zjx5sn5chxo3kbp3j-
5uxo6l299lf98vuglt4z4wsm0 165.227.109.90:2377
This node joined a swarm as a worker.
root@swarm-node:~#
Y el nodo de trabajo se ha unido al cluster
DESPLIEGE DE LA APLICACION A LA NUBE CON DOCKER SWARM
Los servicios se pueden definir en nuestro archivo docker-compose. En nuestro caso teniamos los
servicios dockerapp y redis.
La definición del servicio incluye que imagenes de docker se ejecutarán, la asignacion de puertos
y la dependencia entre servicios. Tambien surge una nueva llave: deploy que se puede usar para
equilibrar la carga y optimizar el rendimiento de cada servicio.
Un ejemplo:
el valor de réplicas a 3, lo que significa que docker ejecutará 3 instancias (contenedores) de la
imagen nginx como un servicio llamado nginx.
En resources podemos establecer límites de uso de cpu y memoria
Con restar_policy podemos pedirle a docker que reinicie los contenedore sen caso de que uno de
ellos falle.
Todo esto esta hecho para garantizar excalabilidad de ompilación y alta disponibilidad para los
servicios desplegados en un cluster Swarm.
DOCKER STACK
DOCKER STACK = DOCKER-COMPOSE EN MODO SWARM
Creamos un nuevo fichero prod_swarm.yml para nuestro swarm. Será igual que el que tenms
para producción de la anterior máquina (que no esta en claster) pero añadiendo la llave deploy.
De momento, para no complicarnos, solo dos replicas en el servicio phpapache.
A continuacion crearemos unstack a partir de nuestro archivo docker compose y lo
desplagaremos a docker swarm con el comando docker stack deploy mas la opción para el
fichero de docker compose y un combre al nuevo stack
OJO! Siempre con el entorno apuntando a nuestro manager
docker stack deploy --compose-file prod_swarm.yml php-apache_stack
[oracle@ServidorLinux7 php-apache]$ docker stack deploy --compose-file prod_swarm.yml php-apache_stack
Creating network php-apache_stack_default
Creating service php-apache_stack_phpapache
Creating service php-apache_stack_mysqltoo
ahora docker swarm a creado una red overlay por nosotros llamada apache-php_stack_default
para la comunicación cruzada de nodos. Esta red se crea automaticamente cuando ejecutamos
docker stack deploy.
docker stack ls Para ver todos los stacks
docker stack services php-apache_stack Para listar todos los servicios del stack
Ya tenemos un stack compuesto por dos servicios
Para acceder a nuestro servicio phpapache.
Primero enumeremos las direcciones ip de todas las máquinas virtuales en ejecución.
[oracle@ServidorLinux7 php-apache]$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER
docker-app-machine - digitalocean Stopped Unknown
php-apache-machine - digitalocean Running tcp://165.227.189.83:2376 v19.03.8
php-apache-manager * digitalocean Running tcp://165.227.109.90:2376 v19.03.8
php-apache-node - digitalocean Running tcp://159.89.47.60:2376 v19.03.8
swarm-manager - digitalocean Stopped Unknown
swarm-node - digitalocean Stopped Unknown
Deberiamos poder acceder a phpapche desde cualquiera de los host debido a la funcionalidad de
equilibrio de carga de swarm. Usemos la ip de cualquiera de las dos máquinas del swarm en el
navegador
165.227.109.90:80
159.89.47.60
y entraremos a nuestra aplicación dockerapp
REALIZAR CAMBIOS
Tan simple como volver a ejecutar el docker stack deploy con los cambios realizados n el .yml
Agregar un contenedor, por ejemplo, a mysql: Con poner deploy en el servicio y replica: 2 bastará
docker stack deploy --compose-file prod_swarm.yml php-apache_stack
Ya no creará la red overlay porque se creo la primera ver.
Agregar un contenedor por ejemplo a mysql: Con poner deploy en el servicio y replica: 2 bastará
Ojo!!! si cambiamos alguna imagen hay que subirla a docke hub
docker stack rm dockerapp_stack PARA BORRAR EL STACK
6-44 HERRAMIENTAS DE MONITOREO DE DOCKER
docker stat id_container
docker stat
Todos los contenedores Docker se envían con una herramienta de monitoreo preconfigurada que
es Docker Stat.
El siguiente comando proporciona estadísticas de la utilización de la CPU docker, el uso de
memoria, el límite de memoria y las métricas de E / S de la red.
$ docker stats [CONTENEDOR …]
El primer comando "docker" es un comando base para la CLI de docker. Puede especificar uno o
más contenedores separados por espacios para obtener información sobre cada uno.
El siguiente comando mostrará detalles de todos los contenedores que se ejecutan en Linux
daemon
$ docker stats