HPE CMS团队推进NFV容器化的探索之路


背景

XEN、KVM、VMware等传统虚拟化技术在过去几年中被引入到电信网络中,并且带来了一定的好处,但是这种重型虚拟化的基础设施也带来一些新问题,比如整体特别“重”,对于IT软件系统的部署、微服务化改造来说并没有带来特别多的价值。 而后起之秀的容器技术相比传统虚拟化技术,其特点在于运行时的轻量级和应用部署的高效性,同时借助于谷歌新一代基于容器技术的微服务架构基础设施——Kubernetes的支持,运营商很容易升级现有的业务即系统为最新的微服务架构,大大提高电信业务部署的灵活性、加速新业务的推出速度、支持业务的不中断升级特性并且具备很强的弹性扩容能力。

【上海站|3天烧脑式微服务架构训练营】培训内容包括:DevOps、微服务、Spring Cloud、Eureka、Ribbon、Feign、Hystrix、Zuul、Spring Cloud Config、Spring Cloud Sleuth等。

自2015年以来, NFV和容器都成为各自领域里最热门的技术,这两项技术也被很多业内人士认为是未来的发展趋势,进入2016年,越来越多的人开始行动起来,开始尝试并积极探索NFV容器化的新方向。2016年6月,OPNFV Summit在德国柏林召开,德国电信公布了Docker承载NFV方面的一些应用案例与成果,而在OPNFV PoC战区,中国移动和红帽公司联合展示了容器化ICT融合平台。2016年9月,由云计算发展与政策论坛、百度、腾讯、阿里巴巴、中国电信、中国移动、中国信息通信研究院、英特尔等多家知名厂商与组织承办的“2016ODCC开放数据中心峰会”上,中国电信北京研究院云计算与大数据产品线的专家发表了题为“基于通用x86 硬件承载容器化NFV的关键技术验证”的演讲,演讲中重申了《中国电信CTNET2025技术白皮书》里关于容器技术与NFV的重要观点:“容器对SDN/NFV既有协同发展和增强的一面,又在很多场景下可以替代NFV的作用,是一种轻量级的价廉物美的虚拟化技术,运营商对容器技术在特定业务场景下的应用持积极态度”。

NFV领域里的一个热点目标是IMS平台,因为IMS系统成为4G VoLTE正式商用的必须条件,当前全球运营商都在开始加速VoLTE商用的业务目标,这也重新促进了大家对IMS平台的重视,特别是IMS平台容器化的可能性。我们知道在开源IMS领域内,有两个比较知名的项目:Clearwater与Kamalio,Clearwater与Kamalio又有什么重要的区别呢?答案是架构。Clearwater一开始就定位在云上的IMS,其宣传口号“IMS in the Cloud”,它采用了大型互联网软件架构的设计思路,以微服务方式设计各个组件,使得系统本身具有很好的弹性伸缩能力,成为一个电信级的开源IMS平台。

