Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

execute a command within docker swarm service

Tags:

docker-swarm

  1. Initialize swarm mode:

    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. Join the second node:

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

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the 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 

As shown above, redis has it's replica while miniconda does not seem to be replicated.

I do usually log-in to miniconda container to type these commands:

/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 

The problem is that docker exec -it XXX bash command does not work with swarm mode.

like image 482
shantanuo Avatar asked Sep 07 '16 06:09

shantanuo


People also ask

Which port is used for docker swarm cluster management?

TCP port 2377 . This port is used for communication between the nodes of a Docker Swarm or cluster.

Which command will run a global service in docker Swarm?

The command we will be executing is the docker command with the swarm init options. With the above command, in addition to the swarm init , we also specified the --advertise-addr flag with a value of 10.0. 0.1 . This is the IP that the Swarm node manager will use to advertise the Swarm Cluster Service.

How do I run a command in a docker container?

Running Commands in an Alternate Directory in a Docker Container. To run a command in a certain directory of your container, use the --workdir flag to specify the directory: docker exec --workdir /tmp container-name pwd.

How do I execute a docker swarm service?

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions. As shown above, redis has it's replica while miniconda does not seem to be replicated. The problem is that docker exec -it XXX bash command does not work with swarm mode.


2 Answers

You can execute commands by filtering container name without needing to pass the entire swarm container hash, just by the service name. Like this:

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

like image 134
isca Avatar answered Oct 28 '22 21:10

isca


There is one liner for accessing corresponding instance of the service for localhost:

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

It is tested on PowerShell, but bash should be the same. The oneliner accesses the first instance, but replace '1' with the number of the instance you want to access in two places to get other one.

More complex example is for distributed case:

#! /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 

This script could be used later as:

swarm_bash stack_task 1 

It just execute bash on required node.

like image 37
user1936595 Avatar answered Oct 28 '22 22:10

user1936595