【Docker 精选】Docker 1.12.0 中负载均衡功能有何新亮点?

Docker 1.12.0 版本中服务俨然是一等公民:新版本的 Docker 允许服务镜像的复制和升级,以及动态负载均衡。有了 Docker 1.12,服务可以接入所有 Swarm 节点的端口,并通过 Docker 中基于虚拟 IP(VIP)的负载均衡法,或者基于轮询调度(RR)DNS 的均衡负载法(抑或两种方法兼有)来实现负载均衡

如果你还是初次接触负载均衡的概念,那我就来解释一下吧。负载均衡器会把工作负载布置到一套联网的计算机服务器或组件上,并使计算资源能以一种最理想的方式被利用。负载均衡器能监测服务器或组件故障,正确重新配置系统,来提供很高的可用性。在这篇博文中,我将尝试回答以下问题:

  • 负载均衡是 Docker 的新功能吗?
  • 基于可见 IP 的负载均衡有什么特别之处?
  • 为什么选择 IPVS ?它为什么比 HA-proxy、Nignx、ELB 等现行工具更优秀?
  • 路由网是一种新的负载均衡吗?
  • 我们能否在新的 Swarm 模式下使用外接负载均衡或 HA-proxy?

1

我们开始吧——

负载均衡是 Docker 的新功能吗?

负载均衡(LB)功能对于 Docker 而言绝非新事物。它最初出现在 1.10 版的 Docker 上,那时 Docker 引擎为用户自定义网络中的容器内嵌了一个 DNS 服务器。尤其是那些用网络别名(net-alias)运行的容器,在使用别名时都需要这个嵌入式 DNS 来解决容器 IP 地址的问题。

毫无疑问,基于轮询调度(RR)DNS 的均衡负载法是相当简单易行的,对于特定脚本的增量能力而言,还是一种极为优秀的机制——如果你考虑进那些默认的地址选择误差的话。不过它也有着这样那样的限制和问题,比如一些客户端应用会把 DNS 主机名与实际 IP 的映射关系缓存起来,这就会在映射发生改变时,造成应用的宕机。同时,非零的 DNS TTL 值会使得 DNS 记录延迟反映最新的细节。基于负载均衡的 DNS 不会做出正确的、基于客户端执行的负载均衡。轮询调度(RR)DNS 经常被叫做“穷人协议”,我们会在以后发布更多关于它的内容。

Docker 1.12.0 版本中的负载均衡功能有什么特别之处?

  • 现在,Docker 1.12.0 有了内置的负载均衡功能。负载均衡被当作容器网络模式(正确叫法是 CNM,Container Network Model)不可分割的一部分,并在网络、端点和沙盒等 CNM 高层架构上运行。1.12 版 Docker 自带基于 VIP 的负载均衡。基于 VIP 的服务器使用 Linux IPVS 负载均衡来连接后台容器。
  • 负载均衡器再也不会集中使用了,它已经被分散布置,也因此可以实现规模化。负载均衡被植入了独立容器,无论何时,只要容器想与其它服务之间通信,负载均衡就能即时嵌入到那个容器中。负载均衡如今更为强大,能够在各种不确定因素中完美工作。

2

 

  • 新的 1.12.0 版 Docker Swarm 模式使用 IPVS(名为 “ip_vs” 的核心模块)来进行负载均衡。这是一个被整合进 Linux 内核的负载均衡模块。
  • Docker 1.12 第一次使用了路由网(Routing Mesh)。有 IPVS 在内核中规划数据包的路线,Swarm 的路由网能实现高性能的、可感知容器的负载均衡。Docker Swarm 模式包含有一个能使用多主机网络的路由网。它能创建一个基于云网络的虚拟拓展式局域网(VXLAN),允许两台不同主机上的容器顺畅通信,就像在同一台主机上一样。在本文的最后,我们会详细讨论路由网。

不管你什么时候在 Swarm 集群内创建了新的服务,这个服务都会获得虚拟 IP(VIP) 地址。不管你什么时候尝试对特定 VIP 提出需求,Swarm 负载均衡器都会把这一需求分配给特定服务中的某一容器。事实上,内置的服务发现功能就可以决定虚拟 IP 的服务名。最后,从服务 VIP 到容器 IP 负载均衡是通过 IPVS 实现的。这里要特别提一下,VIP 只有在集群内是有用的。在集群外,它一点意义都没有,因为它是一个私有的,无法路由转发的 IP。

我在谷歌云引擎上的 1.12.0 版 Docker 上运行了一个 6 节点集群。让我们通过以下步骤来检查一下 VIP 地址:

1. 创建一个新的覆盖网络:

 $docker network create –driveroverlay \

     –subnet10.0.3.0/24 \

     –optencrypted \

     collabnet

3

