负载均衡(Load Balancing)是开源PaaS Rainbond的亮点功能,主要由“软件定义负载均衡”Rainbond-Entrance控制器完成。nginx
本文将围绕设计架构和实现介绍Rainbond-Entrance。git
Rainbond内部网络划分支持多租户,每一个租户都有一个私有的IP段,不一样租户的网络相互不可见。当咱们把一个容器化应用部署到Rainbond,Rainbond会为该容器分配一个内部IP,用于同一租户中不一样应用在集群内部的通讯,而集群外部没法直接访问,所以咱们须要有一个集群入口控制器,以便用户能够方便地访问这些应用。github
另外,Rainbond中部署的每一个应用均可以有多个实例,即假设咱们为一个WEB应用部署了三个实例,每一个实例分担一部分流量,咱们就须要这三个实例前增长负载均衡控制器来完成分发流量的工做。web
除了上述的基本功能之外,负载均衡控制器还必须支持更多功能,例如:json
综上所述,咱们须要一个同时支持L4或各种应用协议(L7)的负载均衡控制器集群,还必须可以自动发现集群中的应用变化以更新本身的转发规则。api
web
:表示Rainbond中的一个应用,而且有三个实例api-server
:kubeneters的kube-apiserver组件entrance
:Rainbond的负载均衡控制器通用接口,支持多种负载均衡插件Rainbond中的负载均衡是面向应用的,不一样应用可使用不一样的负载均衡。Rainbond的Entrance组件设计,使之能够集成集成多种负载均衡插件,也就是说,Rainbond不只支持经常使用的OpenResty,还能够支持其它负载均衡插件,例如商业支持的F5等。缓存
Entrance的主要工做是从kube-apiserver中监听应用运行节点信息的变化,例如Service、Endpoint、Pod等,而后把这些资源抽象为通用的负载均衡抽象并缓存在etcd中,这些通用抽象包括:服务器
Pool
:负载均衡池,其中包括多个节点,对应上图中的三个WEB实例Node
:Pool中的一个节点,对应上图中的其中一个WEB实例Domain
:域名,负载均衡控制器能够识别一个数据包中的域名信息而后将数据转发给对应的PoolVirtualService
:监听了某个端口的虚拟主机,还指明了端口的协议名称,主要用来处理L4入口控制和负载均衡Rule
:转发规则,用来描述域名跟Pool的对应关系,还指明了端口的协议名称与证书信息,处理L7入口控制和负载均衡当有资源发生变化时,Entrance会将通用资源转化为相应插件的资源,并根据应用所选择的不一样的插件驱动操做负载均衡控制器。微信
从架构中能够看到,有两个Entrance和两个OpenResty实例,它们的关系是:每一个Entrance中持有全部OpenResty的地址,当有信息须要更新时,Entrance会将信息更新到全部的OpenResty。那两个Entrance之间怎么协调呢?这里咱们利用etcd自己的特性作了分布式锁,保证只有一个Entrance有权限向OpenResty更新信息,如此实现了高可用。网络
OpenResty是一个能够用Lua脚原本处理请求和业条逻辑的WEB应用,而且内置了众多Lua相关的指定和函数供开发者使用,很合适开发Restful API服务器,咱们将OpenResty做为Entrance的插件之一缘由以下:
咱们在OpenResty端嵌入了一个Rest API服务器,这些API是用Lua写的。前面说过OpenResty集成了Lua脚本功能,咱们能够直接用Lua来处理请求,下面是Nginx配置文件的其中一部分:
# custom api of upstream and server server { listen 10002; location ~ /v1/upstreams/([-_0-9a-zA-Z.@]+) { set $src_name $1; content_by_lua_file lua/upstream.lua; } location ~ /v1/servers/([-_0-9a-zA-Z.@]+) { set $src_name $1; content_by_lua_file lua/server.lua; } }
当咱们调用下面的API时:
curl -s localhost:10002/v1/servers/app1 -X POST -d "$json_data"
OpenResty会执行相应的Lua脚中,也就是lua/server.lua
,前面说过,OpenResty内置了不少Lua相关的指命与函数,可让Lua与Nginx更好地交互,因此咱们在脚本中很容器处理接收到的JSON数据,并将其转换为配置Nginx文件,因为Lua代码较多就不贴出来了,能够在本文的引用部分找到该项目地址。
这里有个须要注意的地方,当收到大量修改server和upstream的请求时,OpenResty须要频繁加载配置文件,这样会增长负载且影响性能。实际上OpenResty有不少第三方插件可使用,有一个叫dyups的插件能够作到动态修改upstream,它的使用方式以下,Lua代码:
-- 增长或更新指定upstream dyups.update("upstream_name", [[server 127.0.0.1:8088;]]) -- 删除指定upstream dyups.delete("upstream_name")
执行成功后就已经生效了,不须要咱们执行nginx -s reload
命令,这会提升一些效率。
对于server的修改暂时尚未相应用插件作到动态修改,因此实际上咱们的负载均衡控制器分两种状况,若是更新了upstream配置会即时生效,而更新server配置则须要加上nginx -s reload
命令。
咱们用Entrance加OpenResty实现了一个可插拔且高可用的负载均衡控制器,总体来讲并不复杂,但愿本文能带给你一些帮助。
目前咱们已经把Rainbond的OpenResty插件分离出来作为一个子项目而且开源在Github上,你能够下载并单独使用:Github地址。
好雨Rainbond(云帮)是一款以应用为中心的开源PaaS,深度整合基于Kubernetes的容器管理、Service Mesh微服务架构最佳实践、多类型CI/CD应用构建与交付、多数据中心资源管理等技术,为用户提供云原生应用全生命周期解决方案,构建应用与基础设施、应用与应用、基础设施与基础设施之间互联互通的生态体系,知足支撑业务高速发展所需的敏捷开发、高效运维和精益管理需求。