多个Docker容器节点组网实现负载均衡的方案
admin
2021-12-19多个Docker容器节点组网实现负载均衡的方案
目录导航:
当前我们的MVC 容器被创建了,但是都没有映射端口,这意味着它们只能通过Docker的虚拟网络进行访问,我们无法通过主机的操作系统访问。
这个时候就需要我们创建一个负载均衡工具了。它可以通过在主机的操作系统上单一的端口上接收HPPT请求然后映射到frontend
网络,分发到MVC的各个容器中。
谈到负载均衡的时候,有很多选择,而选择什么工具通常与基础设施搭建有关,无所谓对错,我们只需要将应用程序部署到这些负载均衡器即可。
例如,如果您正在部署您的应用程序到企业网络中的时候,你很可能会发现已经安装了负载均衡器,并且运行的很正常。
这里,我们选择HAProxy作为我们的负载均衡工具,它是Docker官方团队在使用的,同时国内知乎等公司也在使用。
提示:HAProxy只支持在Linux容器中使用,不支持Windows容器,如果您使用的是 Windows容器,可以采用Nginx。
现在我们在项目YoYoMooc.ExampleApp
的根目录下创建一个haproxy.cfg
的文件。
defaults
timeout connect 5000
timeout client 50000
timeout server 50000
frontend localnodes
bind *:80
mode http
default_backend mvc
backend mvc
mode http
balance roundrobin
server mvc1 productapp1:80
server mvc2 productapp2:80
server mvc3 productapp3:80
此配置告诉HAProxy接收从主机操作系统上映射出来的80端口,然后 将其分发到三个不同的MVC容器中,而这三个容器通过它们的容器名称进行识别,这是利用了Docker NDS的功能。
HTTP请求将依次分发到每个MVC容器,这使得显示所有的MVC容器和测试负载均衡都变得更加容易和方便。
需要注意的是,当前这个文件的编码格式为utf-8
行尾的结尾为LF
,如果不正确,否则HAProxy
进行在读取配置信息的时候就会报错。
关于负载平衡和会话(Session)的匹配策略介绍
当前HAproxy的负载均衡配置策略为平衡策略,这意味着每次向服务器发送请求的时候都会依次访问Docker的内部容器(服务器)。
但是这样会有一个问题,如果应用程序包含了会话数据(Session),则必须确保负载平衡策略适合您的会话存储模型。 如果每个应用程序容器维护自己的Session信息的话,您必须配置负载均衡器,以便后续客户端的请求与之前的服务器是相同的。
但是这可能导致你的HTTP请求不是均匀分布的,但可以确保session会像预期的那样工作。
那么还有一种方案叫做循环负载均衡方案,这样您存储的Session数据就可以从任意的应用程序访问该容器了。
您如果使用HAProxy,那么可以在前往官方网站
www.haproxy.org
,查询它的配置信息。 我们这里不做太多说明,毕竟这个是Docker课程。
为了使负载均衡器的配置文件可以正常工作,我将使用Docker volumes
功能,容器的文件系统会提供一个文件夹来允许主机操作系统中的配置文件复制到指定目录中,这样我们就无须配置一个专用的Docker 卷Volume了。
对于Windows和macOS的系统,需要进行一些配置(对于LInux用户来说,则不需要配置),我没有Macos的设备,所以请参考Windows的配置。
操作其实很简单,Windows用户,右击任务栏中的Docker
图标,然后在弹出对话框中选择 "settings
"。然后在弹出的settings
对话框中,选择File Sharing
选项卡,然后在资源中选择共享盘符,如果所示。
创建和启动负载均衡器容器
现在我们需要创建负载均衡器HAProxy
容器以连接到frontend
的Docker网络中,并配置且监听来自主机操作系统的Http请求映射到容器中的80端口。
打开项目YoYoMooc.ExampleApp
导航到根目录下,然后输入以下命令:
docker run -d --name loadbalancer --network frontend -v "$(pwd)/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg" -p 3000:80 haproxy:1.7.0
命令说明:
-v参数告诉 Docker容器
loadbalancer
你需要挂载的haproxy.cfg
配置文件,是将YoYoMooc.ExampleApp
文件夹的根目录文件复制到了/usr/local/etc/haproxy
目录中。这对于创建需要配置文件的容器来说,是一个很有用的功能。我们会在后面的课程中经常使用它。--network参数 在将
loadbalancer
容器与frontend
网络连接起来,这样它就可以使用与 MVC 容器进行通信。-p 将主机操作系统上的端口 3000 映射至容器中的端口80,这样负载平衡器就可以接收来自外部世界的请求。
注意:如果你在容器启动时看到错误,那么很有可能是你忘记了修改字符haproxy.cfg文件的编码,即结尾形式为
LF
当负载均衡器启动后,打开浏览器标签页并请求URL http://localhost:3000
,刷新该页面,你会看到负载平衡器在MVC应用程序之间分配请求。
每个MVC容器被第一次请求的时候,可能需要一秒钟的时间进行刷新,因为应用程序启动时,需要进行初始化,但随后的请求便会被立即效应。
现在我们来看看当前用了多少技术?分别是五个容器、两个虚拟网络以及一个主机操作系统上的端口映射,它的组成形式与传统的多应用程序组成 是类似的,区别只是所有的容器均运行在一台主机服务器上,并且他们是相互隔离的。
从上图可以得知,数据库容器只与后端(backend)网络连接。MVC应用容器是连接到frontend
和backend
网络;它们通过frontend
网络来接收HTTP请求,并通过backend
网络进行SQL查询。负载均衡器容器只连接到frontend
网络,并有一个映射到主机操作系统的端口;
Docker基础小结
截止这一章,我介绍了Docker卷和Docker网络的功能,这些功能可以让更多的容器进行复杂组合,然后实现一个复杂的应用。我们学习了如何用卷来存储容器之外的数据文件,以及使用Entity Framework CoRe 来创建数据库的仓储模式。 还介绍了软件定义的网络即虚拟网络是什么,以及如何创建一个虚拟网络,并使用它们为应用程序搭建一套网络结构,这样我们所有组件都存在Docker容器中,而不需要专用的硬件服务器。
在后面的章节中,我们将学习Docker-compose,向您展示如何创建复杂的应用程序容器,而不必单独创建和管理容器、卷和网络。