如何在不同节点上限制容器 运行 使用 docker 堆栈部署

how to limit container running on different node use docker stack deploy

我在 docker swarm 中有三个节点(所有节点都是管理器) 我想运行在这三个节点上建立zookeeper集群

我的docker-编写文件

version: '3.8'
services:
  zookeeper1:
    image: 'bitnami/zookeeper:latest'
    hostname: "zookeeper-1"
    ports:
      - '2181'
      - '2888'
      - '3888'
    volumes:
      - "zookeeper-1:/opt/bitnami/zookeeper/conf"
    environment:
      - ZOO_SERVER_ID=1
      - ZOO_SERVERS=0.0.0.0:2888:3888,zookeeper-2:2888:3888,zookeeper-3:2888:3888
      - ALLOW_ANONYMOUS_LOGIN=yes
    networks:
      - network_test
  zookeeper2:
    image: 'bitnami/zookeeper:latest'
    hostname: "zookeeper-2"
    ports:
      - '2181'
      - '2888'
      - '3888'
    volumes:
      - "zookeeper-2:/opt/bitnami/zookeeper/conf"
    environment:
      - ZOO_SERVER_ID=2
      - ZOO_SERVERS=zookeeper-1:2888:3888,0.0.0.0:2888:3888,zookeeper-3:2888:3888
      - ALLOW_ANONYMOUS_LOGIN=yes
    networks:
      - network_test
  zookeeper3:
    image: 'bitnami/zookeeper:latest'
    hostname: "zookeeper-3"
    ports:
      - '2181'
      - '2888'
      - '3888'
    volumes:
      - "zookeeper-3:/opt/bitnami/zookeeper/conf"
    environment:
      - ZOO_SERVER_ID=3
      - ZOO_SERVERS=zookeeper-1:2888:3888,zookeeper-2:2888:3888,0.0.0.0:2888:3888
      - ALLOW_ANONYMOUS_LOGIN=yes
    networks:
      - network_test

我使用 docker stack deploy to 运行,我的期望是每个 zookeeper 将 运行 在不同的节点上,但有时一个节点会启动两个 zookeeper conatiners

docker栈部署可以有这个功能吗??

谢谢

要在 Docker Swarm 集群中的每个可用节点上启动服务,您需要 运行 它处于 global 模式。

但是,在您的情况下,由于每个 Zookeeper 的特定卷,您可以使用 placement constraints 来控制可以分配服务的节点。因此,您可以将以下部分添加到每个 Zookeeper 服务,这将允许每个实例 运行 在不同的节点上:

services:
  ...
  zookeeper-1:
   ...
   deploy:
      placement:
        constraints:
          - node.hostname==node1

如果将 zookeepers 合并到一个服务中,则可以使用 max_replicas_per_node

像这样:

version: "3.9"

volumes:
  zookeeper:
    name: '{{index .Service.Labels "com.docker.stack.namespace"}}_zookeeper-{{.Task.Slot}}'

services:
  zookeeper:
    image: zookeeper:latest
    hostname: zoo{{.Task.Slot}}
    volumes:
      - zookeeper:/conf
    environment:
      ZOO_MY_ID: '{{.Task.Slot}}'
      ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
      ALLOW_ANONYMOUS_LOGIN: 'yes'
    ports:
    - 2181:2181
    deploy:
      replicas: 3
      placement:
        max_replicas_per_node: 1
        constraints:
        - node.role==worker

为了演示目的,我使用了 docker 官方图像,而不是 bitnami 图像。

服务模板用于为每个副本分配一个“zoo1”...“zoo3”形式的主机名,这样就可以使用 1 个服务和 3 个副本,而不是 3 个服务。这也意味着端口 2181 仅发布,dockers 服务网格将自动将 zookeeper 客户端负载平衡到 zookeeper 实例。

由于原始问题包括每个服务的唯一卷,服务模板参数再次用于分配形式为“stack_zookeeper_1”的卷名称。但是,这是一个配置卷,可能需要共享? 此外,当 zookeeper 任务副本在 swarm 节点之间迁移时,如果使用默认卷驱动程序(本地)而不是 swarm 感知驱动程序,则卷将在每个 swarm 节点上创建为空。

最后,replicasmax_replicas_per_node保证3个zoo任务启动,不共享节点。