云计算是目前主流的IT技术,云计算提供的应用弹性伸缩和快速部署的能力是互联网的关键能力,受到互联网企业以及传统数字化转型企业的欢迎。在云计算的实践过程中,通过不断的总结经验,业界提出了“云原生应用”的概念。云原生应用就是通过一整套的设计理念,打造基于云计算环境的最佳应用实践。在云原生应用中,容器平台扮演这重要的角色。通过容器提供的轻量级运行环境和标准化交付能力,实现应用的重复、一致性交付、部署、运维,实现需求的快速交付。
目前很多企业都在打造自己的私有容器云平台,我们在这个过程中也曾经遇到很多问题,通过解决这些问题和事后分析,总结了一些经验以及想法,在这里抛砖引玉拿出来和大家一起讨论。
1
明确建设目标
在进行任何IT系统建设之前,必须明确系统建设的目标,容器云平台也是一样的。IT系统的建设目标通常是根据组织的战略进行设定的。不同的企业战略决定了不同的IT系统建设目标和原则。企业的战略决定了IT系统的建设目标,IT系统的建设目标决定了评估的原则。举个例子,企业的战略是数字化转型、鼓励业务创新,那么企业的IT系统建设的目标就是满足业务需求快速响应,支持业务的快速试错。IT系统建设需要遵循快速部署弹性伸缩的原则。
明确容器云建设的目标,可以为后续在云平台建设过程中的决策提供参考原则,避免容器平台的建设偏离了方向,导致项目的失败。在项目实施之前,在组织内部明确这一个目标是很重要,可以保证不同部门的诉求是基本同一个方向的。
容器云是目前最主流的云计算技术之一,但是在技术领域没有“银弹”,容器云并不是适用于所有的场景,在容器云建设前,弄清楚建设容器云的目的,对于后续的决策和规划起着决定作用。容器云有自身的优势,在建设前进行一个简单评估是很有意义的,在以下的问题中,如果得分过低,容器云可能不是目前最急迫的任务:
这个表格中根据实际选择每个目标的重要程度,根据每个目标的重要程度得分乘以权重,然后相加得到的结果。
容器云,微服务架构,持续交付和DevOps是云原生应用架构的四大支柱。我们建设容器云的目标就是能够实现云原生应用。如果所得的分数超过75分,容器技术是我们组织当前的战略,否则,需要考虑建设的必要性。
记住我们对容器云平台的定位是非常重要的,避免了在后续的工作中偏离方向或走弯路。
如果不明确这个目标,可能会导致一个误区,就是试图将容器云作为一个通用的平台,试图使用容器云来接管所有的应用系统,这会导致很多问题的复杂化,最终不仅不能发挥容器云的优势,甚至会导致项目的失败。
2
容器云建设前需要具备的能力
在开始云平台建设之前,评估一下组织具备的IT能力,可以更好的推动后续容器云的建设。
2.1 应用的云原生成熟度
容器云是云原生应用的一个支柱,应用的架构会直接影响容器云的推广和应用效果。应用必须具备一些基本的特性和能,才能够更好的发挥云的优势,我们称之为云原生的成熟度。云原生应用的开发不只是架构和工具的普及,最重要的是设计思维的转变。云上应用的设计不同于以往的主机系统和应用集群,应用上云之前,最好已经达到了“云就绪”的水平,否则会使得容器平台的建设和应用的迁移过程会有很多困难。
2.2 持续交付的文化
云原生的一个目标就是支持业务的快速创新。要支持快速创新,除了容器云提供的轻量级容器和快速的服务编排技术外,持续交付能力也是非常重要的。成熟的容器云平台中,都将持续集成工具作为云平台的一个重要组成部分。持续交付不是只是工具的建设,更重要的是组织端到端流程的改造。企业文化的改变并非一朝一夕就可以改变的。在实现容器云平台之前,需要在组织内部达成共识,取得领导的认可和支持,慢慢形成持续交付的文化。
3
容器云的评估考量
容器云的技术选型是容器云平台建设的一个重要工作,容器技术经过几年的发展,涌现了多套解决方案。容器实现和容器编排管理是容器云平台的两项关键技术。
容器技术方面有目前最流行的Docker容器,Pivotal主导的Garden容器,开源社区维护的Rocket容器等。在容器编排技术方面有Google开源的Kubernetes,Docker企业版使用的Swarm,Cloud Foundry中提供的Diego,Apache的开源项目Messos等,大部分的容器云厂商的容器云都可以支持不同的容器编排实。
在建设容器云之前,可以重点从以下的几个方面进行评估:
3.1 所选技术平台的发展前瞻性
云计算的基础设施,比以往的任何基础设施技术有着更快的技术迭代速度。非主流的技术会很快的被淘汰。选择的技术是否符合技术主流,是需要评估的一大重点。
目前容器技术采用的基本上是基于开源技术的提供的解决方案,这些开源项目一般都受到几个大型IT企业,比如Google,Facebook等的支持。对于容器平台的技术前景,目前主要是根据各大IT厂商的支持和开源社区的热度进行评估。
容器云平台的技术流派从目前看来,Docker和Kubernetes的解决方案,是最受业界认可的。
Docker是一个构建在LXC之上的,基于进程容器(Process container)的轻量级VM解决方案。在LXC的基础上, Docker额外提供的Feature包括:标准统一的打包部署运行方案, 历史版本控制, Image的重用,Image共享发布等等。
Kubernetes(k8s)是自动化容器操作的开源平台,这些操作包括部署,调度和节点集群间扩展。Kubernetes不提供容器实现,而是将其他容器技术作为低级别组件。Kubernetes不仅仅支持Docker,还支持其他的容器技术。使用Kubernetes可以:
自动化容器的部署和复制
随时扩展或收缩容器规模
将容器组织成组,并且提供容器间的负载均衡
很容易地升级应用程序容器的新版本
提供容器弹性
Kubernetes并不是唯一的容器编排引擎,其他的选择包括Apache Mesos,Docker企业版本的Swarm。
3.2 基础设施对接方案
在容器云的具体实施方案中,如何与底层基础设施进行对接也最重要的技术决策之一。容器云的底层基础设施方案主要有两种:
直接运行在物理设备之上,可以提供更好的应用性能,适合与对性能和带宽敏感的应用,如数据库和大数据应用。这种方案的最大问题是如何实现物理节点的自动化管理;
运行在虚拟层之上。将容器安装在虚拟机之上,可以提供更好的灵活性和可扩展性。
由于我们建设容器云的目标就是支持创新业务的快速部署和弹性伸缩,所以采用虚拟层的方式,能够实现最大的灵活性和可伸缩性,同时可以更好的实现自动化运维。
如果组织已经建成了基础设施即服务,在建设容器云服务时,需要考虑容器云平台与现有IaaS平台的对接,对接包括但不限于容器云管理中心和底层服务接口的对接,操作系统的版本兼容,存储方案的支持等。举个实际的例子,在建设容器云平台时,容器的存储方案是一个比较难选择的方案。容器可以通过迁移来实现故障转移,如果使用直接挂接本机物理服务的存储,在IO性能上可以达到最优,但是损失了底层物理机故障时的容错能力;如果使用vSAN等虚拟存储技术,可以实现最大程度的灵活性和横向扩展性,但是IO性能容易受到其他应用的影响,同时vSAN容易形成单点故障。一个解决方案是存储计算分离方案,在牺牲一些性能的条件下,获取更好的弹性。
3.3 厂商选型
金融行业建设容器云一般会引入厂商支持,在技术方案已经基本确定的情况下,对厂商的选择是一个重要的工作。每个金融机构对与厂商的资质都有一套完整的认证体系。这里补充几点云容器平台特别需要考量的。
容器云平台作为基础设施,是一个中长期的项目,一旦建设成,需要一段较长的运行时间,所以平台的技术稳定性尤其重要。在容器云选型的时候,需要将厂商的规模和对容器业务的投入程度需要重点考量。同时产品是否开源,也是在评估厂商的时候的一个加分项。同时,在顶层应用设计的时候,要尽量避免与底层过度耦合,避免过于依赖底层技术,导致后续迁移成本过高。
容器云跟微服务、DevOps紧密相关,选择容器云合作伙伴,不仅仅是选择一个容器厂家,同时也要求厂家在微服务、DevOps方面有丰富经验,并具备咨询、设计、开发的能力。
经过慎重选择,最终选择由在DevOps、微服务、容器方面均有丰富经验的本土厂商BoCloud博云提供了DevOps设计和支撑、传统应用和微服务应用上云设计和实施等,最终也达到了很好的效果。
4
容器云建设策略
在云平台实施过程中,由于主导的部门不同,会形成三种策略:
先建设平台,再上应用。这种方式通常由数据中心主导的,基本上的策略就是希望能先将旧应用直接迁移到容器环境下运行,再进行应用改造。这种方式的好处是统一平台,运维保障级别高;问题是由于保证旧应用的迁移,需要在容器云平台上做很多改造,例如加入重量级J2EE容器的支持等,一不小心就会偏离了容器云的初衷。
应用云原生改造驱动容器云建设。这种方式通常是由开发主导,通过对现有的应用进行微服务改造的同时引入容器支持。这种方式的好处是云的推广阻力小,能发挥容器云的优势;问题在于容器技术分散,不同的项目可能使用不同的技术,不利于统一的运维管理,而且由于前期没有容器云平台的支持,应用改造的难度相对较大。
开发运维一体化。由DevOps团队主导,根据实际项目的需要引入相关的技术能力,实现开发运维的同步。问题是,这种方案不太符合现实情况,目前传统金融IT的开发运维一体化还没有实际落地。一个折中的方案是由架构管理部门统一进行规划云原生应用和容器云建设。国内某商业银行的容器云建设,在15年由架构部门进行了统一的云平台建设规划,同时启动了微服务的研究和试点。建立云平台的开发部门,负责行内云平台的开发和运维,避免对厂商的过度依赖,兼顾开发和运维两方面的需求。
5
应用上云策略
对应用迁云的讨论很多,不同的企业有不同的上云策略。根据经验,直接利用云服务器替换物理机并不是使用云的正确姿势。以往基于主机和集群的应用的可用性都是依赖于底层的硬件和中间件,而在云上,底层的容器是不可靠的,云最大的特点就是通过故障的漂移来实现整体的可用性。另外要充分发挥容器云弹性伸缩,快速部署的特点,上层应用设计需要满足一系列的设计原则,遵循一系列的设计模式。满足这些设计模式和设计原则的应用,我们称之为“云原生应用”。
5.1 新应用上云策略
对于新的系统,需要满足云原生的设计规范。云原生应用本质上是一种分布式系统,并不能适用于所有的应用场景。适合采用云原生架构的系统才适合于容器云平台。
Cloud Native Application(云原生应用)是当下一个热门名词,简单而言就是针对云计算的特性,来设计应用架构,并优化应用的交付、运维流程。Linux基金会旗下的云原生计算基金会 CNCF(Cloud Native Computing Foundation)开宗明义地描述了云原生系统所具有的几个关键特性:
Container packaged:容器化的交付方式,保证开发、交付和运维的一致性
Dynamically managed:自动化的管理,提升系统利用率、降低运维成本
Micro-services oriented:松耦合应用架构,提升系统的敏捷性和可维护性
云原生应用可以满足我们的几个关键诉求:
高可用:在不可靠的基础框架上面建设高可靠的应用系统。系统没有故障单点,另外还需要具有良好的自我恢复能力。
弹性伸缩:能够让应用从容应对峰值流量,同时保证基础设施的使用率。
快速迭代:天下武功唯快不破。在互联网时代,快速迭代、最小化试错成本是核心竞争力。
云原生应用不是一个单一的技术架构问题,应用上云,并发挥云的最大优势,不只要有容器平台,还需要相应的软件架构,以及DevOps的文化支持。
在云原生应用中,容器平台扮演这重要的角色。通过容器来解耦应用和运行时环境,使得应用可以在不同的环境中可以重复、一致地交付、部署、运维,从而更好地支持DevOps和弹性。
云原生应用通过微服务的方式将应用系统逻辑分解为一组松耦合的服务,使得每个服务可以独立开发、部署、演进和伸缩。强调服务的无状态设计,服务无状态才能让业务逻辑可以水平扩展,并且出现故障的时候可以快速恢复。对于云原生应用的设计原则,可以参考Adam Wiggins的12 Factor。
持续交付是云原生应用的要求,持续集成工具应该是作为容器云平台的一部分进行建设。如果组织已经有了部署流水线,需要采用最轻量级的方式接入到已有的部署流水线上。实施过程中遇到过一个问题,部署流水线被设计成为可以支持组织内所有的平台,导致流水线实现的过于臃肿,失去了容器云快速部署的优势。
5.2 旧应用的上云策略
实际的应用上云是一个逐步迁移的过程,既要关注新的应用,又要考量旧系统的迁移。
应用确定了迁移在容器云上后,需要根据微服务的设计原则对应用进行解耦。微服务的服务强调根据业务功能,而不是处理流程来进行服务划分。对系统进行微服务解耦是一个复杂的过程,要求对业务领域有着深厚的知识积累。了解一些设计方法论,比如领域驱动设计(Domain Driven Design)对于设计出一个好的微服务应用系统很有帮助。
在旧应用上云的实践中,我们尝试过两种策略:一种是先将原来的传统应用不做大的改造,直接迁移到云上;一种是伴随着应用的微服务改造方式实现应用上云。
第一种策略是基于快速上云的考虑,可以最快的实现上云的目标,同时可以让开发人员熟悉云应用的开发部署方式。由于不需要对应用做大的改造,迁移的风险相对较低,对于业务影响比较小,因而上线阻力小,适用于破冰项目。这种方式的问题我们前面已经提过了,为了能够满足传统应用的运行要求,需要对容器云做出修改和定制,很多这方面的修改,是有悖于容器轻量级运行环境的初衷的,导致容器云过于重量级,失去容器的优势。
另外一种是采取逐步迁移传统应用的策略,通过逐步对现有的应用进行部分重构,将新增的功能和需求变动比较大的原有功能通过微服务实现,通过API网关与旧的单体式应用集成。通过持续的重构,旧的单体应用在整个架构中比例逐渐下降直到消失或者成为微服务的一部分。这种方式尽管有挑战,但是比起重写的风险小很多。Martin Fowler将这种现代化策略称为绞杀(Strangler)应用,名字来源于雨林中的绞杀藤(strangler vine),也叫绞杀榕(strangler fig)。绞杀藤为了爬到森林顶端都要缠绕着大树生长,一段时间后,树死了,留下树形藤。围绕着传统应用开发了新型微服务应用,传统应用会渐渐退出舞台。