若是您的应用程序是面向大量用户、会吸引大量流量,那么一个不变的目标必定是在高效知足用户需求的同时、不让用户感知到任何相似于“服务器繁忙!”的状况。这一诉求的典型解决方案是横向扩展部署,以便有多个应用程序容器能够为用户请求提供服务。可是,这种技术须要可靠的路由功能,须要能够有效地在多个服务器之间分配流量。本文分享的内容就是要解决负载均衡解决方案的问题。nginx
Rancher 1.6是Docker和Kubernetes的容器编排平台,为负载均衡提供了功能丰富的支持。在Rancher 1.6中,用户能够经过使用开箱即用的HAProxy负载均衡器,来提供基于HTTP / HTTPS / TCP主机名/路径的路由。git
而在本文中,咱们将探讨如何在原生使用Kubernetes进行编排的Rancher 2.0平台上实现这些流行的负载均衡技术。github
Rancher 2.0 负载均衡功能docker
经过Rancher 2.0,用户能够开箱即用地使用由NGINX Ingress Controller支持的原生Kubernetes Ingress功能进行7层负载均衡。由于Kubernetes Ingress仅支持HTTP和HTTPS协议,因此目前若是您使用的是Ingress支持,那么负载均衡仅限于上述这两种协议。编程
对于TCP协议,Rancher 2.0支持在部署Kubernetes集群的云上配置第4层TCP负载均衡器。后文中咱们还将介绍如何经过ConfigMaps为TCP均衡配置NGINX Ingress Controller。后端
HTTP/HTTPS 负载均衡功能服务器
在Rancher 1.6中,您添加了端口/服务规则以配置HAProxy负载均衡器,以均衡目标服务。您还能够配置基于主机名/路径的路由规则。app
例如,下面让咱们来看看一个在Rancher 1.6上启动了两个容器的服务。启动的容器正在监听私有80端口。负载均衡
为了均衡两个容器之间的外部流量,咱们能够为应用程序建立一个负载均衡器,以下所示。在这里,咱们会配置负载均衡器,将进入端口80的全部流量转发到目标服务的容器端口,而后Rancher 1.6在负载均衡器服务上放置了一个方便的连接到公共端点。tcp
Rancher 2.0提供了一种使用很是类似的、由NGINX Ingress Controller支持的、使用Kubernetes Ingress的负载均衡器功能。下文中咱们一块儿来看看咱们该如何作。
Rancher 2.0 Ingress Controller部署
Ingress只是一种规则,控制器组件会将这一规则应用于实际负载均衡器中。实际负载均衡器能够在集群外部运行,也能够在集群中部署。
经过RKE(Rancher Kubernetes安装程序),Rancher 2.0让用户能够开箱即用地在配置的集群上部署NGINX Ingress Controller和负载均衡器,以处理Kubernetes Ingress规则。请注意,NGINX Ingress Controller默认安装在RKE配置的集群上。经过云提供商(如GKE)配置的集群具备本身的Ingress Controller来配置负载均衡器。本文的范围仅适用于使用RKE安装的NGINX Ingress Controller。
RKE将NGINX Ingress Controller部署为Kubernetes DaemonSet——所以NGINX实例会部署在集群中的每一个节点上。NGINX就像一个Ingress Controller,在整个集群中监听Ingress建立,它还会将自身配置为知足Ingress规则的负载均衡器。DaemonSet配置有hostNetwork以暴露两个端口——端口80和端口443。有关如何部署NGINX Ingress Controller DaemonSet和部署配置选项的详细信息,请参阅此处:
https://rancher.com/docs/rke/v0.1.x/en/config-options/add-ons/ingress-controllers/
若是您是Rancher 1.6用户,那么将Rancher 2.0 Ingress Controller以DaemonSet的形式部署,会带来一些你须要知悉的重要的改变。
在Rancher 1.6中,您能够在堆栈中部署可扩展的负载均衡器服务。所以,若是您在Cattle环境中有四台主机,则能够部署一台规模为2的负载均衡器服务,并经过端口80在这两个主机IP地址上指向您的应用程序。而后,您还能够在剩余的两台主机上启动另外一台负载均衡器,以经过端口80再次均衡不一样的服务(由于负载均衡器使用不一样的主机IP地址)。
Rancher 2.0 Ingress Controller是一个DaemonSet——所以它全局部署在全部可调度节点上,以便为整个Kubernetes集群提供服务。所以,在对Ingress规则进行编程时,你须要使用惟一的主机名和路径指向工做负载,由于负载均衡器节点IP地址和端口80/443是全部工做负载的公共访问点。
如今让咱们看看如何使用Ingress将上述1.6示例部署到Rancher 2.0上。在Rancher UI上,咱们能够导航到Kubernetes Cluster和Project,并选择【部署工做负载/Deploy Workloads】功能,在命名空间下部署所需镜像的工做负载。让咱们将工做负载的规模设置为两个副本,以下所示:
如下是工做负载选项卡上部署和列出工做负载的方式:
要达到这两个pod之间的均衡,您必须建立Kubernetes Ingress规则。要建立此规则,请导航到您的集群和项目,而后选择“ 负载均衡”选项卡。
与Rancher 1.6中的服务/端口规则相似,您能够在此处指定针对工做负载的容器端口的规则。
基于主机和路径的路由
Rancher 2.0容许您添加基于主机名或URL路径的Ingress规则。根据您的规则,NGINX Ingress Controller将流量路由到多个目标工做负载。下面让咱们看看如何使用相同的Ingress规范将流量路由到命名空间中的多个服务。好比以下两个在命名空间中部署的工做负载:
咱们可使用相同的主机名但不一样的路径添加Ingress来均衡这两个工做负载的流量。
Rancher 2.0还为Ingress记录中的工做负载提供了方便的连接。若是配置外部DNS以对DNS记录进行编程,则能够将此主机名映射到Kubernetes Ingress地址。
Ingress地址是您的集群中Ingress Controller为您的工做负载分配的IP地址。您能够经过浏览此IP地址来达到工做负载。使用kubectl查看控制器分配入口地址。
您可使用Curl来测试基于主机名/路径的路由规则是否正常工做,以下所示:
如下是使用基于主机名/路径的规则的Rancher 1.6配置规范,与2.0 Kubernetes Ingress YAML规范进行比较:
HTTPS /证书选项
Rancher 2.0 Ingress功能还支持HTTPS协议。您能够在配置Ingress规则时上载证书并使用它们,以下所示:
添加Ingress规则时选择证书:
Ingress限制
尽管Rancher 2.0支持HTTP- / HTTPS-基于主机名/路径的负载均衡,但要突出的一个重要区别是在为工做负载配置Ingress时须要使用惟一的主机名/路径。缘由是Ingress功能仅容许将端口80/443用于路由,负载均衡器和Ingress Controller则可做为DaemonSet全局启动。
从最新的Rancher 2.x版本开始,Kubernetes Ingress不支持TCP协议,但咱们将在下一节中讨论使用NGINX Ingress Controller的解决方法。
TCP负载均衡选项
对于TCP协议,Rancher 2.0支持在部署Kubernetes集群的云提供程序中配置四层负载均衡器。为集群配置此负载均衡器设备后,Layer-4 Load Balancer在工做负载部署期间选择for port-mapping 选项时,Rancher会建立Load Balancer服务。此服务会让Kubernetes的相应云提供商配置负载均衡器设备。而后,此设备将外部流量路由到您的应用程序pod。请注意,上述功能须要该Kubernetes云提供商知足负载均衡器服务的要求,按此文档配置:
https://rancher.com/docs/rancher/v2.x/en/cluster-provisioning/rke-clusters/options/cloud-providers/
一旦负载均衡器配置成功,Rancher将在Rancher UI中为您的工做负载的公共端点提供一个连接。
如上所述,Kubernetes Ingress自己不支持TCP协议。所以,即便TCP不是NGINX的限制,也没法经过Ingress建立来配置NGINX Ingress Controller以进行TCP负载均衡。
可是,您能够经过建立一个Kubernetes ConfigMap,来使用NGINX的TCP负载均衡功能,具体可参阅这里:https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/exposing-tcp-udp-services.md。您能够建立Kuberenetes ConfigMap对象,来将pod配置参数存储为键值对,与pod镜像分开,更多细节能够参考这里:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/
要配置NGINX以经过TCP暴露服务,您能够添加或更新命名空间tcp-services中的ConfigMap ingress-nginx。此命名空间还包含NGINX Ingress Controller pod。
ConfigMap条目中的密钥应该是您要公开访问的TCP端口,其值应为格式<namespace/service name>:<service port>。如上所示,我暴露了Default命名空间中存在的两个工做负载。例如,上面ConfigMap中的第一个条目告诉NGINX我想在外部端口上暴露运行在default命名空间上的myapp工做负载,并监听在外部端口6790上的私有端口80。
将这些条目添加到Configmap,将自动更新NGINX pod,以配置这些工做负载来进行TCP负载均衡。您能够执行部署在ingress-nginx命名空间中的这些pod,并查看如何在/etc/nginx/nginx.conf文件中配置这些TCP端口。<NodeIP>:<TCP Port>在NGINX配置/etc/nginx/nginx.conf更新后,应该可使用公开的工做负载。若是它们不可访问,则可能必须使用NodePort服务来暴露TCP端口。
Rancher 2.0负载均衡的限制
Cattle提供了功能丰富的负载均衡器支持(详细介绍在此:https://rancher.com/docs/rancher/v1.6/en/cattle/adding-load-balancers/#load-balancers)。其中一些功能在Rancher 2.0中暂时没有等效功能:
当前NGINX Ingress Controller不支持SNI。
TCP负载均衡须要集群中的云提供程序启用的负载均衡器设备。Kubernetes上没有对TCP的Ingress支持。
只能经过Ingress为端口80/443配置HTTP / HTTPS路由。此外,Ingress Controller做为Daemonset进行全局部署,而不是做为可扩展服务启动。此外,用户没法随机分配外部端口来进行负载均衡。所以,用户须要确保它们配置的主机名/路径组合是惟一的,以免使用相同的两个端口发生路由冲突。
没法指定端口规则优先级和排序。
Rancher 1.6增长了对draining后端链接和drain超时的支持。Rancher 2.0暂不支持此功能。
目前在Rancher 2.0中,不支持指定自定义粘性策略和自定义负载均衡器配置以附加到默认配置。原生Kubernetes对此有必定的支持,不过也只限于定制NGINX配置:
https://kubernetes.github.io/ingress-nginx/examples/customization/custom-configuration/README/。
将负载均衡器配置从Docker Compose迁移到Kubernetes YAML?
Rancher 1.6经过启动本身的微服务提供负载均衡器支持,该微服务启动并配置了HAProxy。用户添加的负载均衡器配置在rancher-compose.yml文件中指定,而不是标准的docker-compose.yml。Kompose工具适用于标准的docker-compose参数,但在本文的状况下,是没法解析Rancher负载均衡器配置结构的。截至目前,咱们暂时没法使用Kompose工具将负载均衡器配置从Docker Compose转换为Kubernetes YAML。
结 论
因为Rancher 2.0基于Kubernetes并使用NGINX Ingress Controller(与Cattle使用HAProxy相比),所以原先Rancher 1.6中Cattle支持的一些负载均衡器的功能目前暂时没有直接等效功能。可是,Rancher 2.0支持流行的HTTP / HTTPS基于主机名/路径的路由,这种路由最经常使用于实际部署。还经过Kubernetes Load Balancer服务使用云提供商提供四层(TCP)支持。2.0中的负载均衡功能也具备相似的直观UI体验。
Kubernetes生态系统在不断发展,我相信咱们能找到更多适合全部负载均衡细微差异的解决方案!