3.1 云(原生)平台的发展
使用平台来支持软件的开发和运维并不是什么新鲜事。已经被大规模使用的Java 2平台企业版(J2EE)从发布到本书撰写时已经有20年了,也有了多个主要版本。JBoss、WebSphere和WebLogic是这种开源技术的商业产品,分别为RedHat、IBM和Oracle带来了数十亿美元的收入。许多其他专有平台,例如来自TIBCO软件公司或微软公司的平台也同样成功,并为它们的用户提供了帮助。
但是,正如需要新架构来满足现代软件的需求一样,也需要新的平台来支持相应的新的开发和运维实践。下面快速回顾一下我们是如何发展到今天这一步的。
3.1.1 从云计算开始
可以说,云平台是从Amazon Web Services(AWS)开始的。它在2006年发布了第一批产品,其中包括了计算(弹性计算云,Elastic Compute Cloud,简称EC2)、存储(简单存储服务,Simple Storage Service,简称S3)和消息通知(简单消息队列服务,Simple Queue Service,简称SQS)服务。这绝对是一个游戏颠覆者,因为开发人员和运维人员不再需要购买和管理他们自己的硬件,而是可以通过自助式的服务界面,在很短的时间内获得所需要的资源。
起初,这个新平台代表着现有的客户端-服务器模式会转向可访问互联网的数据中心模式。软件架构并没有发生巨大的变化,相关的开发和运维实践也没有变化。在云的早期发展阶段,更多的是提供计算能力。
几乎在同时,云的特点开始对在传统基础设施上构建的软件产生压力。AWS在数据中心上使用了大量的普通硬件,来代替“企业级”服务器、网络设备和存储器。使用更便宜的硬件是以令人满意的价格提供云服务的关键,但随之而来的是更高的失败率。AWS通过其软件和产品弥补了硬件弹性能力的降低,并向用户提供了一些抽象概念,比如可用区(Availability Zone,简称AZ),这使得即使在基础设施并不稳定的情况下,在AWS上运行的软件依然能够保持稳定。
重要的是,在将这些新的概念(例如,可用区或者区域)向用户公开后,用户就承担了恰当应用这些概念的责任。我们当时可能没有意识到,但是随着平台在应用程序接口(API)中公开这些新的抽象概念,就逐渐塑造出一个新的软件架构。人们开始尝试编写在这类平台上运行良好的软件。
AWS实际上创造了一个新的市场,而谷歌和微软等竞争对手花了两年时间才有所反应。当它们加入进来的时候,又各自带来了新的产品。
谷歌首先发布了谷歌应用引擎(Google App Engine,GAE),这是一个专门为运行Web应用程序而设计的平台。它所公开的抽象概念(API中的一级实体)与AWS有明显区别。后者主要公开了计算、存储和网络接口,例如,可用区到服务器组的映射,允许用户控制服务器池的绑定或解绑。相比之下,GAE的接口中没有(现在依然没有)提供对这些原始计算资源的任何访问,也并不直接公开底层的基础设施资产。
微软则推出了自己的云平台Azure,提供了运行中等信任(Medium Trust)代码等功能。与谷歌的方法类似,中等信任机制限制了用户对计算、存储和网络资源的直接访问,负责为用户创建运行代码的基础设施。这使得平台能够限制用户代码对基础设施造成的影响,从而提供一定的安全性和弹性保证。现在回想起来,我认为谷歌和微软的这两款产品,是从云计算过渡到云原生的最早的两款产品。
谷歌和微软最终都提供了公开基础设施能力的服务,如表3.1所示,而AWS则开始提供具有更高抽象能力的云服务。
表3.1 主要云平台服务商提供的基础架构即服务(IaaS)产品
这三个服务商在21世纪初上演的“大戏”,不约而同地暗示了软件架构即将发生的重大变化。作为一个行业,我们正在进行尝试,看看是否有可能利用数据中心的资源,在生产力、敏捷性和弹性等方面获取更大提升。这些试验最终导致了一个新的平台模式出现,即云原生平台,它具有更高层的抽象概念、与之相关的服务以及随之而来的优势。
本章将开始介绍云原生平台,让我们先从云原生平台提供的更高层抽象开始。
3.1.2 云原生的“拨号音”
开发人员和应用程序的运维人员关心的是,提供用户服务的系统是否正常运行。在过去的几十年中,为了提供令人满意的服务级别,他们不仅需要正确配置应用程序的部署,还要正确配置底层的基础设施。这是因为他们可以使用的原语(primitive),与一直使用的计算、存储和网络组件的相同。
但是,正如云平台的发展所暗示的那样,这种情况正在改变。为了清楚地理解这种差异,我们来看一个具体的例子。假设你已经部署了一个应用程序,为了确保它运行正常,或可以在出现问题时加以诊断,你必须能够访问它的日志和指标数据。
正如前面已经说过的,云原生应用程序会部署多个副本,这也是为了适应变化和扩大规模。如果你在一个底层是传统基础设施的平台上运行现代应用程序,那么必须通过暴露的传统数据中心抽象(例如主机、存储卷和网络),来获取或者访问日志。
图3.1演示了这些步骤:
1 确定应用程序的实例在哪些机器上运行,这通常存储在一个配置管理数据库(CMDB)中。
2 确定打算诊断行为的应用程序实例在哪些机器上运行。有时可以一次检查一台机器,直到找到正确的机器为止。
3 找到正确的机器后,必须进入一个指定的目录,找到要查找的日志。
运维人员要打交道的工作实体分别是CMDB、主机和文件系统目录。
图3.1 访问一个传统基础设施平台上的应用程序日志的操作非常烦琐
相比之下,图3.2显示了当应用程序在云原生平台上运行时运维人员的感受。这个过程变得非常简单,只需要请求应用程序的日志。你发出的请求是以应用程序为中心的。
云原生平台承担了以前由运维人员承担的一部分工作。这个平台本身就可以理解应用程序的拓扑结构(以前是保存在CMDB中),通过它来聚合所有应用程序实例的日志,并为运维人员提供他们感兴趣的实体的数据。
关键在于:运维人员感兴趣的实体是应用程序,而不是运行应用程序的机器或者保存日志的目录。运维人员需要的是要诊断的应用程序的日志。
你在这个示例中看到的,分别是以基础设施为中心和以应用程序为中心的不同效果。应用程序的运维人员的体验不同,是因为他们在工作中使用的抽象概念不同。我喜欢把这种情况叫作“拨号音”不同。
图3.2 在一个以应用程序为中心的环境中,访问应用程序的日志非常简单
定义 基础设施即服务(IaaS)平台的“基础设施拨号音”:一个提供访问基础设施(例如,主机、存储和网络)的接口。
定义 云原生平台的“应用程序拨号音”:一个让应用程序成为开发人员或运维人员最主要的交互对象的接口。
你肯定已经看到了图3.3中堆叠在一起的方框,它们清楚地划分出了三层,并最终组合在一起为消费者提供数字化解决方案。虚拟化的基础设施使计算、存储和网络抽象的使用变得更加容易,从而将底层硬件的管理留给了IaaS服务商。云原生平台进一步提高了抽象程度,允许用户更加轻松地调用操作系统和中间件的资源,并且将底层计算、存储和网络的管理留给了基础设施服务商。
图3.3中方框两边的注释说明了这些抽象在运维方面的差异。与通过IaaS接口将应用程序部署到一台或多台机器上不同,在云原生平台上,运维人员只需要部署一个应用程序,而平台根据可用资源来分配请求的实例。运维人员不需要配置防火墙规则来保护运行指定应用程序的机器,只需将策略应用于应用程序,由平台来负责保护应用程序容器。运维人员不需要访问机器来获取应用程序的日志,而是可以直接访问应用程序的日志。与IaaS平台相比,云原生平台的应用体验差别是显而易见的。
图3.3 云原生平台在基础设施上做了进一步抽象,使得运维人员只需要关注应用程序,而不需要关注对这些底层基础设施的管理
本章后面将要讨论的内容,以及我鼓励你在构建云原生软件时使用的环境,都指的是云原生平台,即一个能发出“应用程序拨号音”的平台。目前,有几个平台可供你选择。对于大型的云服务商,可选的有Google App Engine、AWS Elastic Beanstalk和Azure App Service(它们都没有得到特别广泛的使用)。Cloud Foundry是一个开源的云原生平台,在全球范围内的大型企业中拥有众多的客户。一些服务商也会提供商业产品(例如,Pivotal、IBM和SAP等)。[1]虽然这些平台的实现各不相同,但都基于一个共同的哲学基础,并且都提供了“应用程序拨号音”。