Compartir comentarios
Las respuestas se generan en base a la documentación.

Desplegar una pila (stack) en un swarm

Al ejecutar Docker Engine en modo swarm, puedes utilizar el comando docker stack deploy para desplegar una pila de aplicaciones completa en el swarm. El comando deploy acepta una descripción de la pila en forma de archivo Compose.

Note

El comando docker stack deploy utiliza el formato heredado versión 3 del archivo Compose, utilizado por Compose V1. El formato definido por la especificación de Compose no es compatible con el comando docker stack deploy.

Para obtener más información sobre la evolución de Compose, consulta la Historia de Compose.

Para realizar este tutorial, necesitas:

  1. Un Docker Engine ejecutándose en modo Swarm. Si no estás familiarizado con el modo Swarm, es recomendable leer los Conceptos clave del modo Swarm y Cómo funcionan los servicios.

    Note

    Si estás probando esto en un entorno de desarrollo local, puedes activar el modo Swarm en tu motor de ejecución con docker swarm init.

    Si ya tienes un swarm de múltiples nodos en funcionamiento, ten en cuenta que todos los comandos docker stack y docker service deben ejecutarse desde un nodo administrador (manager).

  2. Una versión reciente de Docker Compose.

Configurar un registro de Docker (Registry)

Dado que un swarm consta de múltiples Docker Engines, se requiere un registro para distribuir las imágenes a todos ellos. Puedes utilizar Docker Hub o mantener tu propio registro. A continuación, se detalla cómo crear un registro temporal, que podrás eliminar después.

  1. Inicia el registro como un servicio en tu swarm:

    $ docker service create --name registry --publish published=5000,target=5000 registry:2
    
  2. Comprueba su estado con docker service ls:

    $ docker service ls
    
    ID            NAME      REPLICAS  IMAGE                                                                               COMMAND
    l7791tpuwkco  registry  1/1       registry:2@sha256:1152291c7f93a4ea2ddc95e46d142c31e743b6dd70e194af9e6ebe530f782c17
    

    Cuando se lea 1/1 en la columna REPLICAS, estará en funcionamiento. Si indica 0/1, probablemente todavía esté descargando la imagen.

  3. Verifica que esté funcionando utilizando curl:

    $ curl http://127.0.0.1:5000/v2/
    
    {}
    

Crear la aplicación de ejemplo

La aplicación utilizada en esta guía se basa en la aplicación de contador de visitas de la guía Primeros pasos con Docker Compose. Consiste en una aplicación en Python que mantiene un contador en una instancia de Redis e incrementa el contador cada vez que la visitas.

  1. Crea un directorio para el proyecto:

    $ mkdir stackdemo
    $ cd stackdemo
    
  2. Crea un archivo llamado app.py en el directorio del proyecto y pega el siguiente contenido:

    from flask import Flask
    from redis import Redis
    
    app = Flask(__name__)
    redis = Redis(host='redis', port=6379)
    
    @app.route('/')
    def hello():
        count = redis.incr('hits')
        return 'Hello World! I have been seen {} times.\n'.format(count)
    
    if __name__ == "__main__":
        app.run(host="0.0.0.0", port=8000, debug=True)
  3. Crea un archivo llamado requirements.txt y pega estas dos líneas:

    flask
    redis
  4. Crea un archivo llamado Dockerfile y pega el siguiente contenido:

    # syntax=docker/dockerfile:1
    FROM python:3.4-alpine
    ADD . /code
    WORKDIR /code
    RUN pip install -r requirements.txt
    CMD ["python", "app.py"]
  5. Crea un archivo llamado compose.yaml y pega el siguiente contenido:

      services:
        web:
          image: 127.0.0.1:5000/stackdemo
          build: .
          ports:
            - "8000:8000"
        redis:
          image: redis:alpine

    La imagen para la aplicación web se construye utilizando el Dockerfile definido anteriormente. También se etiqueta con 127.0.0.1:5000, que es la dirección del registro creado previamente. Esto es importante al distribuir la aplicación en el swarm.

Probar la aplicación con Compose

  1. Inicia la aplicación con docker compose up. Esto construye la imagen de la aplicación web, descarga la imagen de Redis si aún no la tienes y crea dos contenedores.

    Verás una advertencia indicando que el motor de ejecución está en modo Swarm. Esto se debe a que Compose no aprovecha el modo Swarm y despliega todo en un único nodo. Puedes ignorar esta advertencia.

    $ docker compose up -d
    
    WARNING: The Docker Engine you're using is running in swarm mode.
    
    Compose does not use swarm mode to deploy services to multiple nodes in
    a swarm. All containers are scheduled on the current node.
    
    To deploy your application across the swarm, use `docker stack deploy`.
    
    Creating network "stackdemo_default" with the default driver
    Building web
    ...(build output)...
    Creating stackdemo_redis_1
    Creating stackdemo_web_1
    
  2. Verifica que la aplicación se esté ejecutando utilizando docker compose ps:

    $ docker compose ps
    
          Name                     Command               State           Ports
    -----------------------------------------------------------------------------------
    stackdemo_redis_1   docker-entrypoint.sh redis ...   Up      6379/tcp
    stackdemo_web_1     python app.py                    Up      0.0.0.0:8000->8000/tcp
    

    Puedes probar la aplicación utilizando curl:

    $ curl http://localhost:8000
    Hello World! I have been seen 1 times.
    
    $ curl http://localhost:8000
    Hello World! I have been seen 2 times.
    
    $ curl http://localhost:8000
    Hello World! I have been seen 3 times.
    
  3. Detén y elimina la aplicación:

    $ docker compose down --volumes
    
    Stopping stackdemo_web_1 ... done
    Stopping stackdemo_redis_1 ... done
    Removing stackdemo_web_1 ... done
    Removing stackdemo_redis_1 ... done
    Removing network stackdemo_default
    

Subir la imagen generada al registro

Para distribuir la imagen de la aplicación web por todo el swarm, es necesario subirla al registro que configuraste anteriormente. Con Compose, este proceso es directo:

$ docker compose push

Pushing web (127.0.0.1:5000/stackdemo:latest)...
The push refers to a repository [127.0.0.1:5000/stackdemo]
5b5a49501a76: Pushed
be44185ce609: Pushed
bd7330a79bcf: Pushed
c9fc143a069a: Pushed
011b303988d2: Pushed
latest: digest: sha256:a81840ebf5ac24b42c1c676cbda3b2cb144580ee347c07e1bc80e35e5ca76507 size: 1372

La pila (stack) ya está lista para ser desplegada.

Desplegar la pila al swarm

  1. Crea la pila utilizando el comando docker stack deploy:

    $ docker stack deploy --compose-file compose.yaml stackdemo
    
    Ignoring unsupported options: build
    
    Creating network stackdemo_default
    Creating service stackdemo_web
    Creating service stackdemo_redis
    

    El último argumento es el nombre de la pila. Cada red, volumen y nombre de servicio tendrá como prefijo el nombre de la pila.

  2. Comprueba que se esté ejecutando utilizando docker stack services stackdemo:

    $ docker stack services stackdemo
    
    ID            NAME             MODE        REPLICAS  IMAGE
    orvjk2263y1p  stackdemo_redis  replicated  1/1       redis:3.2-alpine@sha256:f1ed3708f538b537eb9c2a7dd50dc90a706f7debd7e1196c9264edeea521a86d
    s1nf0xy8t1un  stackdemo_web    replicated  1/1       127.0.0.1:5000/stackdemo@sha256:adb070e0805d04ba2f92c724298370b7a4eb19860222120d43e0f6351ddbc26f
    

    Una vez que esté en funcionamiento, deberías ver 1/1 en la columna REPLICAS para ambos servicios. Esto puede tardar un poco si tienes un swarm de múltiples nodos, ya que se deben descargar las imágenes.

    Como antes, puedes probar la aplicación con curl:

    $ curl http://localhost:8000
    Hello World! I have been seen 1 times.
    
    $ curl http://localhost:8000
    Hello World! I have been seen 2 times.
    
    $ curl http://localhost:8000
    Hello World! I have been seen 3 times.
    

    Con la malla de enrutamiento integrada de Docker, puedes acceder a cualquier nodo del swarm en el puerto 8000 y ser redirigido a la aplicación:

    $ curl http://address-of-other-node:8000
    Hello World! I have been seen 4 times.
    
  3. Elimina la pila con el comando docker stack rm:

    $ docker stack rm stackdemo
    
    Removing service stackdemo_web
    Removing service stackdemo_redis
    Removing network stackdemo_default
    
  4. Elimina el registro utilizando el comando docker service rm:

    $ docker service rm registry
    
  5. Si solo estás probando cosas en una máquina local y deseas retirar tu Docker Engine del modo Swarm, utiliza docker swarm leave:

    $ docker swarm leave --force
    
    Node left the swarm.