[这篇文章最初是由Shay Naeh写的]
在我之前的文章中,我讨论了在云上虚拟化网络功能的必要性。在这篇文章中,我将深入探讨一个真实的场景,比方说可以在家里尝试。(我们也支持本地云,还记得吗?)
我们先回顾一下,虚拟化云网络组件的主要挑战通常在于如何实现自动化,贯穿于部署阶段到部署后阶段:
以下是我如何使用Cloudify在OpenStack上实现的。
解决方案
对于自动部署(Automatic deployment)和层之间的依赖关系,我使用了 Cloudify。Cloudify提供了一种简单的方法来编写组件之间的配置和依赖关系。我做了个实验,单独取了个制作视频流的软件在Tomcat Web容器上运行,使用了Tomcat和一个虚拟软件负载均衡器来实现弹性。Tomcat依次登记了我使用Apache创建的虚拟负载均衡器。点击这里你可以了解更多关于Apache mod_proxy_balancer。Apache LB是一项虚拟网络功能,可根据预定义策略将流量引导至多个视频流。这里我使用了一个简单的循环策略,将请求均匀地直接发送到Tomcat服务器中。
同时我还使用了一个Tomcat连接器,每当有一个新的Tomcat启动时,它就会连接到负载均衡器上,并声明这有一个额外的视频流,表明我是可以用的并且你可以直接引导流量给我。
对于只需要最低的配置就可使用的Subsonic视频流。我上传了各种MP3和MP4文件(音频和视频),并能够使用从Google Play和Apple App Store下载的客户端应用程序分别在桌面浏览器和Android以及iPhone移动设备上播放。
请注意,只有在LB启动之前,Tomcat视频流才能启动,因此Tomcat和LB之间存在依赖关系。这个依赖关系在下面的配置中有记录,关于服务创建和它们之间的依赖关系:
application {
name="subsonic"
service {
name = "apacheLB"
}
service {
name = "tomcat"
dependsOn =["apacheLB"]
}
}
部署编排(Orchestration)- Cloudify会处理网络架构流程,这会推动NFV组件的部署。Cloudify在OpenStack中定义了网络,子网,安全组,浮动IP,管理网络和应用程序网络。Openstack中的子网取决于先创建的网络。这里是一个来自Cloudify驱动程序的代码片断,定义了应用程序网络的管理网络和规定:
cloudNetwork {
management {
networkConfiguration {
name "Cloudify-Management-Network"
subnets ([
subnet {
name "Cloudify-Management-Subnet"
range "177.86.0.0/24"
options ([ "gateway" : "177.86.0.111" ])
}
])
custom ([ "associateFloatingIpOnBootstrap" : "true" ])
}
}
templates ([
"APPLICATION_NET" : networkConfiguration {
name "Cloudify-Application-Network"
subnets {
subnet {
name "Cloudify-Application-Subnet"
range "160.0.0.0/24"
options { gateway "null" }
}
}
custom ([ "associateFloatingIpOnBootstrap" : "true" ])
}
])
}
Cloudify还会编排上面定义的应用程序服务和依赖项。
监控(Monitoring)是部署编排的一部分,它定义了要收集并采取行动的指标。指标可以是请求的数量,吞吐量(即给定单位时间内的请求数量),特定域的指标(如Tomcat),繁忙的线程等等。指标用于衡量系统,应用程序和内部资源的当前状态。也可用于其他任务,如自我修复和弹性伸缩,更多用于更深的层面。监视器可以使用各种收集方法应用于任何数据源,如SNMP,CLI,JMX等。下面是我用Tomcat服务器通过JMX收集指标的监视器的一个例子。
monitors {
def metricNamesToMBeansNames = [
"Current Http Threads Busy": ["Catalina:type=ThreadPool,name=\"http-bio-${currHttpPort}\"", "currentThreadsBusy"],
"Current Http Thread Count": ["Catalina:type=ThreadPool,name=\"http-bio-${currHttpPort}\"", "currentThreadCount"],
"Backlog": ["Catalina:type=ProtocolHandler,port=${currHttpPort}", "backlog"],
"Total Requests Count": ["Catalina:type=GlobalRequestProcessor,name=\"http-bio-${currHttpPort}\"", "requestCount"],
"Active Sessions": ["Catalina:type=Manager,context=/${ctxPath},host=localhost", "activeSessions"],
]
return getJmxMetrics("127.0.0.1",currJmxPort,metricNamesToMBeansNames)
}
自我修复(Self healing)- 当Tomcat服务器宕机或负载平衡器宕机时,Cloudify将启动一个新的服务器。Cloudify通过对其管理的服务持续监视来获知这种情况。当服务崩溃时,将按照自定义配置自动启动。 弹性伸缩(Auto scaling)- 当你的系统中有更多的负载,更多的用户和更多的事务需要处理时,你会怎么做?如何在高负载的时候增加容量并在正常的时候减少负载?你必须有一个灵活的自动解决方案,比如一个Auto Scaling解决方案。
以下是一个体系结构图,您可以看到从vLB到vVideo视频流的流量情况,以及负载生成来模仿来自真实客户端的请求。生成负载以检查弹性伸缩的规则。我在Tomcat配置中添加了以下规则:
service {
extend "../../../services/tomcat"
elastic true
numInstances 2
minAllowedInstances 1
maxAllowedInstances 4
scalingRules ([
scalingRule {
serviceStatistics {
metric "Current Http Threads Busy"
statistics Statistics.maximumOfMaximums
movingTimeRangeInSeconds 1
}
highThreshold {
value 4
instancesIncrease 2
}
lowThreshold {
value 1
instancesDecrease 1
}
}
])
}
这告诉管理自动化行为的Cloudify从两个Tomcat实例开始,并基于一个名为“Current HTTP Threads Busy”的监控指标,如果阈值跨越四个,则将服务器数量增加两个(您可以使用更高的数字,其可配置)。我用了四个以便立即看到结果。Cloudify使用JMX从Tomcat获取繁忙线程的数量,然后将其与定义的阈值进行比较。
这是用桌面浏览器打开Subsonic网站的视觉图(图片取自Subsonic网站)
然后我们借了一些朋友的手机,同时用多部手机登上该网站,让每个手机各自播放音乐或视频。
一旦LB正在运行,并且在制定cookies之后继续将用户的会话导向到用户刚开始使用的相同视频流,所有事情都很顺利。用户被定向到在Tomcat上运行的视频流,当视频流或者更精确的Tomcat线程超过了定义的阈值时,额外的Tomcat服务器将被引入,自动注册到LB,并准备好容纳额外的用户和请求。
关于弹性伸缩(Auto scaling)再说一点,当系统空闲,客户端使用率降低时,它会释放服务器,减少可用vVideo视频流的数量。换句话说,一个100%弹性的系统,会随着需求增长和收缩。
现在,我可以将虚拟LB组件作为虚拟NFV组件用于其他目的,它是我目录上现有的NVF组件。