Clearwater包括一系列符合IMS标准的组件,提供了语音、视频、即时消息等服务。用户可以使用Clearwater模拟出运营商级的IMS系统,因此被业界广泛认可。官方网站(http://www.projectclearwater.org/)发布了一个声明,声称在亚马逊公有云上部署一个支持几百万用户的Clearwater集群,每用户每年的成本小于2美分。

本篇接下来,我们分享惠普CMS团队在Clearwater容器化改造探索过程中的一些收获和经验。

Clearwater的架构和集群分析

下图是来自Clearwater官方网站的架构图,虚线方框里的组件是Clearwater的核心组件,也是IMS系统的核心组件,下面简单介绍一下各个组件的功能。

首先,位于边缘的Bono组件充当了IMS中的P-CSCF功能,它相当于是对外联络点,负责接收客户端的SIP请求,即VOIP客户端直接跟它建立TCP连接并发起SIP协议的信令报文,然后Bono会把SIP报文传送给IMS中的I-CSCF节点,即图中的Sprout节点,I-CSCF是运营商的核心网络——也就是运营商内部网络的入口,Sprout节点发送请求给HSS节点(Home Subscriber Server),HSS节点存储了用户账号数据、用户订购的业务和配置参数以及用户的归属地等资料,当HSS收到Sprout节点发来的请求后,查询此用户的归属地信息,并且自动分配一个用户归属地所在的空闲S-CSCF节点为其提供SIP服务, S-CSCF节点相当于真正的VOIP里Proxy Server的角色,它负责完成用户注册认证和VOIP呼叫的路由处理,以及电话业务的触发(一个业务应用在IMS称为一个Application Server,独立成一个子系统,并统一接入IMS平台),Sprout组件同时担当了S-CSCF的角色,如果Clearwater集群中部署了多个Sprout副本节点,则任何一个节点都可以同时担当S-CSCF与I-CSCF的功能,Clearwater内在的基于DNS轮询的负载均衡机制在这里发挥了重要作用。
image001.png

Homer组件则用于存取用户开通MMTel业务(多媒体电话业务)时的业务相关配置信息,在用户发起VOIP请求是,Spout通过它还获取相关的用户配置信息。Homer与Homestead使用了同一个Cassandra集群,由于Cassandra集群本身提供了分布式海量存储,所以Clearwater可以实现大规模用户的支持能力。接下来我们说说Ralf组件,在SIP业务过程中,Bono与Sprout会产生可以用于产生用户账单的一些计费事件,这些事件就被发送到Ralf,然后Ralf把它们存储到memcached中,并通过标准的接口报告给外部的CDF(计费数据功能), 以最终完成用户计费和账单流程。由于Ralf组件的水平扩展能力比较有限,而且存在单点故障,所以Clearwater后来开发了新的组件——Chronos,Chronos配合Ralf一起工作,从而弥补这个明显的短板。

最后我们说说Ellis,它提供了一个简单的Web界面,用来完成SIP用户的注册管理功能。严格意义上,Ellis不属于Clearwater产品的一部分,因为正常情况下,我们的环境中有一个现成的外部HSS来存储用户数据,然后通过Homestead组件自动或手动同步用户数据,当我们测评Clearwater时,通过自带的Ellis创建任意数量的测试账号,从而加速整个测试流程。

Clearwater集群架构中还用到了流行的Etcd组件,Etcd用来解决Clearwater集群下的系统配置文件问题以及实现Clearwater集群的服务发现功能。Cassandra、Memcached以及Chronos集群的信息都存储在Etcd中,举个例子,一个Sprout节点启动的过程中,Clearwater的集群管理器进程(clearwater-cluster-manager)首先会通过Etcd查询当前存在的Memcached与Chronos集群,并为这个Sprout节点生成正确的配置文件,随后Sprout进程才启动并开始工作,因此,Clearwater集群中的组件很容易动态扩容。

Clearwater早先针对虚机部署的方式提供了ISO镜像文件,最近官方也开始尝试容器化改造,下一节我们来分享这方面的内容。

Clearwater On Docker

Clearwater官方于2016年初尝试容器化改造,对应的GitHub地址为:https://github.com/Metaswitch/clearwater-docker,但资料比较少,进度也缓慢,截止此文时间,Docker hub上还没有官方发布的Clearwater镜像,因此需要从官方提供的Dockerfile手工编译,Clearwater镜像总共包括9个镜像,总大小6个G。官方公布了Clearwater镜像在Docker中运行的方式,有以下几个关键点:

下图是Clearwater官方在Github上公开的一个Docker化部署结果,可以看到Clearwater容器化部署还是相对比较复杂的过程,因为总共有10个容器!
image003.png

下面我们分析一下Clearwater的Docker镜像的结构和特点。

首先,Clearwater的10个镜像都继承自Base镜像。Base镜像采用了supervisord来管理容器内的多个进程服务,默认装载了Clearwater基础设施(infrastructure)服务,下面是对应的supervisord的配置描述:
[program:clearwater-infrastructure]
command=bash -c '/etc/init.d/clearwater-auto-config-docker start && /etc/init.d/clearwater-infrastructure start && /etc/init.d/clearwater-etcd start && /etc/init.d/clearwater-cluster-manager start && supervisorctl start clearwater-group:*'
startsecs=0  

我们看到,Clearwater基础设施服务完成的工作包括以下几点:
  1. 实现Clearwater的自动配置功能(Clearwater auto config),在/etc/init.d/clearwater-auto-config-docker的脚本文件控制着Clearwater参数文件的生成,每个Clearwater组件的服务都从这个参数文件中获取自己所需的启动参数。
  2. 启动clearwater-infrastructure服务,提供了大部分Clearwater组件运行时所依赖的基础设施服务,比如解决了SNMP采集与监控告警,系统的TCP参数优化与安全通讯等问题。
  3. 启动本地的Etcd服务代理进程, Clearwater组件查询本地的Etcd的服务,可以减轻Etcd服务的压力以及提升数据查询的响应时间。


下面是Base镜像的Dockerfile,基于ubuntu镜像,可以看到,安装的是最新稳定版的Clearwater组件,并且开启了SSH服务:
FROM ubuntu:14.04
MAINTAINER maintainers@projectclearwater.org
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y openssh-server supervisor curl
RUN mkdir -p /var/run/sshd /var/log/supervisor
RUN echo 'root:root' | chpasswd
RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config
EXPOSE 22
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]
RUN locale-gen en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
COPY sysctl /sbin/sysctl
RUN sed -e 's/\#\(precedence ::ffff:0:0\/96  100\)/\1/g' -i /etc/gai.conf
RUN echo deb http://repo.cw-ngv.com/stable binary/ > /etc/apt/sources.list.d/clearwater.list
RUN curl -L http://repo.cw-ngv.com/repo_key | apt-key add -
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --force-yes clearwater-infrastructure clearwater-auto-config-docker clearwater-management
RUN /etc/init.d/clearwater-auto-config-docker restart
RUN /etc/init.d/clearwater-infrastructure restart
COPY clearwater-infrastructure.supervisord.conf /etc/supervisor/conf.d/clearwater-infrastructure.conf
COPY clearwater-group.supervisord.conf /etc/supervisor/conf.d/clearwater-group.conf  

