Initialiser le mode essaim:
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:
Rejoignez le deuxième noeud:
docker swarm join \
--token SWMTKN-1-4xvddif3wf8tpzcg23tem3zlncth8460srbm7qtyx5qk3ton55-6g05kuek1jhs170d8fub83vs5 \
172.31.44.207:2377
Pour ajouter un gestionnaire à cet essaim, exécutez "Gestionnaire des jetons de jointure de Docker Swarm" et suivez les instructions.
# 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
Comme indiqué ci-dessus, redis a sa réplique tandis que miniconda fait pas semble être répliqué.
Je me connecte habituellement au conteneur miniconda pour taper ces commandes:
/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
Le problème est que docker exec -it XXX bash
La commande ne fonctionne pas avec le mode Essaim.
Il existe une seule ligne pour accéder à l'instance correspondante du service pour localhost:
docker exec -ti stack_myservice.1.$(docker service ps -f 'name=stack_myservice.1' stack_myservice -q --no-trunc | head -n1) /bin/bash
Il est testé sur PowerShell, mais bash devrait être identique. L'un des doublons accède à la première instance, mais remplace "1" par le numéro de l'instance à laquelle vous souhaitez accéder à deux endroits pour en obtenir une autre.
Un exemple plus complexe concerne le cas distribué:
#! /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
Ce script pourrait être utilisé plus tard comme:
swarm_bash stack_task 1
Il suffit d'exécuter bash sur le noeud requis.
EDIT 2017-10-06:
De nos jours, vous pouvez créer le réseau de superposition avec --attachable
drapeau pour permettre à tout conteneur de rejoindre le réseau. C'est une fonctionnalité intéressante car elle permet beaucoup de flexibilité.
Par exemple.
$ 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>
....
Vous avez raison, vous ne pouvez pas courir docker exec
sur le service en mode Docker Swarm. Mais vous pouvez toujours savoir quel nœud exécute le conteneur, puis exécuter directement exec sur le conteneur. Par exemple.
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
Dans votre cas, vous devez d’abord comprendre pourquoi le service ne peut pas obtenir le conteneur miniconda. Peut-être que courir docker service ps miniconda3
montre quelques messages d'erreur utiles ..?
Vous pouvez exécuter des commandes en filtrant le nom du conteneur sans avoir besoin de transmettre l'intégralité du hachage du conteneur Swarm, uniquement par le nom du service. Comme ça:
docker exec $(docker ps -q -f name=servicename) ls
Utilisation de l'API Docker
À l'heure actuelle, Docker ne fournit pas une API comme docker service exec
ou docker stack exec
pour ça. Mais à ce propos, il existe déjà deux problèmes liés à cette fonctionnalité:
(En ce qui concerne le premier problème, il n’est pas clair pour moi que ce problème concerne exactement ce type de fonctionnalité. Mais Exec for Swarm a été fermé et marqué comme une copie du service service Docker exec issue.)
Utilisation du démon Docker sur HTTP
Comme mentionné par BMitch sur exécutez docker exec depuis swarm manager , vous pouvez également configurer le démon Docker pour qu'il utilise HTTP et se connecter à chaque nœud sans avoir besoin de ssh. Mais vous devriez protéger cela en utilisant authentification TLS qui est déjà intégré à Docker. Ensuite, vous pourrez exécuter le docker exec
comme ça:
docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem \
-H=$Host:2376 exec $containerId $cmd
Utilisation de skopos-plugin-swarm-exec
Il existe un projet github qui prétend résoudre le problème et fournit la fonctionnalité souhaitée liant le démon docker:
docker run -v /var/run/docker.sock:/var/run/docker.sock \
datagridsys/skopos-plugin-swarm-exec \
task-exec <taskID> <command> [<arguments>...]
Autant que je sache, cela fonctionne en créant un autre conteneur sur le même nœud que celui-ci où réside le docker exec
devrait être exécuté le. Sur ce nœud, ce conteneur monte le socket du docker daemon pour pouvoir exécuter docker exec
_ localement.
Pour plus d'informations, consultez: skopos-plugin-swarm-exec
Utilisation des aides de Docker Swarm
Il y a aussi un autre projet appelé docker swarm helpers qui semble être plus ou moins un wrapper autour de ssh
et docker exec
.
Référence:
Vous pouvez sauter dans un nœud Swarm et répertorier les conteneurs Docker exécutés à l'aide de:
docker container ls
Cela vous donnera le nom du conteneur dans un format similaire à: Containername.1.q5k89uctyx27zmntkcfooh68f
Vous pouvez ensuite utiliser l’option normale exec pour y exécuter des commandes:
docker container exec -it containername.1.q5k89uctyx27zmntkcfooh68f bash
créé un petit script pour notre cluster docker swarm. ce script prend 3 paramètres. le premier est le service auquel vous voulez vous connecter, puis la tâche que vous voulez exécuter peut être /bin/bash
ou tout autre processus que vous souhaitez exécuter. La troisième est optionnelle et remplira l'option -c pour bash ou sh
-n est facultatif pour le forcer à se connecter à un nœud
il récupère le nœud qui exécute le service et exécute la commande.
#! /bin/bash
set -e
task=${1}
service=$2
bash=$3
serviceID=$(Sudo docker service ps -f name=$service -f desired-state=running $service -q --no-trunc |head -n1)
node=$(Sudo docker service ps -f name=$service -f desired-state=running $service --format="{{.Node}}"| head -n1 )
Sudo docker -H $node exec -it $service".1."$serviceID $bash -c "$task"
note: les nœuds du menu fixe doivent accepter les connexions TCP en exposant le menu fixe sur le port 2375 sur les nœuds de travail.
J'ai écrit le script pour exécuter la commande dans Docker swarm par nom de service. Par exemple, il peut être utilisé dans cron. Vous pouvez aussi utiliser les pipelines bash et passer tous les paramètres à docker exec
commande. Mais ne fonctionne que sur le même nœud où le service a démarré. Je souhaite que cela puisse aider quelqu'un
#!/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;
Exemple d'utilisation:
./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