3. Docker Services (DevOps series)

Genial, si ya llegaste hasta aquí eres perfectamente capaz de crear y gestionar tus propias imágenes, tanto en tu máquina local como en tu propio repositorio, ahora bien comencemos a entrar a un plano más profesional y para esto empezaremos ya a hablar de servicios, de cluster, de pods y del deploy de estos, para ello necesitamos entender estos nuevos conceptos.

Que es un cluster, pues bien fácilmente podemos definir un cluster como un conjunto de instancias de maquinas (Nodos) que aportan su rendimiento ya sea de CPU, GPU o memoria a un fin en común de forma organizada. Bien con esto ya entendemos entonces que un Nodo es una instancia de una máquina tipo Virtual Machine (VM) cuyo fin es el despliegue de aplicaciones.

Ahora bien, que es un pod, pues aquí viene lo interesante y comienza la carnita, ya que el pod es un conjunto de aplicaciones dentro de una instancia, y cada uno de estos pods tiene su propia IP y esta no es expuesta fuera del cluster.

Veamos la siguiente imagen:

Pues bien, como podemos apreciar entonces un cluster está compuesto de varios nodos y dentro de estos nodos existen pods y dentro de estos pods existirán nuestras aplicaciones (containers).

Para esta práctica vamos a crear el siguiente código:

Dockerfile

# Use an official Python runtime as a parent image
FROM python:2.7-slim

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
COPY . /app

# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt

# Make port 80 available to the world outside this container
EXPOSE 80

# Define environment variable
ENV NAME World

# Run app.py when the container launches
CMD ["python", "app.py"]

requirements.txt

Flask
Redis

app.py

from flask import Flask
from redis import Redis, RedisError
import os
import socket

# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

app = Flask(__name__)

@app.route("/")
def hello():
try:
visits = redis.incr("counter")
except RedisError:
visits = "cannot connect to Redis, counter disabled"

html = "
Hello {name}!

" \
"Hostname: {hostname}
" \
"Visits: {visits}"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)

if __name__ == "__main__": app.run(host='0.0.0.0', port=80)

Ahora vamos a crear una imagen de esto con la siguiente instrucción:

docker build --tag=blackdie79/docker-demo:part2 .

Recuerden acá usar su nombre de repositorio, bien ahora subamos esta imagen al repositorio

docker push tonyman/docker-demo:part2

Bueno esto es para ir entendiendo el funcionamiento de este ecosistema, para este ejemplo utilizaremos un archivo de docker-compose.yml el cual nos dará lo necesario para exponer la aplicación que acabamos de crear.

Ejemplo del archivo:

version: "3"
services:
web:
# replace username/repo:tag with your name and image details
image: blackdie79/docker-demo:part2
deploy:
replicas: 2
resources:
limits:
cpus: "0.1"
memory: 50M
restart_policy:
condition: on-failure
ports:
- "4000:80"
networks:
- webnet
networks:
webnet:

Que estamos diciendo en este archivo???

  • Usa de la imagen que subimos con el tag part2 .
  • Ejecute 2 instancias de esa imagen como un servicio llamado web, limitando a cada una a usar, como máximo, el 10% de la CPU (en todos los núcleos) y 50 MB de RAM.
  • Reinicie inmediatamente los contenedores si falla uno.
  • Asigne el puerto 4000 en el host al puerto web 80 de nuestra aplicación.
  • Indique a los contenedores de la web que compartan el puerto 80 a través de una red de carga equilibrada llamada webnet. (Internamente, los propios contenedores se publican en el puerto 80 de la web en un puerto efímero).
  • Defina la red web con la configuración predeterminada (que es una red de superposición con equilibrio de carga).

Bien  ahora vamos a iniciar un cluster aunque este proceso lo retomaremos luego con más profundidad. ingresa el comando:

docker swarm init

Con eso iniciamos el cluster, ahora vamos a desplegar la aplicación con nuestro nuevo archivo y a esta app le llamaremos myApp, para esto ingresa por línea de comandos

docker swarm init

Con eso iniciamos el cluster, ahora vamos a desplegar la aplicación con nuestro nuevo archivo y a esta app le llamaremos myApp, para esto ingresa por línea de comandos

docker stack deploy -c docker-compose.yml myApp

Perfecto, ahora veamos nuestro servicios corriendo, ingresemos:

docker service ls

Deberían ver en pantalla algo similar a esto:

Bien ese es nuestro servicio corriendo, con nuestro balanceador de carga en local, ahora nosotros declaramos en nuestro archivo que queríamos 2 contenedores(aplicaciones) corriendo en simultaneo, para verlo usa en línea de comando:

docker container ls

Ya puedes ir a tu navegador e ingresar por el http://localhost:4000 y si refrescas varias veces verás que el Hostname cambia, claro están corriendo en contenedores diferentes, que tienen una misma salida, por cierto si estás corriendo esto en windows posiblemente la salida no sea localhost para ti, sino la ip de la máquina virtual que tenga linux instalado.

Ahora vamos a escalar nuestra aplicación, donde  antes decía réplicas : 2 ahora dile que son 5

    deploy:
replicas: 5

y vuelve a correr el comando de despliegue

docker stack deploy -c docker-compose.yml myApp

Ahora mira las aplicaciones correr:

docker container ls

Perfecto a esto se le llama escalar una aplicación y es uno de los conceptos fundamentales a tener en cuenta, bien hasta aquí hoy aprendimos a crear un cluster, desplegamos nuestro propio balanceador de carga, escalamos una aplicación, ahora limpiemos este desastre

Eliminemos la aplicación:

docker stack rm getstartedlab

Eliminamos el cluster:

docker swarm leave --force

Excelente… Si te perdiste de algo o no lo recuerdas ve a los post anteriores:

Información de Contacto

Heredia, Costa Rica, 40102

+506 6048-6672
info@blackdiezone.net

Lunes a Sabado: 8:00 am - 5:00 pm
Domingos: Cerrado

Copyright 2021 Blackdie Zone Network ©  All Rights Reserved