由于继承了Base镜像,所以Clearwater的其他镜像的Dockerfile比较简单,下面是Bono组件的Dockerfile文件内容:
FROM clearwater/base
MAINTAINER maintainers@projectclearwater.org
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --force-yes bono
RUN sed -e 's/\(echo 0 > \/proc\/sys\/kernel\/yama\/ptrace_scope\)/# \0/g' -i /etc/init.d/bono
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --force-yes restund
RUN sed -e 's/\(echo 0 > \/proc\/sys\/kernel\/yama\/ptrace_scope\)/# \0/g' -i /etc/init.d/restund
COPY bono.supervisord.conf /etc/supervisor/conf.d/bono.conf
COPY restund.supervisord.conf /etc/supervisor/conf.d/restund.conf
COPY clearwater-group.supervisord.conf /etc/supervisor/conf.d/clearwater-group.conf
EXPOSE 3478 3478/udp 5058 5060 5060/udp 5062 

可以看出,Bono镜像在Base镜像之上,安装了bono以及restund这两个服务,其中bono服务默认在5060(TCP&UDP)端口以及5062(用于TLS加密)端口对外提供SIP服务, 而restund服务启动了一个STUN server,STUN的全称是Session Traversal Utilities for NAT,为了协助解决位于防火墙之后的SIP终端通讯问题,STUN在3478(TCP&UDP)端口提供服务。需要说明的是Clearwater本身并不提供TURN Server(媒体转发服务)。从Clearwater的GitHub上下载源码,按照官方说明文档进行操作,即可完成Clearwater的镜像打包,执行下面的Docker命令即可启动一套Clearwater的测试环境。