2. 创建一个名叫 collabweb 的新服务,就是如下所示,一个简单的 Nginx 服务端:

 $docker service create \

      —replicas 3 \

      —name collabweb \

      —network collabnet \

       Nginx

3. 如下所示,在名为 “collabnet” 的 Swarm 覆盖网络下,有 3 个容器副本在 3 个节点上运行服务。

4

4. 如下所示,用 Docker 检查命令来定时查看服务:

5

它显示了添加到各个服务的 “VIP” 地址。在下面的图表中,有一个可以帮助我们获得可见 IP 地址的简单命令:

6

5. 你可以用 nsenter 功能进入它的沙盒,来检查 iptables 的配置:

7

在任何 iptable 里,数据包通常先进入 Mangle Table 链,然后再进入 NAT Table 链。前者负责修正 IP 数据包,而后者只负责地址的翻译。如上面的 mangle table 所示,10.0.3.2 服务器 IP 用 iptables 输出链获得了 0x10c 的标记。IPVS 使用了这一标记,并如下所示,将其负载均衡到了容器 10.0.3.3,10.0.3.5 和 10.0.3.6。

8

如上图,你可以在 Linux 内核里用 ipvsadm 来安装、维系或检测 IP 可见的服务端 table。这一工具可以通过基于 Linux 分布规则的 apt 或 yum 命令,安装到任何 Linux 机器上。

按下图,一个典型的轮询调度 DNS 和 IPVS 负载均衡可以清楚地区分开来。每次我们尝试连接服务器时(不管是用 curl 命令或 dig 命令),轮询调度 DNS 会显示顺序的 IP 地址列表,而 IPVS 会将其负载均衡到容器上(比如 10.0.0.1, 10.0.0.2 和 10.0.0.3)。

9

6. 让我们在同一网络下创建一个名叫 collab-box 的新服务。如图所示,一个新的可见 IP(10.0.3.4)会自动像下面这样附加到这个服务:

10

同时,服务发现也按照预想在工作,

 11

为什么选择 IPVS?

IPVS(IP虚拟服务器)在 Linux 内核中执行传输层的负载均衡,因此被叫做 “Layer-4转换”。它是一个被整合进 Linux 内核的负载均衡模块,基于 Netfllter(网络过滤器)。它支持 TCP、SCTP 和 UDP、v4 和 v7。IPVS 在真正的服务器集群之前先在主机上工作,作为负载均衡器。它能把对服务(基于 TCP/UDP)的需求引导到真正的服务器上去,让真正服务器的服务以虚拟服务的方式呈现在单个 IP 地址上。

值得特别注意的是,IPVS 并不是一个代理——它是运行在4层网络上的转发者。IPVS 负责转送从客户端到后台的信息通信,这意味着你可以负载均衡任何东西,甚至是 DNS!它能使用的模式包括以下特征

  • 支持 UDP
  • 动态配置
  • 有 8 种以上的均衡方法
  • 可进行健康检测

IPVS 有很多有趣的特性,而且已经在 Linux 内核用了 15 年以上了。下面这张表区分了 IPVS 和其他负载均衡工具:

12

路由网是一种新的负载均衡吗?

路由网络(Routing Mesh)不是负载均衡器,它利用了负载均衡的概念。路由网为某一特定服务器提供通用式端口,这些端口都基于服务发现和负载均衡。所以,要想接触集群外的服务器,你需要开放端口,并通过公共端口连接它们。

简而言之,如果你有 3 个 Swarm 节点,A、B 和 C,还有一个运行在节点 A 和 C 上的服务,并且已经指定了节点端口 30000,那么只要通过端口 30000 上 3 个 Swarm 节点中的任意一个,就能连接该服务,并自动在两个运行的容器之间完成负载均衡,不管这个服务器是否在那台机器上运行。如果时间允许,我会另写一篇博客来细讲路由网。

请特别注意,1.12 版 Docker 引擎创建 ingress overlay 网络来达到 Routing Mesh 的目标。一般情况下,前端网络服务和 sandbox 是 “ingress” 网络的一部分,会在路由网里被特别关注。所有的节点都通过内置其中的沙盒网络命名空间,默认成为 “入口” 覆盖网络的一部分。

是否可能把外部的负载均衡器整合进集群的服务器中?

我能否在 Docker Swarm 模式下使用 HA-proxy?

你可以把服务的端口开放给一个外部的负载均衡器。从内部而言,Swarm 允许你特殊规定如何在节点之间分配服务容器。如果你想用 L7 负载均衡器,你需要把它们指定给任何(全部也好,部分也好)节点 IP 和公共端口——这只有在你的 L7 负载均衡器无法变成集群的一部分时才有用。如果你的 L7 负载均衡器可以通过自行运行,变成集群的一部分,那么它们只需指定给自命名的服务即可(会分配到一个 VIP)。一个典型的架构会是这副样子:

13

Leave a Reply

Your email address will not be published. Required fields are marked *