Docker Swarm - 如何在Swarm集群中平衡已运行的容器?

20

我在AWS上有一个由2个节点组成的Docker Swarm集群。我先停止了这两个实例,然后首先启动了Swarm管理器,接着再启动Worker。在停止实例之前,我有一个运行中的服务,其中4个副本分布在管理器和Worker之间。
当我首先启动Swarm管理器节点时,所有副本容器都在管理器本身上启动,并且没有转移到Worker上。
请告诉我如何进行负载均衡?
当Worker启动时,Swarm管理器不负责执行此操作吗?


你能重启服务吗?在另一个工作人员启动之前,它们可能都被安排在管理器上了。 - avigil
我需要重启Docker服务还是Docker堆栈? - Bukkasamudram
我尝试重新启动Docker服务,然后尝试重新部署堆栈。但是没有成功。 - Bukkasamudram
2
我希望通过手动停止Swarm Manager上的容器,新的容器可以移动到Worker进行负载平衡,但是否有其他方法可以由Swarm Manager自动平衡? - Bukkasamudram
我认为Swarm不会移动已经存在并且正在运行的容器,因为它无法知道这样做是否会对您的应用程序造成干扰。 - avigil
4个回答

50

目前(18.03),如果服务处于默认的“复制模式”,则Swarm不会在启动新节点时移动或替换容器。这是设计上的考虑。如果我要添加一个新节点,我不一定想停止一堆其他容器并在我的新节点上创建新的容器。当Swarm必须(在复制模式下)“移动”副本时,它才会停止容器。

docker service update --force <servicename>将重新平衡满足其要求和约束条件的所有节点上的服务。

进一步建议:与其他容器编排器一样,您需要在节点上提供容量,以处理任何服务副本在故障期间移动的工作负载。你的备用容量应该匹配你计划支持的冗余级别。例如,如果你想同时处理2个节点失败的容量,你需要在所有节点上拥有最低百分比的资源,以便这些工作负载转移到其他节点。


你知道这是否是滚动更新吗?这会导致停机时间吗? - Alec Gerona
2
回答自己的问题:https://docs.docker.com/engine/reference/commandline/service_update/#perform-a-rolling-restart-with-no-parameter-changes - Alec Gerona

5

这是我用来重新平衡的Bash脚本:

#!/usr/bin/env bash

set -e

EXCLUDE_LIST="(_db|portainer|broker|traefik|prune|logspout|NAME)"

for service in $(docker service ls | egrep -v $EXCLUDE_LIST | 
                 awk '{print $2}'); do
  docker service update --force $service
done

3
Swarm在容器创建后不会自动平衡。您可以在所有工作节点启动后进行缩放,它将根据您的配置要求/角色等分配容器。
请参阅:https://github.com/moby/moby/issues/24103

添加新节点存在“被抢”的问题。我们还避免了对健康任务的抢占。重新平衡是随着时间而进行的,而不是杀死正在工作的进程。预占在未来可能会被考虑。

作为解决方法,将服务进行扩展和收缩应该可以重新平衡任务。您也可以触发滚动更新,因为这将重新安排新任务。


1
在 docker-compose.yml 中,您可以定义以下内容:
version: "3"

services:

  app:
    image: repository/user/app:latest
    networks:
      - net
    ports:
      - 80
    deploy:
      restart_policy:
        condition: any
      mode: replicated
      replicas: 5
      placement:
        constraints: [node.role == worker]
      update_config:
        delay: 2s

备注:约束条件为节点角色为worker

使用标志“--replicas”意味着我们不关心它们被放置在哪个节点上,如果我们想要每个节点一个服务,可以使用“--mode=global”。

在Docker 1.13及更高版本中,您可以使用docker服务更新命令的--force或-f标志,强制服务在可用的工作节点之间重新分配其任务。


1
但我想要负载均衡容器,包括管理器。我在我的docker-compose.yml中更新了**constraints: [node.role == worker]**。所有容器都被移动到worker节点。 - Bukkasamudram

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