Clearwater On Kubernetes

首先,我们来看看为什么Clearwater on Kubernetes的方案更为重要,这是因为Kubernetes作为当前最有影响力的容器化微服务架构平台,很多公司已经用它来实现自己的弹性PAAS平台,所以相对于Clearwater on Docker来说,Clearwater On Kubernetes显得比较更为重要;此外,Clearwater on Docker的部署方案,目前不好解决弹性扩容问题,因为Docker本身没有提供Kubernetes的Service概念,我们很难部署多个Bono(或Sprout)组件并让它们自动成为Clearwater集群的一部分,而如果在Kubernetes平台上,我们则可以将Clearwater的各个组件定义成Kubernetes Service,然后不同组件之间用Service的DNS名称进行通信,这样我们就可以借助Kubernetes的能力来实现Clearwater集群的弹性扩容操作了,在Kubernetes 1.4的平台上,除了可以实现手动扩容之外,还能借助于Kubernetes的Auto-Scale功能实现基于容器负载压力的自动扩容能力,无需人工参与,除此之外,Kubernetes平台强大的自动化与自我治愈能力也大大降低了人工运维Clearwater这种复杂系统的的难度。但不幸的是,虽然官方已经给出 Clearwater在Docker上的部署方案,但Clearwater on Kubernetes的方案却一直没有结果,主要是官方维持的Clearwater Docker项目都还有不少问题迟迟得不到资源投入和修复,更没有精力去研究Clearwater On Kuberntes了,从github上的一些问题我们可以验证这一点:
image005.png

由于官方没有给出Clearwater On Kuberntes的资料,所以我们只能从官方给出的Clearwater On Docker的资料去研究,一路上遇到不少“坑”,这个过程中遇到的一些疑问也得到了Clearwater项目志愿者们的解答,最终得以顺利实现Clearwater在Kuberntes集群上的部署,在此感谢他们。我们首先仔细研究了IMS通讯的流程以及Clearwater的架构图,初步了解了Clearwater各个组件的作用,组件之间大致的通讯关系等基础问题,然后按照Clearwater的容器化指南,开始了我们的Clearwater On Kuberntes的改造探索之旅。

首先,我们针对Clearwater组件分别定义了10个Service,如下表所示:
biao.jpeg

上述Kubernetes Service与Pod定义并不难,根据官方给出的Clearwater On Docker资料即可完成,下面我们以最复杂的Bono服务为例,给出它的Pod与Service定义文件以及重要参数的介绍。

首先是Pod定义:
apiVersion: v1
kind: Pod
metadata:
name: clearwater-bono
labels:
 app: clearwater-bono    
spec:
 containers:
    - name: clearwater-bono
      image: clearwater-bono
      env:
        - name: PUBLIC_IP
          value: 10.1.1.1
      imagePullPolicy: IfNotPresent
      ports:
      - containerPort: 22
      - containerPort: 3478
      - containerPort: 5060
      - containerPort: 5062
      - containerPort: 5060
        protocol: UDP
      - containerPort: 5062
        protocol: UDP
 restartPolicy: Always

Bono容器进程需要一个PUBLIC_IP的环境变量,可以理解为集群的“公网IP”,在没有外部负载均衡器的情况下,这里可以填写Kubernetes集群中任意Node节点的IP地址。

接下来是是Bono对应的Service的定义文件:
apiVersion: v1
kind: Service
metadata:
name: bono
spec:
type: NodePort
ports:
- name: 5060t
  port: 5060
  protocol: TCP
  nodePort: 5060
- name: 5060u
  port: 5060
  protocol: UDP
  nodePort: 5060
- name: 5062t
  port: 5062
  protocol: TCP
  nodePort: 30002
- name: 5062u
  port: 5062
  protocol: UDP
  nodePort: 5062
- name: 3478t
  port: 3478
  protocol: TCP
  nodePort: 3478
- name: 3478u
  port: 3478
  protocol: UDP
  nodePort: 3478
