V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
daocloud
V2EX  ›  程序员

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

  •  
  •   daocloud ·
    DaoCloud · 2016-08-24 16:32:22 +08:00 · 3047 次点击
    这是一个创建于 3006 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    我们开始吧——

    负载均衡是 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 负载均衡来连接后台容器。

    • 负载均衡器再也不会集中使用了,它已经被分散布置,也因此可以实现规模化。负载均衡被植入了独立容器,无论何时,只要容器想与其它服务之间通信,负载均衡就能即时嵌入到那个容器中。负载均衡如今更为强大,能够在各种不确定因素中完美工作。

    • 新的 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
    

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

    $docker service create \

      — replicas 3 \
    
      — name collabweb \
    
      — network collabnet \
    
       Nginx
    

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

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

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

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

    在任何 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 。

    如上图,你可以在 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 )。

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

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

    为什么选择 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 和其他负载均衡工具:

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

    路由网络( 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 )。一个典型的架构会是这副样子:

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1946 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 00:36 · PVG 08:36 · LAX 16:36 · JFK 19:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.