专栏名称: 分布式实验室
最专业的Docker文章,最权威的Docker新闻。关注容器生态圈的发展。
目录
相关文章推荐
51好读  ›  专栏  ›  分布式实验室

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

分布式实验室  · 公众号  · 后端  · 2017-03-22 07:44

正文

背景

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

自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轮询的负载均衡机制在这里发挥了重要作用。

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个容器!

下面我们分析一下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 [email protected]
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 [email protected]
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上的一些问题我们可以验证这一点:

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

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

上述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服务的端口映射到公网上,供外部用户使用,下面是建议的部署示意图:







请到「今天看啥」查看全文