selector:
app: clearwater-bono

由于Bono需要暴露SIP接入与STUN服务的的端口,供客户端连接,所以Bono的5060,5062以及3478等端口都采用NodePort方式绑定到Node上,从而SIP客户端可以与集群中的任意Node建立通信连接。更好的方式是外部有负载均衡器,BONO服务的端口映射到公网上,供外部用户使用,下面是建议的部署示意图:
image007.png

随后,我们用kubectl命令将定义好的YAML文件部署到Kubernetes集群上。注意,必须是Kubernetes 1.4或更高的版本,并且Docker的镜像存储不能采用OverlayFS,否则由于OverlayFS的一个Socket相关的Bug,supervisord无法正常运行,导致Clearwater的一些组件启动失败。发布到Kubernetes集群上以后,观察到Pod的状态都正常,我们成功登录到Ellis的网页(8080端口),但很快我们发现,无法创建SIP账号,浏览器页面报错,随后我们进入到Ellis的Pod容器中进行错误排查,发现了问题所在:
root@clearwater-ellis:/# more /var/log/ellis/ellis_20161017T170000Z.txt 
17-10-2016 17:35:11.121 UTC INFO main.py:113: Ellis process starting up
17-10-2016 17:35:11.195 UTC ERROR homestead.py:68: Failed to ping Homestead at http://homestead:8889/ping. Have you configured your HOMESTEAD_URL?

Ellis组件无法Ping通homestead这个主机名(Kubernetes Service名称), 而我们在Pod容易里执行下面的命令,却能返回结果:
curl http://homestead:8889/ping 

后来我们排查才发现,这是Clearwater的一个深坑。

Clearwater的设计中大量采用了DNS来实现负载均衡机制,与常规做法不同,Clearwater内部自己向DNS Name Server发起DNS查询指令以达到精确控制的负载均衡效果,下面是Bono组件查询Sprout服务的DNS记录失败时的日志截图:
image009.png

为什么在Pod容器内可以解析(Ping)的Kubernetes域名却无法被Clearwater解析?这背后隐藏着Clearwater的一个Bug。我们知道,Linux的DNS查询会用到/etc/resolv.conf文件,该文件是DNS域名解析的配置文件,它的格式很简单,每行以一个关键字开头,后接配置参数,resolv.conf的关键字主要有四个,分别是:
nameserver   #定义DNS服务器的IP地址
domain       #定义本地域名
search       #定义域名的搜索列表
sortlist     #对返回的域名进行排序

其中,domain和search作用相同,不能共存,当我们查询一个不带域名的主机名时,如果resolv.conf中配置了domain(或search),则DNS查询的时候,需要带上domain(或search)中定义的域名,以Kuberntes Pod中的容器为例,resolv.conf文件内容如下:
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.0.0.1
options ndots:5

因此,当DNS客户端要查询sprout的DNS记录时,其实是向SkyDNS Server发出如下的完整查询指令:nslookup sprout.default.svc.cluster.local,但是,Clearwater的DNS查询没有遵循上面的规则,会忽略主机的域名,直接向SkyDNS发出的指令是nslookup sprout,由于SkyDNS上是没有这个主机记录的,所以自然就查询不到了,找到问题原因以后就好办了,我们找到Clearwater配置文件/etc/clearwater/shared_config的控制脚本/etc/init.d/clearwater-auto-config-docker,修改相关的组件名,补充了完整的域名记录,最后生成的/etc/clearwater/shared_config内容如下:
# Deployment definitions
home_domain=example.com
sprout_hostname=sprout.default.svc.cluster.local
hs_hostname=homestead.default.svc.cluster.local:8888
hs_provisioning_hostname=homestead.default.svc.cluster.local:8889
xdms_hostname=homer.default.svc.cluster.local:7888
ralf_hostname=ralf.default.svc.cluster.local:10888
chronos_hostname=chronos.default.svc.cluster.local
cassandra_hostname=cassandra.default.svc.cluster.local
# Email server configuration
smtp_smarthost=127.0.0.1
smtp_username=username
smtp_password=password
email_recovery_sender=clearwater@example.com
# I-CSCF/S-CSCF configuration
upstream_hostname=scscf.sprout.default.svc.cluster.local

