为什么我们不应该在 Docker Swarm 集群中的多个主机之间进行负载平衡?

为什么我们不应该在 Docker Swarm 集群中的多个主机之间进行负载平衡?

我们在 Swarm 集群中有 3 个主机,并且我们在这个集群中部署了一个 Web 应用程序。该 Web 应用程序在任何时候都只能在 1 个主机上运行。如果一个主机死机,该 Web 应用程序将被转移到另一个主机。

无论您的请求命中哪个主机,Docker 都会负责将您的请求路由到 Web 应用程序。

为了确保我们始终能够访问正常运行的主机,我们考虑使用 Nginx 作为前端。我们将在 Nginx 上创建一个虚拟主机,它将代理对 Docker 群的请求。

对此我们有两种方法。

答:我们只是在主机之间“循环”处理请求。

这是一种简单的方法。当服务发生故障时,我们将使用 Nginx 来移除服务。但是,即使 Nginx 从主机 1 收到 500 错误,也可能是 Web 应用程序从主机 3 返回了该 500 错误。Nginx 会错误地认为主机 1 上的服务发生故障,并移除该主机上的服务。

B. 我们会将所有请求发送给群组领导者。

我们不使用 Nginx 在主机之间进行负载平衡。我们只是将所有请求发送到 Docker Swarm 领导者(通过各种脚本,我们配置 Nginx 来执行此操作)。这样,我们就不会进行“双重”负载平衡(Nginx 和 Docker Swarm),但所有流量都只通过 Docker Swarm 领导者。

一方面,解决方案 A 简单易懂,但在双负载平衡方面也可能会增加复杂性。第二种解决方案可能更复杂,因为它不太标准,但也可能使事情更容易理解。

从纯技术角度来看,我们应该选择哪种方法?

答案1

我认为这是对选项 1 的评论。

我也在研究这个问题,从 Docker Swarm > 1.12 中我所知道的,你所要做的就是创建一个到服务/网站的反向代理。我在概念验证中所做的是:1) 创建两个覆盖网络,一个用于代理网络,它将面向外部,另一个用于我的服务网络,它只用于内部;然后 2) 部署 3 个服务副本,将其附加到服务覆盖和代理覆盖网络 (--network proxy --network my-service)。最后,我建立了一个绑定到我公司别名的 nginx 反向代理,它将接受端口 80 和 443 上的传入连接。

sudo docker service create --name proxy \ 
-p 80:80 \
-p 443:443 \
--network proxy \
--mount type=volume,source=reverse-proxy,target=/etc/nginx/conf.d,volume-driver=azurefile \
--mount type=volume,source=ssl,target=/etc/nginx/ssl,volume-driver=azurefile \
nginx

挂载点就在那里,所以我不必将文件复制到每个主机。此挂载指向 Azure 文件存储帐户,这使得启动更多容器更加易于维护。

反向代理如下所示:

location /my-service/ {
    proxy_read_timeout 900;                
    proxy_pass http://my-service/;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

http://我的服务是 Swarm 内部的 DNS 记录,它始终指向托管我服务的 VIP,无论是 1 个节点还是 1,000 个节点。据我所知,您部署的每项服务都有自己的子网范围,主节点会跟踪容器的运行位置并为您处理路由。

目前,我们有多个指向不同主机 IP 的 A 记录,并使用循环调度,但我们可能会将其从 Windows Server 管理的 DNS 移至 Azure Traffic Manager,以获得更好的控制。

相关内容