今年9月,我在奥斯汀举行的nginx.conf 2016大会上做了一个演讲,主题是在Docker Swarm集群中使用NGINX和NGINX Plus。本文将介绍如何结合Docker 1.12中引入的功能,使用NGINX和NGINX Plus为Docker Swarm提供负载均衡。我在nginx.conf演示中使用的所有文件(以及更多文件)均已发布在GitHub上,供您试用。
概述
Docker 1.12版于2016年7月下旬发布,集成了Docker Engine和Swarm,并新增了一些编排功能,从而构建出一个类似Kubernetes等其他容器平台的平台。在Docker 1.12中,Swarm Mode可将一组Docker主机组合成一个swarm,提供容错、自修复的去中心化架构。新平台还简化了Swarm集群的设置,使用密钥保护所有节点,并通过TLS加密节点之间的所有通信。
与此同时,Docker API也进行了扩展,能够识别服务。服务是使用同一镜像的一组容器(类似于Docker Compose中的服务,但功能更多)。您可以创建和扩缩服务、执行滚动更新、创建运行状况检查等。该API内置DNS服务发现和负载均衡功能,还可以设置集群范围的覆盖网络。
Docker Swarm负载均衡拓扑
在本次讨论和演示中,我设置了3个Swarm节点,包括1个管理节点和2个工作节点。Swarm命令在管理节点上运行。Swarm负责所有节点上的调度、DNS服务发现、扩缩容和容器负载均衡(图中以小方框表示)。

为实现集群内各容器之间的专用网络通信,可将容器连接到多个覆盖集群中所有节点的内部覆盖网络。容器可通过Swarm负载均衡器向集群外部公开。

Docker Swarm负载均衡器在每个节点上运行,可在集群中任意主机的任意容器之间对请求进行负载均衡。在未部署NGINX或NGINX Plus的Swarm环境中,Swarm负载均衡器既处理入站客户端请求(图3中的绿色箭头),也处理内部服务间请求(红色箭头)。

既然Swarm已包含负载均衡功能,为什么还需要另一个负载均衡器?原因之一是,Swarm负载均衡器只是一个基本的第4层(TCP)负载均衡器。许多应用还需要其他功能,例如:
- SSL/TLS终止
- 基于内容的路由(例如,根据URL或标头进行路由)
- 访问控制和授权
- 重写和重定向
此外,您可能已经具备负载均衡器的使用经验。将其与 Swarm 配合使用,可以继续利用现有的工具和知识。
使用NGINX Open Source和NGINX Plus
NGINX Open Source和NGINX Plus是两款负载均衡器,可提供Swarm原生负载均衡器所缺少的应用关键功能。
使用 NGINX Open Source
NGINX Open Source不仅提供前述功能(SSL/TLS终止等),还包括:
- 可选择多种负载均衡算法
- 支持更多协议,例如HTTP/2和WebSocket
- 可配置的日志记录
- 流量限制,包括请求速率、带宽和连接数
- 使用Lua、Perl和JavaScript编写脚本,以支持高级用例(JavaScript使用nginScript动态模块[编辑注:现称为NGINX JavaScript动态模块])
- 安全功能,例如允许列表和拒绝列表
使用NGINX Open Source最简单的方法是将其作为服务部署,并使用一个或多个容器。NGINX服务所需的端口会在集群上公开,Swarm负载均衡器通过这些端口将请求分发到NGINX容器。

在本示例中,NGINX提供的服务是SSL/TLS终止。为说明其工作原理,我们在集群中部署后端服务A,并将其扩展为3个容器(如图5所示,其中一个节点上有2个实例,另一个节点上有1个实例)。Swarm为服务A分配一个虚拟IP地址(VIP),供其在集群内部使用。我们在NGINX配置中为服务A设置上游组时使用此VIP,而不是逐一列出各容器的IP地址。这样,无需更改NGINX配置即可扩展服务A。
如图5所示,当客户端向第一个Swarm节点发出访问服务A的请求时,该节点上的Swarm负载均衡器会将请求路由到NGINX。NGINX处理该请求(在本例中执行SSL/TLS解密),并将其路由到服务A的VIP。Swarm负载均衡器随后将此时已解密的请求路由到任一Swarm节点上服务A的某个容器。