重新打包镜像并发布以后,终于可以在Ellis界面上生成SIP用户账号了,我们下载X-Lite客户端并配置好SIP账号后,却发现无法登陆成功,报错SIP路由找不到。而Bono与Sprout组件的日志都正常,后来我们研究Bono的启动脚本,修改日志输出级别为DEBUG,此时可以看到完整的SIP报文信息,从这些信息中我们得知原因,是因为SIP路由过程中无法连接scscf.sprout.default.svc.cluster.local,后来我们再去看Docker方式部署Clearwater的命令,发现sprout组件用Docker network-alias的方式注入了3个DNS名称:
sudo docker run -d --net=clearwater_nw --network-alias=icscf.sprout --network-alias=scscf.sprout --name sprout -p 22 clearwater/sprout

这三个DNS名称分别是sprout、icscf.sprout以及 scscf.sprout,这与Clearwater的设计有关,因为sprout组件用子域名icscf.sprout承载I-CSCF,用子域名scscf.sprout 承载S-CSCF服务。如果上述任何一个DNS名字不存在或者设置不对(如设置为一样的DNS名称),则SIP客户端登录Clearwater的时候报错,常见的两个错误是“路由不存在”以及“Too many hops error”,下面是Clearwater的问题邮件列表,可以看出很多尝试在Kubernetes上部署Clearwater的人都遇到这个问题:
image011.png

我们的最初想法是为sprout这个组件定义三个Kubernetes Service,名字分别是:sprout、icscf.sprout以及 scscf.sprout,并且都指向同一个Pod,但很快表明这个思路行不通,因为在Kubernetes中,Service的名字是不能带“.”的,其中一个原因是Kubernetes Service的名称是SkyDNS的一部分,而“.”恰好是子域名的分割符号。解决这个问题有两个办法,第一个办法,第一个办法是修改Clearwater里的相关配置参数,采用类似 icscf_sprout这样的DNS名称而不是子域名来提供I_CSCF服务的寻址;第二个办法是修改Kubernetes的源码,使得Service名称支持“.”。后一个做法很快被否决了,因为Kubernetes发展太快,非官方的源码修改并不靠谱。所以我们采用了第一种做法,首先创建名字为scscf_sprout与icscf_sprout的两个Kubernetes Service,他们与sprout服务共享同一个后端Pod实例,然后再去修改/etc/init.d/clearwater-auto-config-docker脚本中的upstream_hostname参数upstream_hostname,最后重新打包镜像并测试,发现还是通不过。后来我们研究发现,在Clearwater其他组件的启动脚本程序中也有一些固定写死的参数,前后花费了近一周的时间,一一修改查找和修改这些参数后重新打包镜像并进行测试,但最终还是华丽丽的失败了!后来我们查看了Bono与Srpout的源码,才发现源码中有一些icscf.sprout(scscf.sprout)相关的硬编码,意味着仅仅修改配置文件的方式是行不通的!无奈之下我们在Clearwater的github上发了一个Issue,他们也承认Clearwater目前的确有些设计并不能很好的兼容Kubernetes,也随即发起了一个新的分支,尝试解决Clearwater在Kubernetes上的运行问题,但截至当前,这个新的分支除了给出了几个Kuberntes YAML文件,还没有其他动静。
image013.png

我们继续研究可能的解决方案,后来我们设想了一个新方案:绕过Kuberntes,用手工方式在Kubernetes的SkyDNS里插入icscf.sprout与scscf.sprout这两条DNS记录,他们都指向sprout服务的Cluster IP,这样一来这个棘手的问题可能就得以解决。

