新东方的负载均衡架构探索和实践
Rancher是一个对用户很友好的产品,吸引了大批的用户和粉丝。在实际落地过程中,大家可能已经注意到Rancher组件之间的耦合存在单点。那么如何部署才能提高Rancher的可用性和可扩展性呢?Rancher在官方文档中给出了一些指导方案,用户可以根据自己的需要选择合适的方案落地。我今天和大家分享的是新东方在Rancher全组件负载均衡架构的实践,供大家在探索自己的高可用方案时做个参考。
1.Rancher的部署架构演变
Rancher1.6是一套小巧而实用的容器管理平台,我个人认为Rancher的定位应该是容器编排引擎的后台支撑系统,或者说是编排引擎的系统,因此Rancher1.6的架构并不是分布式架构,而是传统的C/S架构。无数的client(agent)连接到一个中心的Server,中心的Server连接一个数据库做持久化。这种架构就必然会涉及一个老话题,如何增强C/S之间的高可用性、可扩展性和解耦问题。我今天和大家聊内容是:Rancher1.6全组件负载均衡设计。
一般Rancher的简单部署方案是这样的:
SPOF问题,Server的单点,数据库的单点等。
扩展性问题,单server能带动的client数量有限。
强耦合问题,server写死数据库地址,client写死server地址等等。
总结下来就是下面这个图:
下面就对这个架构进行优化,我们的目标是达到Server/Client和数据库三个组件的自由扩展,如何做到呢?Rancher官方文档中已经给了答案,只需要在C/S中间增加一层负载均衡方案,在数据库一侧增加高可用方案即可。
总体架构就演变为这样:
我们看到,Server一侧使用RancherServerHA方案,将server扩展为多个。
中间增加一层负载均衡,这个负载均衡常见的私有云方案有LVS+Nginx或者F5,在公有云中可以使用阿里云的SLB或者AWSELB等等。Rancher的数据量并不算太大,可以简单的使用Mysql的主从方案。
优化到这步已经可以满足日常工作需要了,这里大家会注意到mysql主从还是会影响server的可靠性。一旦出现主库问题,Mysql切换的时候server肯定就down了,切换也需要一定的时间,启动后还需要重启server等等。如果希望更进一步提高server的可靠性,或者希望数据库切换对RancherServer透明,那就需要使用更高级的数据库高可用方案。
我们的DBA推荐使用Maxscale中间件+Galera集群的方案,Galera为多主库的分布式数据方案,发生写入操作后Galera会同步数据到其他数据库中,直到同步都完成后返回完成写入操作。MaxScale是数据库中间件,它通过解析mysql协议判断读写操作,可以将读写操作分离。一旦数据库发生故障整个数据库集群的切换对外界是无感知的。
这个方案的部署图是这样的:
每个组件都介绍一下,负载均衡采用互联网最常用的LVS-DR+Nginx方案。数据库采用Galera集群做多主库的数据库复制,通过Maxscale中间件来做高可用和读写分离。
这就是我们现在最终的架构,这个架构的好处有几点:
可靠性大大增加,所有组件都可以扩展,server,client,数据库和负载均衡本身。
每个组件的扩展并不影响其他组件,所有组件的扩展都可以在线进行。
配置解耦,通过域名映射的方式,server连接数据库的域名映射为maxsacle中间件的ip,client连接server的域名映射为负载均衡的Vip。
故障切换透明,对其他组件无感知。数据库故障,server故障都可以在线解决,解决后重新加入集群。
顺便提一下,这个架构中的数据库部分还可以进一步优化为:
MaxScale前增加一层LVS四层负载均衡(设备可复用c/s之间的负载均衡),那么这个方案就可以说是全模块无死角的负载均衡架构了。但是我们实际实施的时候并没有采用这样的方案,考虑到RancherServer和Client断开一段时间后并不会影响主机上的容器运行。
这段时间完全可以做一些维护,采用Galera和Maxscale后已经大大的减少了数据库切换时间,并且实测MaxScale的稳定性很好,感觉没有必要再投入更多资源在MaxScale上。更何况加入更多的组件会使得整个系统的复杂度上升,这实际上增加了维护成本并且扩展了故障域,可靠性有可能不升反降。因此这个方案也只是停留在纸面上了。
那么说到这里大家对整体架构就有了初步认识,下面说说实现。
篇幅和时间原因,我这里只是点一下配置的要点,具体的实践过程可以关注我的工作笔记http://jiangjiang.space
2.Rancher各个组件负载均衡的配置2.1LVS-DR+Nginx
LVS-DR设置:
LVS1:配置keepalived,配置虚拟ip,配置到Nginx1和Nginx2的四层转发
LVS2:配置keepalived,配置虚拟ip,配置到Nginx1和Nginx2的四层转发
Nginx1:配置nginx到rancherserver8080上的七层转发
Nginx2:配置nginx到rancherserver8080上的七层转发
**A.安装keepalived和ipvsadmin**
LVS从2.6内核开始就已经是内核的一部分了,因此只需要安装ipvsadmin和keepalived,通过yum安装或者源码安装都可以,步骤略过。
B.配置keepalived.conf
vi/etc/keepalived/conf/rancher.conf
**C.Nginx节点配置**
Nginx节点配置分为两部分:
1.虚拟IP(VIP)设置到回环设备上(lo),当接收到lvs发来的包后本机网卡才会处理这些包。
2.设置Nginx的Websocket转发到rancherserver的8080端口上。
VIP配置在lo上的配置:
下面设置Nginx的Websocket转发到Rancherserver的8080端口上。安装nginx过程略过,在conf.d中增加虚拟主机配置。vi/usr/local/nginx/conf/conf.d/rancher.conf
配置好后,直接访问http://VIP:80应该就可以看到Rancher控制台界面了。如果没有则是配置错误,继续调整。
2.2galera和Maxscale
以下步骤摘自新东方资深DBA傅少峰的文档。
https://mariadb.com/downloads下载并安装mariadb10.2
安装如下rpm包
MariaDB-client-10.2.11-1.el7.centos.x86_64
MariaDB-devel-10.2.11-1.el7.centos.x86_64
MariaDB-server-10.2.11-1.el7.centos.x86_64
MariaDB-common-10.2.11-1.el7.centos.x86_64
MariaDB-compat-10.2.11-1.el7.centos.x86_64
galera-25.3.22-1.rhel7.el7.centos.x86_64.rpm
jemalloc-3.6.0-1.el7.x86_64.rpm
jemalloc-devel-3.6.0-1.el7.x86_64.rpm
maxscale-2.1.16-1.centos.7.x86_64.rpm
maxscale-devel-2.1.16-1.centos.7.x86_64.rpm
maxscale可以复用其中一个数据库节点或者单独部署到一个机器。
mysql配置注意的地方,其他参数省略。
galera配置
执行:
建立cattle数据库和用户(连接任何一个galera实例执行):
创建maxscale监控用户(连接任何一个galera实例执行):
数据库准备完毕,下面是配置MaxScale。
MaxScale配置
配置文件:/etc/maxscale.cnf
启动maxscale
2.3server、client和数据库的连接和设置
数据库准备好了,下面就可以启动server了。启动过程非常简单,只需要修改rancherserver的启动参数如下:
逐条解释一下:
Server启动后就可以增加client了,登陆Rancher管理控制台,选择infrastructure->Hosts->AddHost
这样一个完整的负载均衡的Rancher就搭建完成了。
3应用交付和负载均衡现在说最后一个话题,应用交付和负载均衡。所谓应用交付说的是如何将Rancher上的一个应用公布到公网上给用户使用。为了能在前方接住大量的用户请求,一般都会统一搭建站点级别的入口负载均衡。示意图如下:
如图所示,用户请求从公网进来后,通过各路ISP接入设备到达站点边缘,连接通过各种防御设备到达入口负载均衡(LVS+Keepalived+Nginx),再由入口负载均衡统一代理到内部源站点上,这就是常见的应用交付过程。
在Rancher上的应用对接入口负载均衡一般采用Traefik,Traefik是一个容器化7层代理软件,性能接近Nginx。之前群里也有多位大拿分享过Traefik的应用,我这里就不重复介绍了,大家可以参考爱医康架构师张新峰的分享:《关于高可用负载均衡的探索》
我下面要讲的是traefik与LVS+Nginx负载均衡的对接和我对traefik的一些实践。
利用traefik交付应用的整个过程我总结为下图:
用户在浏览器中输入www.myxdf.com,通过DNS查询到这个域名对应的公网ip地址。
这个公网ip地址指向我们站点的入口负载均衡(LVS+Nginx),入口负载均衡收到请求后根据域名的设置,将请求转发给Rancher上的Traefik节点,我称这些节点为Ranhceredge。
traefik收到请求后,根据traefik.frontend.rule将请求转给打了标记的容器(或者rancherlb)
根据这个流程我们需要做以下几个配置。
3.1定义边界(rancheredgehost)
什么是边界?边界就是Ranchercluster中对外转发的中转站,边界是特殊的一个Rancherhost,边界上只跑treafik,其他什么容器都不跑,边界最好也不要接入任何存储(比如Ranchernfs),边界需要做严格的安全加固。当然也可以不将边界放在专门的host上,可以将边界混合到整个Rancher集群中,这样的好处是节省计算资源,两种模式都可以。
下面介绍如何将host定义为专门的边界节点:在Ranhcer控制台上,打开infrastructure,点击Hosts中。找到作为边界的host点击Edit:
在Labels中增加label,增加这个label后traefik就会自动运行在这台host上。
在RequiredContainerLabel中随便增加一个lable不用给值,我这里写的cn.xdf.edge
这个lable加入后,这个节点上就不会被调度任何其他容器了。这样一个边界节点就制作好了。
3.2启动traefik到边界节点
在社区商店中找到这个可爱的小交警,启动traefik。
配置说明如下:
好了启动traefik后,容器已经在edgeHost上启动了!
登陆管理界面看看:
3.3在traefik上发布应用服务
假设现在要把mydockerapp04.myxdf.com这个域名的应用发布出去。首先将mydockerapp04.myxdf.com这个域名匹配到对应的Rancherstack上面去。
这个就是我们的mydockerapp04应用,它是一些tomcat容器和一个内部lb组成的。
按照traefik的文档,只需要将label打到容器上即可,这里我的做法是增加了一个内部的lb,直接将label打在lb上。这里必须的label是:
label加入后应用就发布到traefik中了。
3.4从站点入口负载均衡转发到Traefik
在站点入口负载均衡上做转发配置,转发到treafik边界节点。负载均衡上所有源站都是通过80端口转发,通过设置不通的server_name来区分转发目的地。将server_name设置为*.myxdf.com。意思是所有myxdf.com的二级域名全部转发给traefik,这样做是为了跳过在入口负载均衡上配置明细转发规则(比如mydockerapp01转发到哪里这样的一条一条的规则),所有明细的转发规则全部交给traefik来管理。
这样做有很大的优势,我们之前也看到了traefik设置转发规则非常简单,只需要在容器或者ranhcerlb上打label即可。如果需要修改或者删除规则,也只需要修改或删除对应的label即可,管理灵活又免去了每次都要手动到入口负载均衡上刷新配置的麻烦。
Nginx配置如下:
3.5在DNS上设置域名指向站点入口负载均衡
在DNS上添加域名指向,这里就没有办法偷懒了,需要把所有明细域名都写上。
如果你不是公网应用,也可以使用dnsmasq或者bind甚至AD域的DNS等在内网建立DNS指向,DNS指向的IP为内网LVS的vip。
Rancher里面也有修改DNS的APP,比如aliyunDNS、Gandi.net等等。这些APP有的是自动添加DNS记录的,有的是根据label添加,大家有兴趣可以继续研究下。
至此,整个转发过程就完成了。用户已经可以通过外网访问这个应用了。
通过浏览器:打开mydockerapp04.myxdf.com
当然这个域名其实并不存在,是我瞎掰的,只为了方便大家理解这个过程。那么今天的分享也就结束了。
文章标题:新东方的负载均衡架构探索和实践
URL标题:http://ybzwz.com/article/cghsih.html