可以让NGINX直接对发往后端容器的请求进行负载均衡,并处理内部服务间请求,但这需要采用更复杂的解决方案:每次扩缩服务A时,都必须更改并重新加载NGINX配置。后文将介绍如何使用NGINX Plus轻松实现这一点。
使用NGINX Plus
NGINX Plus提供的部分附加功能包括:
- 主动应用运行状况检查:NGINX Plus持续检查后端节点,确保其运行正常并正确响应,同时从负载均衡轮询中移除运行状况异常的节点。
- 会话持久性,也称为“粘性会话”,适用于需要将客户端请求持续发送到同一后端的应用。需要将后端服务器下线时,NGINX Plus支持会话排空,避免影响仍有活动会话的客户端。
- 动态重新配置:此功能支持扩展或缩减后端,无需更改并重新加载NGINX配置。在使用Swarm等微服务平台进行服务发现时,此功能尤其有用,也是支持NGINX Plus与这些平台充分集成的关键功能之一。动态重新配置有两种方法:一种是通过API将更改推送到NGINX Plus;另一种是使用DNS,NGINX Plus会持续检查与域名关联的节点数量是否发生变化。本NGINX Plus演示采用后一种方法,与Swarm内置的服务发现功能集成。
- 实时活动监控:提供一个API,用于从NGINX Plus获取丰富的指标;还提供基于该API构建的Web仪表板,可用于查看指标,以及添加、删除和更改后端服务器。
在上文所述的NGINX Open Source配置中,Swarm负载均衡器既将外部请求分发到后端容器,也处理这些容器之间的服务间请求。NGINX负责SSL/TLS卸载。
使用NGINX Plus时,外部客户端发出的请求会先到达Swarm负载均衡器,但实际将请求负载均衡到后端容器的是NGINX Plus(图6)。让客户端请求先到达Swarm负载均衡器,可以轻松实现NGINX Plus的高可用性。

同样,Swarm负载均衡器接收服务间请求,但实际由NGINX Plus将这些请求分发到各项服务(图7)。

演示
为了举例说明在使用和不使用NGINX的情况下,如何使用Swarm实现Docker负载均衡,我创建了三个演示。演示所需的全部文件均可在GitHub上获取,并附有详细说明。这三个演示分别是:
Docker Swarm负载均衡
此示例演示了在不使用NGINX或NGINX Plus的情况下,如何通过Docker Swarm对发送到简单Web应用后端的请求进行负载均衡。
使用NGINX Open Source实现Docker Swarm负载均衡
此演示添加了NGINX Open Source,为外部请求提供SSL/TLS卸载。Swarm负载均衡器将请求分发到与上一演示相同的简单Web应用后端,并处理内部服务间请求。
使用NGINX Plus实现Docker Swarm负载均衡
此演示分为两部分。第一部分使用NGINX Plus。除了执行SSL/TLS卸载外,NGINX Plus还会将请求直接负载均衡到后端容器,并处理内部服务间请求。它与Swarm服务发现集成,使用动态DNS频繁地重新解析与后端关联的域名。NGINX Plus对两个后端服务进行负载均衡,分别是Service1和Service2。此部分通过让Service1向Service2发出请求,演示内部服务间请求。

第二部分介绍如何结合使用NGINX Status API和Docker Service API,自动扩缩容后端容器。Python程序使用NGINX Plus Status API监控Service1和Service2的负载,并使用Docker Swarm Service API扩容或缩容后端容器。

总结
Docker 1.12引入的新功能增强了Swarm平台的能力,而利用NGINX Open Source可进一步提升其能力,使用NGINX Plus则可获得更显著的增强。NGINX Plus能够利用DNS动态重新配置后端容器以实现负载均衡,Status API还可提供可观测性,两者共同构成了一套功能强大的容器解决方案。
要试用NGINX Plus,立即开始30天免费试用,或联系我们,讨论您的使用场景。
还可试用我们GitHub代码库中提供的演示。
关于作者

相关博客文章
NGINX Plus R26 正式发布
NGINX Plus R26通过缓存JSON Web密钥集加快JWT验证,并强化TLS握手,从而提升安全性。NGINX JavaScript的新功能包括增强对异步函数的支持,以及实现WebCrypto API。
使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击
gRPC具备开发人员设计和部署现代应用所需的速度与灵活性,但其开放性也使其极易受到第7层DoS攻击。NGINX App Protect DoS可保护gRPC应用免受此类破坏性攻击。
Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划
了解选择错误的Ingress控制器可能带来的风险,以及如何从关键方面着手,让您的选择更好地适应未来需求。
NGINX Plus R19 正式发布
NGINX Plus R19扩展了监控功能,不仅提供更多指标,还新增了指标分析方式;增加试运行模式,用于测试限速效果;增强键值存储,以支持IP地址范围;并使限速更加动态。
NGINX现已正式加入F5
NGINX现已正式成为F5的一部分。Gus Robertson现任F5 NGINX业务部门负责人。他阐述了两家公司在人才、文化和愿景方面融合的价值,以及双方将如何携手增强NGINX的开源产品和商业产品。