于是我们开始研究SkyDNS的机制,模仿Kubernetes Service产生的DNS记录,用命令行在Etcd里执行手工插入Key/Value键值对。为了防止手工插入的DNS记录在SkyDNS服务重启后消失,我们把SkyDNS里面用的Etcd地址改为Kubernetes集群所用的独立的Etcd地址。一开始我们插入的DNS记录完全模仿Sprout Service的DNS记录,假如Sprout的ClusterIP是10.1.1.3,则插入的icscf.sprout的DNS记录如下所示:
Key:/skydns/local/cluster/svc/default/sprout/icscf/29512e34
Value: {"host":"10.1.1.3","priority":10,"weight":10,"ttl":30,"targetstrip":0} 

接下来的打包测试结果表明这种方式是可行的,我们的SIP客户端终于连接到了Clearwater上。但观察以后,我们发现一个奇怪的问题:过一段时间后,就登陆失败了。后来排查原因,才发现SkyDNS会周期性同步Kubernetes Service的信息,对于不是Kubernetes Service的DNS记录,他会在同步的过程中删除掉,同步过程影响到/skydns/local/cluster/svc/目录下的所有路径,因此我们后来用了/skydns/local/cluster的路径来定义sprout的子域名,从而绕过了这个问题。

经历了超过3周的反复摸索过程,最终我们打包的Clearwater镜像终于成功发布在Kubernetes平台上,并成功实现了即时通讯、VOIP以及视频通话的演示,以下2张图片给出了Clearwater On Kubernetes的相关细节信息:
9.png

image017.png

下图是用X-Lite客户端成功进行视频电话测试的截图:
WechatIMG90.png

为了让Clearwater集群能正常运行,我们需要注意相关组件的启动顺序,要先启动Etcd、然后memcached、随后Cassandra等,如果顺序不对,也导致Clearwater不能正确运行。此外,需要注意的另外一点是Clearwater的容器采用了supervisord的方式来管理多个进程服务,因此可能出现的问题是容器看起来是正常的,但Clearwater的进程却启动失败的问题。因此我们需要登录到容器内部,查看supervisord控制的各个Clearwater进程的当前运行状态来判断系统是否正常,如下所示:
supervisorctl status
clearwater-group:homestead       BACKOFF    Exited too quickly (process log may have details) 

如果发现系统不能正常工作,我们还需要深入分析Clearwater各个组件的日志来排查错误。

接下来,我们来看看Clearwater on Kubernetes的弹性伸缩问题,由于Kubernetes的微服务架构模型,所以我们只要将Clearwater的相关Service的Pod副本数增加,即可实现在线动态扩容,如下图所示,我们用Kubernetes命令行工具将SIP交互中压力比较大的Bono节点的Pod副本从1个扩展为2个:
11.png

下图是我们建议的Clearwater集群中各个组件对应的Pod副本数:
image023.png

最后,我们也成功在HPE NFV-Director上实现了Clearwater On Kubernetes的新案例,下面是HPE NFV-Director的整体架构图以及Clearwater应用的编排界面(部分):
image025.png

image027.png

image029.png

总结

Clearwater这种复杂的、重量级的IMS平台成功迁移到Kubernetes平台上,并且能正常稳定运行,这个事实充分说明Kubernetes这种先进的基于容器的微服务架构基础平台不仅互联网适用,也适合传统的、密切依赖网络的电信系统的改造升级。一旦旧系统成功改造迁移到Kubernetes平台上, Kubernetes平台强大的弹性伸缩能力和运维高度自动化的优点将会带来可观的收益,包括提高系统的吞吐量和高峰时期业务的承载能力、缩短新业务的上述市场时间、并在很大程度上降低电信运营商的综合运营成本。

1 个评论

关于有依赖的这种应用的部署,kubernetes官方有一个Proposal想解决这种问题,但是一直没有推进,后来我们考虑采用TOSCA来做编排,但是这个标准太过庞大,请问你们是如何控制启动顺序的,只是人工控制还是有别的机制来做的?

要回复文章请先登录注册