初始化群模式:
The method documentationConfiguration(RestDocumentation) in the type MockMvcRestDocumentation is not applicable for the arguments (JUnitRestDocumentation)
加入第二个节点:
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:
要向此群添加管理员,请运行“docker swarm join-token manager”并按照说明操作。
docker swarm join \
--token SWMTKN-1-4xvddif3wf8tpzcg23tem3zlncth8460srbm7qtyx5qk3ton55-6g05kuek1jhs170d8fub83vs5 \
172.31.44.207:2377
如上所示,redis拥有它的复制品,而miniconda 不似乎复制。
我通常登录miniconda容器来输入这些命令:
# 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
问题是/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
命令不适用于swarm模式。
答案 0 :(得分:26)
有一个班轮可以访问localhost的相应服务实例:
docker exec -ti stack_myservice.1.$(docker service ps -f 'name=stack_myservice.1' stack_myservice -q --no-trunc | head -n1) /bin/bash
它在PowerShell上测试,但bash应该是相同的。 oneliner访问第一个实例,但替换' 1'使用您想要在两个地方访问的实例的编号来获取另一个实例。
更复杂的例子是分布式案例:
#! /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
此脚本可以在以后用作:
swarm_bash stack_task 1
它只是在所需节点上执行bash。
答案 1 :(得分:16)
编辑2017-10-06:
现在,您可以使用--attachable
标志创建覆盖网络,以使任何容器都能加入网络。这是一个很棒的功能,因为它具有很大的灵活性。
E.g。
$ 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>
....
你是对的,你无法在docker swarm模式服务上运行docker exec
。但您仍然可以找到运行容器的节点,然后直接在容器上运行exec。 E.g。
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
在您的情况下,您首先要了解,为什么服务无法获得miniconda容器。也许正在运行docker service ps miniconda3
会显示一些有用的错误消息..?
答案 2 :(得分:9)
使用Docker API
目前,Docker没有为此提供docker service exec
或docker stack exec
等API。但就此而言,已经存在两个处理此功能的问题:
(关于第一个问题,对我来说,并不是直接明确这个问题涉及这种功能。但Exec for Swarm已关闭并标记为Docker service exec问题的副本。)
通过HTTP使用Docker守护程序
如BMitch run docker exec from swarm manager所述,您还可以将Docker守护程序配置为使用HTTP,而不是连接到每个节点而不需要ssh。但是你应该使用已经集成到Docker中的TLS authentication来保护它。之后你就可以像这样执行docker exec
:
docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem \
-H=$HOST:2376 exec $containerId $cmd
使用skopos-plugin-swarm-exec
存在一个github项目声称可以解决问题并提供绑定docker守护程序所需的功能:
docker run -v /var/run/docker.sock:/var/run/docker.sock \
datagridsys/skopos-plugin-swarm-exec \
task-exec <taskID> <command> [<arguments>...]
据我所知,这可以通过在容器所在的同一节点创建另一个容器来实现docker exec
应该执行的位置。在此节点上,此容器安装docker守护程序套接字,以便能够在本地执行docker exec
有关更多信息,请查看:skopos-plugin-swarm-exec
使用docker swarm helpers
还有一个名为docker swarm helpers的项目似乎或多或少是ssh
和docker exec
的包装。
参考:
答案 3 :(得分:6)
您可以通过过滤容器名称来执行命令,而无需仅通过服务名称就传递整个swarm容器哈希。像这样:
TextInputEditText
答案 4 :(得分:4)
您可以跳转到Swarm节点并列出使用以下命令运行的docker容器:
docker container ls
这将为您提供类似于以下格式的容器名称:containername.1.q5k89uctyx27zmntkcfooh68f
然后,您可以使用常规exec选项在其上运行命令:
docker container exec -it containername.1.q5k89uctyx27zmntkcfooh68f bash
答案 5 :(得分:3)
我通过服务名称在docker swarm中将脚本写入了exec命令。例如,它可以在cron中使用。您也可以使用bash管道并将所有参数传递给docker exec
命令。但是仅在启动服务的同一节点上有效。我希望它可以帮助某人
#!/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;
使用示例:
./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
答案 6 :(得分:3)
为我们的docker swarm集群创建了一个小脚本。
该脚本需要3个参数。首先是要连接的服务,其次要运行的任务可以是/bin/bash
或要运行的任何其他进程。第三是可选的,它将为bash或sh填充-c选项
-n是强制将其连接到节点的可选
它检索运行服务的节点并运行命令。
#! /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"
注释:这要求docker节点通过在工作节点上的端口2375上暴露docker来接受tcp连接
答案 7 :(得分:1)
对于具有多个副本并且只想在其中任何一个中运行命令的用户,这是另一个快捷方式:
docker exec -it $(docker ps -q -f name=SERVICE_NAME | head -1) bash
答案 8 :(得分:0)
请参阅附录2 ...
在节点my_db
上输入数据库master
的oneliner示例:
DB_NODE_ID=master && docker exec -it $(docker ps -q -f name=$DB_NODE_ID) mysql my_db
如果要配置,请说max_connections
:
DB_NODE_ID=master && $(docker exec -it $(docker ps -q -f name=$DB_NODE_ID) mysql -e "SET GLOBAL max_connections = 1000") && docker exec -it $(docker ps -q -f name=$DB_NODE_ID) mysql my_db
这种方法允许通过相应地设置DB_NODE_ID
变量来输入所有数据库节点(例如从属)。
从站s2
的示例:
DB_NODE_ID=s2 && docker exec -it $(docker ps -q -f name=$DB_NODE_ID) mysql my_db
或
DB_NODE_ID=s2 && $(docker exec -it $(docker ps -q -f name=$DB_NODE_ID) mysql -e "SET GLOBAL max_connections = 1000") && docker exec -it $(docker ps -q -f name=$DB_NODE_ID) mysql my_db
将其放入“数据/命令”下的KiTTY
/ PuTTY
的{{1}}或master
配置中,就可以了。
作为附录:
非虫群模式的旧版本读起来很简单
s2
resp。
docker exec -it master mysql my_db
附录2:
如示例所示,术语DB_ID=master && $(docker exec -it $DB_ID mysql -e "SET GLOBAL max_connections = 1000") && docker exec -it $DB_ID mysql tmp
在某些情况下可能返回错误的值。
以下方法可以正常工作:
docker ps -q -f name=$DB_NODE_ID
您可以相应地替换上面的示例。
附录3:
嗯,这些术语看起来很糟糕,而且键入起来肯定很麻烦,因此您可能希望简化工作。在Linux上,每个人都知道如何执行此操作。在Windws上,您可能要使用AHK。
这是我使用的AHK术语:
docker ps -a | grep "_$DB_NODE_ID." | awk '{print $1}'
因此,当我输入:*:ii::DB_NODE_ID=$(docker ps -a | grep "_." | awk '{{}print $1{}}') && docker exec -it $id ash{Left 49}
时(这很简单),我将光标放在适当的位置就可以得到所需的术语,而只需填写容器名称。
答案 9 :(得分:0)
我发现docker exec
进入运行服务$SWARM_MANAGER_HOST
(例如$SERVICE_NAME
)的群集节点(群集管理器位于mystack_myservice
)中的最简单命令如下:
SERVICE_JSON=$(ssh $SWARM_MANAGER_HOST "docker service ps $SERVICE_NAME --no-trunc --format '{{ json . }}' -f desired-state=running")
ssh -t $(echo $SERVICE_JSON | jq -r '.Node') "docker exec -it $(echo $SERVICE_JSON | jq -r '.Name').$(echo $SERVICE_JSON | jq -r '.ID') bash"
这断言您具有对$SWARM_MANAGER_HOST
的ssh访问权限,以及当前正在运行服务任务的swarm节点。
这也断言您已经安装了jq
(apt install jq
),但是如果您不能安装或不想安装它并且安装了python,则可以创建以下别名(基于在this answer上)
alias jq="python3 -c 'import sys, json; print(json.load(sys.stdin)[sys.argv[2].partition(\".\")[-1]])'"
答案 10 :(得分:0)
我编辑了上面添加的脚本 Brian van Rooijen。因为声望太低,无法添加
#! /bin/bash
set -e
service=${1}
shift
task="$*"
echo $task
serviceID=$(docker service ps -f name=$service -f desired-state=running $service -q --no-trunc |head -n1)
node=$(docker service ps -f name=$service -f desired-state=running $service --format="{{.Node}}"| head -n1 )
serviceName=$(docker service ps -f name=$service -f desired-state=running $service --format="{{.Name}}"| head -n1 )
docker -H $node exec -it $serviceName"."$serviceID $task
我遇到了硬编码 .1 不存在容器的问题。在执行中。
答案 11 :(得分:-1)
看看我的解决方案:https://github.com/binbrayer/swarmServiceExec。
这种方法基于Docker Machines。我还创建了脚本的原型,以异步方式调用容器,因此可以同时调用容器。