在不同节点上使用Docker Swarm副本

12
我是一名有用的助手,可以翻译文本。
我正在使用docker-compose文件版本3和其部署密钥来运行一个swarm(docker版本1.13),我希望复制一个服务以使其能够抵御单个节点故障。
然而,当我添加一个像这样的部署部分时:
deploy:
    replicas: 2

在我的四节点集群中,有时会出现两个副本都被安排在同一个节点上的情况。我缺少一种约束条件,可以将这两个实例安排在不同的节点上。
我知道有一种global模式可以使用,但这将在每个节点上运行一个实例,在我的情况下是四个实例,而不仅仅是两个。
是否有一种简单的通用方式来指定这种约束条件,而不必诉诸于结合global和标签以使其他实例远离的方法?
编辑:再试一次后,我发现容器被安排在不同的节点上了。我开始想知道是否已经设置了'node.hostname==X'约束条件。
编辑2:在另一个服务更新之后 - 没有任何放置约束条件 - 该服务再次被安排在同一节点上(如ManoMarks Visualizer所示)。

enter image description here

3个回答

17

在扩展VonC的答案时,正如您的示例中所使用的是compose文件而不是cli,因此您可以添加max_replicas_per_node: 1,如下所示:

version: '3.8'
...
yourservice:
    deploy:
          replicas: 2
          placement:
            max_replicas_per_node: 1

这里关键是compose模式版本3.8,因为在3.8以下版本不支持max_replicas_per_node。

这是在https://github.com/docker/cli/pull/1410中添加的。


3

docker/cli PR 1612 看起来解决了问题26259,并已在docker 19.03中发布。

Added new switch --replicas-max-per-node switch to docker service

How to verify it

Create two services and specify --replicas-max-per-node one of them:

docker service create --detach=true --name web1 --replicas 2 nginx
docker service create --detach=true --name web2 --replicas 2 --replicas-max-per-node 1 nginx

See difference on command outputs:

$ docker service ls
ID                  NAME                MODE                REPLICAS               IMAGE               PORTS
0inbv7q148nn        web1                replicated          2/2                    nginx:latest        
9kry59rk4ecr        web2                replicated          1/2 (max 1 per node)   nginx:latest

$ docker service ps --no-trunc web2
ID                          NAME                IMAGE                                                                                  NODE                DESIRED STATE       CURRENT STATE            ERROR                                                     PORTS
bf90bhy72o2ry2pj50xh24cfp   web2.1              nginx:latest@sha256:b543f6d0983fbc25b9874e22f4fe257a567111da96fd1d8f1b44315f1236398c   limint              Running             Running 34 seconds ago                                                             
xedop9dwtilok0r56w4g7h5jm   web2.2              nginx:latest@sha256:b543f6d0983fbc25b9874e22f4fe257a567111da96fd1d8f1b44315f1236398c                       Running             Pending 35 seconds ago   "no suitable node (max replicas per node limit exceed)"   
错误信息将会是:
no suitable node (max replicas per node limit exceed)

来自Sebastiaan van Stijn的示例:

Create a service with max 2 replicas:

docker service create --replicas=2 --replicas-max-per-node=2 --name test nginx:alpine
docker service inspect --format '{{.Spec.TaskTemplate.Placement.MaxReplicas}}' test
2

Update the service (max replicas should keep its value)

docker service update --replicas=1 test
docker service inspect --format '{{.Spec.TaskTemplate.Placement.MaxReplicas}}' test
2

Update the max replicas to 1:

docker service update --replicas-max-per-node=1 test
docker service inspect --format '{{.Spec.TaskTemplate.Placement.MaxReplicas}}' test
1

And reset to 0:

docker service update --replicas-max-per-node=0 test
docker service inspect --format '{{.Spec.TaskTemplate.Placement.MaxReplicas}}' test
0

1

抱歉,我应该提到 - 我使用的是1.13版本。 - sas
感谢提供那个问题的链接 - 看起来它仍然没有解决。从那个问题中链接的是一个解决方法,建议添加一个虚拟主机端口:https://github.com/docker/docker/issues/26259#issuecomment-277716832 我猜那会起作用,但感觉有点“hacky”。 - sas
经过再次尝试,我发现容器这次被安排在不同的节点上。我开始怀疑是否之前设置了“node.hostname == X”的限制条件。可能是个无关紧要的问题! - sas
2
我正在使用 Docker 18.03,仍然遇到问题。而且我没有针对该特定服务的任何放置约束。我可能会尝试虚拟主机端口的 hack。 - tsauerwein

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接