tutorial swarm hub espaƱol compose docker-swarm

docker swarm - swarm - Ejecutar un comando dentro del servicio de enjambre docker.



docker swarm vs kubernetes (6)

  1. Inicializar el modo de enjambre:

    root@ip-172-31-44-207:/home/ubuntu# docker swarm init --advertise-addr 172.31.44.207 Swarm initialized: current node (4mj61oxcc8ulbwd7zedxnz6ce) is now a manager. To add a worker to this swarm, run the following command:

  2. Únete al segundo nodo:

    docker swarm join / --token SWMTKN-1-4xvddif3wf8tpzcg23tem3zlncth8460srbm7qtyx5qk3ton55-6g05kuek1jhs170d8fub83vs5 / 172.31.44.207:2377

Para agregar un administrador a este enjambre, ejecute el ''administrador de engarce de enjambre de enjambre de docker'' y siga las instrucciones.

# start 2 services docker service create continuumio/miniconda3 docker service create --name redis redis:3.0.6 root@ip-172-31-44-207:/home/ubuntu# docker service ls ID NAME REPLICAS IMAGE COMMAND 2yc1xjmita67 miniconda3 0/1 continuumio/miniconda3 c3ptcf2q9zv2 redis 1/1 redis:3.0.6

Como se muestra arriba, redis tiene su réplica mientras que la miniconda no parece estar replicada .

Por lo general, me conecto al contenedor de miniconda para escribir estos comandos:

/opt/conda/bin/conda install jupyter -y --quiet && mkdir /opt/notebooks && /opt/conda/bin/jupyter notebook --notebook-dir=/opt/notebooks --ip=''*'' --port=8888 --no-browser

El problema es que el comando docker exec -it XXX bash no funciona con el modo swarm.


EDITAR 2017-10-06:

Hoy en día, puede crear la red de superposición con el indicador --attachable para permitir que cualquier contenedor se una a la red. Esta es una gran característica, ya que permite mucha flexibilidad.

P.ej

$ docker network create --attachable --driver overlay my-network $ docker service create --network my-network --name web --publish 80:80 nginx $ docker run --network=my-network -ti alpine sh (in alpine container) $ wget -qO- web <!DOCTYPE html> <html> <head> ....

Usted tiene razón, no puede ejecutar docker exec en el servicio de modo de enjambre de docker. Pero aún puede descubrir qué nodo está ejecutando el contenedor y luego ejecutar exec directamente en el contenedor. P.ej

docker service ps miniconda3 # find out, which node is running the container eval `docker-machine env <node name here>` docker ps # find out the container id of miniconda docker exec -it <container id here> sh

En su caso, primero debe averiguar por qué el servicio no puede levantar el contenedor de miniconda. ¿Tal vez el docker service ps miniconda3 muestra algunos mensajes de error útiles?


Escribí el script a comando exec en enjambre docker por nombre de servicio. Por ejemplo, se puede utilizar en cron. También puede usar tuberías de bash y pasar todos los parámetros al comando docker exec . Pero funciona solo en el mismo nodo donde se inició el servicio. Ojalá pudiera ayudar a alguien

#!/bin/bash # swarm-exec.sh set -e for ((i=1;i<=$#;i++)); do val=${!i} if [ ${val:0:1} != "-" ]; then service_id=$(docker ps -q -f "name=$val"); if [[ $service_id == "" ]]; then echo "Container $val not found!"; exit 1; fi docker exec ${@:1:$i-1} $service_id ${@:$i+1:$#}; exit 0; fi done echo "Usage: $0 [OPTIONS] SERVICE_NAME COMMAND [ARG...]"; exit 1;

Ejemplo de uso:

./swarm-exec.sh app_postgres pg_dump -Z 9 -F p -U postgres app > /backups/app.sql.gz echo ls | ./swarm-exec.sh -i app /bin/bash ./swarm-exec.sh -it some_app /bin/bash


Hay un forro para acceder a la instancia correspondiente del servicio para localhost:

docker exec -ti stack_myservice.1.$(docker service ps -f ''name=stack_myservice.1'' stack_myservice -q --no-trunc | head -n1) /bin/bash

Se prueba en PowerShell, pero bash debería ser el mismo. El oneliner accede a la primera instancia, pero reemplaza ''1'' con el número de la instancia a la que deseas acceder en dos lugares para obtener otra.

Un ejemplo más complejo es el caso distribuido:

#! /bin/bash set -e exec_task=$1 exec_instance=$2 strindex() { x="${1%%$2*}" [[ "$x" = "$1" ]] && echo -1 || echo "${#x}" } parse_node() { read title id_start=0 name_start=`strindex "$title" NAME` image_start=`strindex "$title" IMAGE` node_start=`strindex "$title" NODE` dstate_start=`strindex "$title" DESIRED` id_length=name_start name_length=`expr $image_start - $name_start` node_length=`expr $dstate_start - $node_start` read line id=${line:$id_start:$id_length} name=${line:$name_start:$name_length} name=$(echo $name) node=${line:$node_start:$node_length} echo $name.$id echo $node } if true; then read fn docker_fullname=$fn read nn docker_node=$nn fi < <( docker service ps -f name=$exec_task.$exec_instance --no-trunc -f desired-state=running $exec_task | parse_node ) echo "Executing in $docker_node $docker_fullname" eval `docker-machine env $docker_node` docker exec -ti $docker_fullname /bin/bash

Este script podría ser utilizado más adelante como:

swarm_bash stack_task 1

Simplemente ejecuta bash en el nodo requerido.


Puede ejecutar comandos filtrando el nombre del contenedor sin tener que pasar todo el hash del contenedor de enjambre, solo por el nombre del servicio. Me gusta esto:

docker exec $(docker ps -q -f name=servicename) ls


Puede saltar a un nodo de Swarm y listar los contenedores de la ventana acoplable que se ejecutan usando:

docker container ls

Eso le dará el nombre del contenedor en un formato similar a: contener nombre de usuario.1.q5k89uctyx27zmntkcfooh68f

Luego puede usar la opción de ejecución regular para ejecutar comandos en ella:

docker container exec -it containername.1.q5k89uctyx27zmntkcfooh68f bash


Usando la API de Docker

En este momento, Docker no proporciona una API como docker service exec docker stack exec o docker stack exec para esto. Pero con respecto a esto, ya existen dos problemas relacionados con esta funcionalidad:

(Respecto al primer problema, para mí, no estaba directamente claro que este problema se trata exactamente de este tipo de funcionalidad. Pero Exec para Swarm se cerró y se marcó como duplicado del problema del ejecutivo de servicio de Docker ).

Usando el demonio Docker sobre HTTP

Como lo mencionó BMitch al ejecutar el ejecutable docker exec desde el administrador de enjambres , también podría configurar el demonio Docker para usar HTTP y luego conectarse a cada nodo sin la necesidad de ssh. Pero debe proteger esto mediante la autenticación TLS que ya está integrada en Docker. Después, podrá ejecutar el docker exec así:

docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem / -H=$HOST:2376 exec $containerId $cmd

Usando skopos-plugin-swarm-exec

Existe un proyecto github que pretende resolver el problema y proporcionar la funcionalidad deseada que vincula al demonio docker:

docker run -v /var/run/docker.sock:/var/run/docker.sock / datagridsys/skopos-plugin-swarm-exec / task-exec <taskID> <command> [<arguments>...]

Por lo que puedo ver, esto funciona creando otro contenedor en el mismo nodo en el que reside el contenedor donde se debe ejecutar el ejecutable de docker exec . En este nodo, este contenedor monta el socket del demonio de la ventana acoplable para poder ejecutar el docker exec localmente.
Para más información, eche un vistazo a: skopos-plugin-swarm-exec

Usando ayudantes de enjambre docker

También hay otro proyecto llamado " docker swarm helpers", que parece ser más o menos una envoltura alrededor de ssh y docker exec .

Referencia: