title: 负载均衡
Rancher 支持多种负载均衡驱动,通过在它之上建立代理规则,可以将网络及应用流量分发至指定的容器中。负载均衡的目标服务中的容器都会被 Rancher 自动注册为负载均衡的目标。在 Rancher 中,将负载均衡加入到应用中是一件非常容易的事情。
默认情况下,Rancher 提供一个基于 HAProxy 的托管的负载均衡,它可以被手动扩容至多台主机。在接下来的例子中将会涉及到负载均衡中不同的配置项,这些配置项主要以 HAProxy 为参考。我们计划支持除 HAProxy 以外的其他负载均衡驱动,但这些配置项都会是相同的。
我们使用 round robin 算法分发流量至目标服务。这个算法可在自定义 HAProxy.cfg中进行自定义。
另外,您可以配置负载均衡来将流量分发至与负载均衡容器处于相同主机的目标容器。通过给负载均衡设置一个特定的标签,能够将负载均衡的目标限定在同一台主机中的目标容器(例如 io.rancher.lb_service.target=only-local),或者优先转发至同一台主机中的目标容器(例如: io.rancher.lb_service.target=prefer-local)。
我们将会查看在UI和Rancher Compose中的负载均衡的配置项,并且给出UI和Rancher Compose的用例。
如何在 UI 上新增一个负载均衡
我们将为我们在添加服务部分中创建的“letschat”应用新增一个负载均衡.
首先,我们从添加一个负载均衡服务开始,单击”添加服务“旁边的下拉图标,找到添加负载均衡并单击它。
进入添加页面后,容器数量默认是 1,填入“名称”,如“LetsChatLB”。
端口规则下,访问选择默认的公开,协议选择默认的HTTP。请求端口填入80,目标选择letschat服务, 并且端口填入8080。
单击创建。
现在,让我们来实际感受一下负载均衡。在应用视图下, 有一个连接到80端口的超链接,这是负载均衡中的源端口。如果您单击它,将会在您的浏览器中自动新开一个页签,并指向负载均衡服务所在的主机。请求将会被重定向到其中一个”LetsChat“容器。如果您刷新浏览器,负载均衡服务会把新的请求重定向到“LetsChat”服务下的其他容器中。
页面上的负载均衡选项
Rancher 提供一个基于 HAProxy 的容器来重定向流量至目标服务。
注意: 负载均衡只会在那些使用
托管网络的服务中生效,其他网络模式都不会生效。
单击添加服务旁边的下拉图标,找到添加负载均衡并单击它。
您能使用滑块选择数量,就是负载均衡使用多少个容器。或者,您可以选择总是在每台主机上运行一个此容器的实例。使用这一个选项, 您的负载均衡容器数量将会随着您环境下的主机数量增减而增减。如果您在调度部分设定了调度规则,Rancher 将会在满足规则的主机上启动负载均衡。如果您的环境下新增了一台不满足调度规则的主机,负载均衡容器不会在这一台主机中启动。
注意: 负载均衡容器的扩缩容不能超过环境下主机的数量,否则会造成端口冲突,负载容器服务将会被阻碍在
activating状态。它会不断去尝试寻找可用的主机并开启端口,直到您修改它的数量或者添加主机.
您需要提供负载均衡的名称,如果有需要的话,您可以添加描述。
接下来,您可以定义负载均衡的端口规则。有两种规则类型可供创建。用于目标为特定的已存在的服务的服务规则和用于匹配一定选择规则的选择器规则。
当创建了多条服务和选择器规则的时候,请求头和路径规则将会自顶向下按显示在 UI 上的顺序匹配。
服务规则
服务规则指的是端口指向目标容器的规则。
在访问选项栏中,您可以决定这个负载均衡端口是否可以被公网访问(就是说是否可以从主机以外访问)或者仅仅在环境内部访问。默认情况下,Rancher 假定您希望被公网访问,但是如果您希望仅仅在环境内部被访问,您可以选择内部。
选择协议选项栏。获取更多关于我们协议选项的信息。如果您选择了需要 SSL 终端(如 https or tls),您将需要在SSL终端标签页中新增您的认证信息。
接下来,您可以针对流量的来源填写请求头信息, 端口 和 路径。
注意:
42端口不能被用作负载均衡的源端口,因为它被用于健康检查。
请求头信息/路径
请求头信息是 HTTP 请求头中的 host 的属性。请求路径可以是一段特殊的路径。您可以任意设置其中一个或者两者都设置。
例子:
domain1.com -> Service1domain2.com -> Service2domain3.com -> Service1domain3.com/admin -> Service2
通配符
当基于 HOST 值设置路由时,Rancher 支持通配符。所支持的语法如下。
*.domain.com -> hdr_end(host) -i .domain.comdomain.com.* -> hdr_beg(host) -i domain.com.
目标服务和端口
每一个服务规则,您都可以选择您想要的目标服务。这些服务列表是基于该环境下所有的服务清单的。每一个服务,您还能选择与之配套的端口。服务上的私有端口通常就是镜像所暴露的端口。
选择器规则
在选择器规则中,您需要填写一个选择器标签而不是特定的服务。选择器基于服务的标签来选择目标服务。当负载均衡被创建的时候,选择器规则将会针对环境下现有的任意一个服务来计算看是否为可匹配的服务。后面新增的服务或者对标签进行修改都会拿来与选择器标签进行匹配。
对于每一个源端口,您都可以添加相应的请求头信息或路径。选择器标签是基于目标的,您能指定一个特定的端口接收转发到服务上的流量。服务上的私有端口通常就是镜像所暴露的端口。
例子: 2 选择器规则
- 源端口:
100; 选择器:foo=bar; 端口:80 - 源端口:
200; 选择器:foo1=bar1; 端口:80
- 服务 A 有一个
foo=bar标签,它将会匹配第一条规则. 任何指向100的流量都会被转发到服务 A。 - 服务 B 有一个
foo1=bar标签,它将会匹配第二条规则. 任何指向200的流量都会被转发到服务 B。 - 服务 C 有
foo=bar和foo1=bar1两个标签,它将会匹配两条规则. 任何指向200和100的流量都会被转发到服务 C.
注意: 目前,如果您想要将一条选择器规则应用于多个主机名/路径上,您需要使用Rancher Compose在目标服务上去设置主机名/路径。
SSL 会话终止
SSL 会话终止标签提供了添加用于https和tls协议证书的能力。在证书下拉框中,您可以为负载均衡选择主证书。
添加证书前,请阅读如何添加证书。
为负载均衡添加多个证书是可以实现的。这样相应的证书会基于请求主机名(查看 服务器名称指示)展示给客户端。这个功能可能在那些不支持 SNI(它会获取主要证书)的老客户端上失效。对于现代客户端,我们会在能匹配到的列表中提供证书,如果没有匹配成功,就会提供主证书。
负载均衡的会话粘性
您可以单击选择负载均衡的会话粘性。会话粘性就是您的 cookie 策略。
Rancher 支持以下两种选项:
- 无: 这个选项意味着不会设置 cookie 策略
- 创建新的 Cookie: 这个选项意味着在您的应用之外会创建 cookie。这个 cookie 是由负载均衡设置在请求与响应中的。这就是会话粘性策略。
自定义 haproxy.cfg
由于 Rancher 基于 HAProxy 来搭建负载均衡,所以您能自定义 HAproxy 的配置。您在这里定义的配置都会被添加到 Rancher 生成的配置的最后面。
自定义 HAProxy 配置的例子
globalmaxconn 4096maxpipes 1024defaultslog globalmode tcpoption tcplogfrontend 80balance leastconnfrontend 90balance roundrobinbackend mystack_foocookie my_cookie insert indirect nocache postonlyserver $IP <server parameters>backend customUUIDserver $IP <server parameters>
标签/调度负载均衡
我们支持向负载均衡添加标签并且调度负载均衡在哪启动。单击这里查看更多关于标签和调度的信息。
用 Rancher Compose 添加负载均衡
在这,我们将一步步为我们之前在创建服务章节创建的”letschat”应用设置一个负载均衡。
单击这里查看更多关于如何配置一个 Rancher Compose。
注意:: 在我们的例子中,我们会使用
<version>作为负载均衡镜像的标签。每一个 Rancher 版本都有特定的,被负载均衡所支持的lb-service-haproxy版本。
我们将会建立一个和我们上面在 UI 中所使用到的例子一样范例。首先您需要创建一个docker-compose.yml文件和一个rancher-compose.yml文件。使用 Rancher Compose,我们可以启动一个负载均衡
Example docker-compose.yml
version: "2"services:letschatlb:ports:- 80image: rancher/lb-service-haproxy:<version>
Example rancher-compose.yml
version: "2"services:letschatlb:scale: 1lb_config:port_rules:- source_port: 80target_port: 8080service: letschathealth_check:port: 42interval: 2000unhealthy_threshold: 3healthy_threshold: 2response_timeout: 2000
Rancher Compose 中的负载均衡配置
Rancher 提供一个基于 HAProxy 的容器来做负载均衡。
注意: 负载均衡仅仅在使用托管网络的服务中生效。其他的网络选择都不会生效。
负载均衡可以像其他任何一个服务一样被调度。单击这里获取更多关于在 Rancher Compose 中使用负载均衡的例子。
负载均衡由暴露在主机上的端口和负载均衡配置组成,这些配置包括针对不同目标服务的特定端口规则,自定义配置和会话粘性策略。
当与含有从容器的服务一起使用的时候,您需要将主服务作为目标服务,就是那些含有sidekick标签的服务。
源端口
当创建一个负载均衡的时候,您可以将任意一个您想要的端口暴露在主机上。这些端口都可以被用做负载均衡的源端口。如果您想要一个内部的负载均衡,就不要暴露任何端口在负载均衡上,只需要在负载均衡配置中添加端口规则。
注意:
42端口 不能被用作负载均衡的源端口,因为它被用于健康检查。
Example docker-compose.yml
version: "2"services:lb1:image: rancher/lb-service-haproxy:<version># Any ports listed will be exposed on the host that is running the load balancer# To direct traffic to specific service, a port rule will need to be added.ports:- 80- 81- 90
Load Balancer configuration
所有负载均衡的配置项都被定义在rancher-compose.yml的lb_config字段中
version: "2"services:lb1:scale: 1# All load balancer options are configured in this keylb_config:port_rules:- source_port: 80target_port: 80service: web1health_check:port: 42interval: 2000unhealthy_threshold: 3healthy_threshold: 2response_timeout: 2000web1:scale: 2
端口规则
端口规则是定义在rancher-compose.yml中的。因为端口规则是单独定义的,会有许多不同的端口指向同一个服务。默认情况下,Rancher 将会优先使用那些基于特定的优先级顺序的端口。如果您想要改变这些优先级顺序,您需要设定特定的优先级规则。
默认优先级顺序
- 没有通配符和 URL 的主机名
- 没有通配符的主机名
- 有通配符和 URL 的主机名
- 有通配符的主机名
- URL
- 默认(没有主机名,没有 URL)
源端口
源端口是值暴露在主机上的某个端口(也就是定义在docker-compose.yml中的端口)。
如果您想要创建一个内部负载均衡,那么源端口酒不需要与docker-compose.yml中定义的任意一个匹配。
目标端口
目标端口是服务内部端口。这个端口就是用于启动您容器的镜像所暴露的端口。
协议
Rancher 的负载均衡支持多种协议类型。
http- 默认情况下,rancher 容器会将 80 端口上的请求重定向到 443 端口上。如果没有设置任何协议,负载均衡就会使用http。HAProxy 不会对流量做任何解析,仅仅是转发。tcp- HAProxy 不会对流量做任何解析,仅仅是转发。https- 需要设置 SSL 会话终结。流量将会被 HAProxy 使用证书解密,这个证书必须在设定负载均衡之前被添加入 Rancher。被流量负载均衡所转发的流量是没有加密的。tls- 需要设置 SSL 会话终结。流量将会被 HAProxy 使用证书解密,这个证书必须在设定负载均衡之前被添加入 Rancher。被流量负载均衡所转发的流量是没有加密的。sni- 流量从负载均衡到服务都是被加密的。多个证书将会被提供给负载均衡,这样负载均衡就能将合适的证书基于主机名展示给客户端。 单击服务器名称指示)查看更多详情。udp- Rancher 的 HAProxy 不支持.
其他的负载均衡驱动可能只支持以上的几种。
主机名路由
主机名路由只支持http, https 和 sni,只有http 和 https同时支持路径路由。
服务
服务名就是您的负载均衡的目标。如果服务在同一个应用下,您可以使用服务名。如果服务在不同的应用下,您需要使用<应用名>/<服务名>。
Example rancher-compose.yml
version: "2"services:lb1:scale: 1lb_config:port_rules:- source_port: 81target_port: 2368# Service in the same stackservice: ghost- source_port: 80target_port: 80# Target a service in a different stackservice: differentstack/web1health_check:port: 42interval: 2000unhealthy_threshold: 3healthy_threshold: 2response_timeout: 2000ghost:scale: 2
主机名和路径
Rancher 基于 HAProxy 的负载均衡支持七层路由,可以在端口规则下通过设定指定的主机头和路径来使用它。
Example rancher-compose.yml
version: "2"services:lb1:scale: 1lb_config:port_rules:- source_port: 81target_port: 2368service: ghostprotocol: httppath: /path/ahealth_check:port: 42interval: 2000unhealthy_threshold: 3healthy_threshold: 2response_timeout: 2000ghost:scale: 2
通配符
当设置基于主机名的路由规则时,Rancher 支持通配符。所支持的语法如下。
*.domain.com -> hdr_end(host) -i .domain.comdomain.com.* -> hdr_beg(host) -i domain.com.
优先级
默认情况下,Rancher 针对同一个服务遵循默认优先级顺序,但是您也可以定制化您自己的优先级规则(数字越小,优先级越高)
Example rancher-compose.yml
version: "2"services:lb1:scale: 1lb_config:port_rules:- source_port: 88target_port: 2368service: web1protocol: httppriority: 2- source_port: 80target_port: 80service: web2protocol: httppriority: 1health_check:port: 42interval: 2000unhealthy_threshold: 3healthy_threshold: 2response_timeout: 2000web1:scale: 2
选择器
您可以通过设定选择器来指定多个服务。通过使用选择器,您可以在目标服务上定义服务连接和主机名路由规则,那些标签匹配了选择器的服务将成为负载均衡的目标。
当使用选择器的时候,lb_config可以设定在负载均衡和任意一个匹配选择器的服务上。
在负载均衡器中。选择器标签 设置在selector下的lb_config中。负载均衡的lb_config端口规则不能有服务,并且也不能有目标端口。目标端口是设置在目标服务的端口规则中的。如果您需要使用主机名路由,主机名和路径是设置在目标服务下的。
注意: 对于那些在 v1 版本 yaml 中使用了的选择器标签字段的负载均衡,这不会被转化成 v2 版本的负载均衡。因为服务上的端口规则不会更新。
Example docker-compose.yml
version: "2"services:lb1:image: rancher/lb-service-haproxy:<version>ports:- 81# These services (web1 and web2) will be picked up by the load balancer as a targetweb1:image: nginxlabels:foo: barweb2:image: nginxlabels:foo: bar
Example rancher-compose.yml
version: "2"services:lb1:scale: 1lb_config:port_rules:- source_port: 81# Target any service that has foo=bar as a labelselector: foo=barprotocol: httphealth_check:port: 42interval: 2000unhealthy_threshold: 3healthy_threshold: 2response_timeout: 2000# web1 and web2 are targeted with the same source port but with the different hostname and path rulesweb1:scale: 1lb_config:port_rules:- target_port: 80web2:scale: 1lb_config:port_rules:- target_port: 80
后台名称
如果您想要清晰地在负载均衡配置中标明您的后台,您需要使用backend_name。如果您想要为一个某个后台自定义配置参数,这就会用得上。
证书
如果您需要使用https 或者 tls 协议, 您可以使用直接加入 Rancher或者挂载在负载均衡容器中的证书。
引用在 Rancher 中添加的证书
证书可以在负载均衡容器的lb_config中被引用。
version: "2"services:lb:scale: 1lb_config:certs:- <certName>default_cert: <defaultCertName>
将证书挂载进负载均衡容器
仅仅在 Compose 文件中支持
证书可以作为卷直接挂载进负载均衡容器。证书需要按照特定的目录结构挂载入容器。如果您使用 LetsEncrypt 客户端生存证书,那么它就已经满足 Rancher 的要求。否则,您需要手动设置目录结构,使他与 LetsEncrypt 客户端生成的一致。
Rancher 的负载均衡将会检测证书目录来实现更新。任何对证书的新增/删除操作都将每 30 秒同步一次。
所以的证书都位于同一个基础的证书目录下。这个文件名将会作为负载均衡服务的一个标签,用于通知负载均衡证书的所在地。
在这个基础目录下,相同域名的证书被放置在同一个子目录下。文件名就是证书的域名。并且每一个文件夹都需要包含privkey.pem和
fullchain.pem。对于默认证书,可以被放置在任意一个子目录名下,但是下面的文件命名规则必须保持一致。
-- certs|-- foo.com| |-- privkey.pem| |-- fullchain.pem|-- bar.com| |-- privkey.pem| |-- fullchain.pem|-- default_cert_dir_optional| |-- privkey.pem| |-- fullchain.pem...
当启动一个负载均衡的时候,您必须用标签声明证书的路径(包括默认证书的路径)。这样以来,负载均衡将忽略设置在lb_config中的证书。
注意: 您不能同时使用在 Rancher 中添加的证书和挂载在负载均衡容器中的证书
labels:io.rancher.lb_service.cert_dir: <CERTIFICATE_LOCATION>io.rancher.lb_service.default_cert_dir: <DEFAULT_CERTIFICATE_LOCATION>
证书可以通过绑定主机的挂载目录或者通过命名卷来挂在入负载均衡容器,命名卷可以以我们的storage drivers为驱动。
Example docker-compose.yml
version: "2"services:lb:image: rancher/lb-service-haproxy:<TAG_BASED_ON_RELEASE>volumes:- /location/on/hosts:/certsports:- 8087:8087/tcplabels:io.rancher.container.agent.role: environmentAdminio.rancher.container.create_agent: "true"io.rancher.lb_service.cert_dir: /certsio.rancher.lb_service.default_cert_dir: /certs/default.commyapp:image: nginx:lateststdin_open: truetty: true
Example rancher-compose.yml
version: '2'services:lb:scale: 1start_on_create: truelb_config:certs: []port_rules:- priority: 1protocol: httpsservice: myappsource_port: 8087target_port: 80health_check:healthy_threshold: 2response_timeout: 2000port: 42unhealthy_threshold: 3interval: 2000strategy: recreatemyapp:scale: 1start_on_create: true
自定义配置
高阶用户可以在rancher-compose.yml中声明自定义的配置。单击HAProxy 配置文档查看更多详情。
Example rancher-compose.yml
version: '2'services:lb:scale: 1lb_config:config: |-globalmaxconn 4096maxpipes 1024defaultslog globalmode tcpoption tcplogfrontend 80balance leastconnfrontend 90balance roundrobinbackend mystack_foocookie my_cookie insert indirect nocache postonlyserver $$IP <server parameters>backend customUUIDhealth_check:port: 42interval: 2000unhealthy_threshold: 3healthy_threshold: 2response_timeout: 2000
会话粘性策略
如果您需要使用会话粘性策略,您可以更新rancher-compose.yml中的策略。
Example rancher-compose.yml
version: '2'services:lb:scale: 1lb_config:stickiness_policy:cookie: <cookieInfo>domain: <domainName>indirect: falsenocache: falsepostonly: falsemode: <mode>health_check:port: 42interval: 2000unhealthy_threshold: 3healthy_threshold: 2response_timeout: 2000
Rancher Compose Examples
Load Balancer Example (L7)
Example docker-compose.yml
version: '2'services:web:image: nginxlb:image: rancher/lb-service-haproxyports:- 80- 82
Example rancher-compose.yml
version: '2'services:lb:scale: 1lb_config:port_rules:- source_port: 80target_port: 8080service: web1path: /foo- source_port: 82target_port: 8081service: web2path: /foo/barhealth_check:port: 42interval: 2000unhealthy_threshold: 3healthy_threshold: 2response_timeout: 2000
内部负载均衡例子
设置内部负载均衡不需要列举端口,但是您仍然可以设置端口规则来转发流量。
Example docker-compose.yml
version: '2'services:lb:image: rancher/lb-service-haproxyweb:image: nginx
Example rancher-compose.yml
version: '2'services:lb:scale: 1lb_config:port_rules:- source_port: 80target_port: 80service: webhealth_check:port: 42interval: 2000unhealthy_threshold: 3healthy_threshold: 2response_timeout: 2000web:scale: 1
SSL 会话终止 Example
在rancher-compose.yml中使用的证书必须被加入到 Rancher 中。
Example docker-compose.yml
version: '2'services:lb:image: rancher/lb-service-haproxyports:- 443web:image: nginx
Example rancher-compose.yml
version: '2'services:lb:scale: 1lb_config:certs:- <certName>default_cert: <defaultCertName>port_rules:- source_port: 443target_port: 443service: webprotocol: httpsweb:scale: 1
