谈到基础架构,不同的人有不同的理解。一般说来,我们将支撑应用研发部署的底层软硬件的集合叫做基础架构。它不仅涉及到IDC、机房、机架、网络、主机、存储等硬件资源,也涉及到操作系统、系统软件、日志管理、应用管理监控等基础软件资源。基础架构支持了分布式服务、大数据、云计算、机器学习等基础领域,也成为IT类企业提升生产力、降低成本的核心。近些年来,随着虚拟化、容器化等新技术的不断涌现和发展,随着应用开发模式从单体应用、MVC、SOA到微服务化,基础架构领域发生了翻天覆地的变化,其对应用的灵活性和透明性不断提升,也显著提升了研发效率,降低了研发成本。
从IaaS、PaaS到CaaS
IaaS
基础架构涉及IDC、机房、网络、主机等基础资源、机架设计和交付、网络架构设计、数据架构规划、操作系统、系统软件、环境交付和机器报废替换等。早期应用的开发和部署过程中大部分的工作不是关注于应用的研发,而是关注于基础环境的搭建,包括租用或者购买主机、搭建网络设施、部署系统及日志监控等基础软件。其开发部署效率低,整体成本高。IaaS基于虚拟化技术提供一种“随需应变”使用硬件资源的方式,它同时提供访问物理主机、存储和网络硬件等接口,使得用户能够按需创建其需要的虚拟资源,较精细的控制所需的主机资源。通过IaaS,能够屏蔽物理硬件的位置,同时节省了IDC、网络、服务器的维护成本。相较于传统的基础架构,IaaS对应用研发人员提供了一层透明性。然而,IaaS仍是以资源为中心的,IaaS仅通过虚拟机提供了机器等底层硬件资源层级的抽象,虚拟机之上的操作系统,应用软件等都依赖于研发人员自行部署和维护。虽然IaaS扩容相对容易,但研发人员仍需从架构上考虑机器宕机、机器故障、网络故障等诸多因素,从而保障应用的高可用。
PaaS
虽然Iaas通过虚拟化屏蔽了底层硬件资源,然而,对于应用研发来说,还有很多基础性的问题没有解决,比如应用部署、弹性扩缩容、高可用保障、监控、日志等。因此,PaaS应运而生。PaaS在IaaS的基础上构建了一层中间层,提供了完整的应用开发、部署、运行、监控平台,提供了一系列的基础服务:包括缓存服务、数据库服务等。国内外比较流行的PaaS平台包括Amazon Web Service、Google App Engine、阿里云、腾讯云等。同时,PaaS平台也提供了工具或者类库来帮助研发人员创建应用、访问PaaS平台提供的各种服务。PaaS平台支持高可靠、自动扩缩容、故障迁移,运维成本极低,可以随需满足业务发展需求。相对于IaaS,PaaS平台对应用的支持更近了一步。然而,PaaS也存在缺点,主要体现在:
PaaS 提供的是应用的开发、运行环境,用户看不到底层虚拟机资源,因此一般无法对底层虚拟机资源进行控制。同时,PaaS平台将应用割裂成应用代码和基础环境代码(指应用代码所依赖的系统库、运行环境、中间件等)。其中,基础环境代码基本上是固化和定制化的,由PaaS平台提供。对于典型的PaaS平台来说,不同的基础环境需要提供不同的代码,例如,Java、PHP、.NET等。应用研发人员对基础环境代码没有控制权,对PaaS平台提供的基础环境存在依赖,新的基础环境需要平台提供商提供后才能使用。例如,在PaaS平台没有提供Java 8的基础环境之前,应用研发人员是无法使用Java 8的。这限制了用户的自主性和灵活性,在复杂场景中扩展性不足。
一般说来,PaaS平台都会对部署在其上的应用提供一个强制性的约束规范,甚至会提供一些私有的SDK供应用来使用。同时,PaaS平台提供的各类服务也是平台私有的。当应用开发者使用此类私有的SDK和服务时,其适配成本较高,应用侵入性强,同时其应用会被PaaS平台绑架,迁移成本很高。因此,PaaS平台中的标准化问题非常重要。它不仅需要规范应用部署和运行标准,还需要规范PaaS平台提供的SDK和各种服务,从而减少甚至完全消除平台对应用的侵入性,降低应用的迁移成本。
标准化程度和灵活性不够,限制了PaaS平台的进一步广泛使用。不过,虽然PaaS平台未能够被进一步广泛使用,但是它是从“以资源为中心”到“以应用为中心”的一次有效的尝试。
CaaS
过去几年间,容器化成为虚拟化之后的又一个技术趋势。容器简单、轻量,具备很强的可移植性,能更高效的利用资源,还能够有效的解决基础环境依赖问题,提高研发效率,降低研发成本。因此,容器以其构建、分发和部署的简易性成为基础架构中的关键技术。其中Docker已成为容器技术的事实标准。随着Docker等容器技术的广泛应用,容器编排和管理也受到了越来越多的关注,涌现出了以Kubernetes为代表的开源生态和解决方案。它们试图将目前“以资源为中心”的管理方式迁移到“以应用为中心”的管理方式,并且试图对应用的基础构成组件(例如配置、服务、负载均衡等)进行标准化,从而获得更好的可管理性。容器生态的持续发展使得CaaS(Containers as a service)平台开始涌现。CaaS平台是一种以容器为基础的应用部署、运行和管理的方式,其底层资源可以来自于云服务商,也可以来自于自建私有云。事实上,我们可以把CaaS平台看成以容器作为应用交付标准的PaaS平台。相较于PaaS平台,基于容器的CaaS平台具备如下优势:
前面我们提到,应用可以分为应用代码和基础环境代码。在PaaS平台中,基础环境代码由PaaS平台控制,而在CaaS平台中,基础环境代码的控制权从平台方转移到了应用研发人员手中,应用研发人员可以自由的选择、甚至是自行构建基础环境,而无需依赖于平台端。同时,由于容器所需的资源可以更灵活的控制,同时可以通过Sidecar模式、代理模式、适配器模式、分散收集模式等基于容器的分布式系统中的设计模式进行组合,应用的可组合性大大提高。因此,应用逐步被拆解职责独立的模块,这样单个模块职责更单一,更易于开发和测试,这也间接促进的微服务的发展。容器编排工具提供了一系列手段来自动化的管理应用依赖的其他相关资源(例如负载均衡,甚至是调度),其灵活性大大提高。
社区很早就意识到并且在积极解决容器技术的标准化的问题。标准化组织OCI(Open Container Initialtive)成立于2015年6月,它致力于制定并维护容器镜像规范(Image Specification)和容器运行时规范(Runtime Specification),分别对应应用的构建和应用的运行标准,使得让一个满足容器镜像规范的容器可以在满足容器运行时规范的平台之间进行迁移。同时,标准化组织CNCF(Cloud Native Computing Foundation)也于2015年7月成立。 它主要关注容器的管理,它推出Cloud Native应用,并期望定义能够支持云原生应用和容器的整个基础设施标准,包括容器管理标准、监控标准、分布式追踪标准等。PaaS平台由于标准化问题而未能得到广泛应用,OCI和CNCF则从一定程度上完成了基于容器的应用构建、运行和管理的标准化问题,推动了CaaS的发展,促使基础架构往 “以应用为中心”迁移。
“以应用为中心”中的应用
随着基础架构的透明性不断提升,研发人员越来越关注应用构建,而不是关注于应用部署所依赖的基础架构。虽然基于容器的规范在一定程度保证了应用运行环境的标准化,然而,应用的开发、部署和管理仍然是一件特别复杂的事情,特别是在分布式环境中。
标准化&可移植性
OCI和CNCF定义了容器镜像标准、容器运行时标准、云原生应用等,使得基于容器的应用具备一定的标准化和可移植性。然而,在实践中受限于诸多因素,应用的可移植性仍然较低。
平台本身提供的功能会影响应用的可移植性。容器给用户的视图就是一个操作系统,采用基于容器的方式来构建应用,整个应用的堆栈(包括基础环境)基本上都由开发者控制,因此CaaS平台对应用的侵入性大大降低。不过,监控、日志、安全等平台级的约束存在,还是对应用有一定的侵入性的。例如,平台为了完成日志收集,一般都会对应用的日志有一些规范,比如日志路径等。这些约束一般由平台方给出,或者是由应用研发人员通过某个管理界面进行配置。同时,容器运行时规范仅定义了运行标准容器的最低约束,一般来说,平台在满足容器运行时规范的基础上,会提供了一系列扩展来提供增值服务。虽然应用镜像本身无需调整,但在应用部署时却需要根据提供商的不同而进行配置。例如,同样是使用负载均衡,某平台可能采用LVS服务,而另一个平台采用Nginx,这些约束在不同的平台可能存在差异,这显然影响了应用的可移植性。
同时,平台提供的服务会影响应用的可移植性。应用是一个巨大的生态系统,应用研发人员会不自觉的使用云服务商的提供的各类私有服务,因此存在被平台绑定/锁定的风险,影响可移植性。
因此,标准化工作不仅包含容器镜像的标准化和容器运行环境的标准化,也包括容器部署描述符的标准化,此描述符将描述平台本身提供的功能(包括监控、日志、分布式追踪、容器运行环境扩展等)和平台所提供的服务。通过容器部署描述符的标准化,可以在应用部署描述中同时将应用的监控相关信息和日志相关信息描述好,在应用部署的时候依据这些信息完成监控和日志等相关平台功能的初始化工作,使得应用具备最大的可移植性。事实上,开源监控平台Prometheus就朝这个方向迈出了一步。
动态性
应用由于扩缩容、故障迁移等特征可能会导致其IP和端口随时发生变化,使得应用拓扑结构从原来的静态结构变成动态结构。因此,基于容器的应用具备较强的动态性,这对依赖于它的服务产生了较大的影响,影响服务发现、权限等应用的方方面面。其中,最重要的是服务发现,它涉及到应用与依赖于它的应用的通信问题。为了有效的管理应用之间的通信,一般我们采用反向代理和动态发布/发现机制。
在采用反向代理的方式中,一般通过Nginx等反向代理访问应用,应用发布时通过某种手段动态更新此反向代理的upstream。此种方式能够有效的屏蔽应用的地址和端口,访问者仅通过域名访问即可。不过,由于反向代理的存在,访问链路中多了一个节点,对应用性能会有一定的影响,不适应于需要高性能的应用。反向代理一般用于向外部网络发布应用,而不是处理内部应用之间的网络通信。
在动态发布/发现机制中,一般会将应用的IP地址和访问端口存储于某个集中的位置,例如服务注册中心,应用在启动的时候通过一定的机制来自动完成注册。同时,也提供一个客户端SDK来动态获取和感知应用地址和端口的变化,从而调整客户端的行为。此类SDK一般会提供负载均衡、流量监控、限流、熔断等能力,例如Spring Cloud。然而,此类 SDK一般会绑定到特定语言,且对应用有一定的侵入性。
对于应用来说,我们期望有一种基础架构,能够减少应用的访问链路、降低应用的侵入性。2017年逐步成为热点的Service Mesh 给了我们一个可能的解决方案。Service Mesh是一种基础设施层服务,它专注于处理应用间的通信,负责将应用间的请求安全、快速、可靠地在服务间进行传输,它可以在不修改应用的基础上提供流量监控、限流、熔断甚至是灰度发布、分布式跟踪等能力。一般说来,Service Mesh是一种网络代理,通过Sidecar模式与应用部署在一起,应用无需感知其存在。相较于反向代理,其访问链路中不会多出一个节点,更适应于内部应用之间的网络通信。同时,相较于动态发布/发现机制中所使用的SDK,它没有绑定到特定语言,开发者无需关心由此带来的复杂性以及引入的技术问题,对应用没有侵入性。在过去一年中,Service Mesh 已经成为云原生技术栈中的关键组件,也涌现出了一些开源实现,例如Istio 、Linkerd、Conduit 。业界一些知名公司也开始使用 Service Mesh,如 PayPal、Lyft等。然而,Service Mesh仍是一个不成熟且快速演化的技术,在生产环境中还未得到大规模的验证。
“一次编译,多处运行”
“一次编译,多处运行”是我们在Java世界中一直努力的梦想。事实上,虽然Java提供了统一的二进制编码,但是多处运行却会受制于环境的约束。我们可以将应用看成代码和配置的组合,配置包括应用配置和基础环境配置。显然,配置在不同的环境存在差异。在容器的世界要实现“一次编译,多处运行”的梦想,我们需要很好的管理配置,而在应用初始化时将配置推送到应用端,从而实现配置即服务,通过配置屏蔽不同环境的差异。Kubernetes提供的ConfigMap、Spring Cloud Config、Consul等配置服务提供了这方面能力。然而,ConfigMap和Consul中存储的配置信息是键值对,对于复杂的配置(例如文件类)支持不够。 Spring Cloud Config虽然支持文件这类复杂配置,但是它无法应用启动前对基础环境配置进行调整,例如,基于Tomcat的Web应用的JVM参数。因此,为了达到“一次编译,多处运行”,除了对应用配置等进行管理之外,还需要额外提供基于环境的动态配置能力。
“以应用为中心”中的基础架构
在应用管理的整个生命周期中,一般会存在应用研发者和平台提供者,对于平台提供者来说,它希望尽可能的将平台功能和应用的业务逻辑相隔离,尽可能减少对应用开发者的约束。从应用的开发模式来说,也经历了从单体应用、客户端-服务器端、多层应用、服务化、微服务化的变迁,应用研发过程也越来越倾向于单一职责,越来越聚焦于实际业务,而将安全、可靠性、性能、发布部署等职责交给基础架构。因此,基础架构发展一直持续不断的往应用方向延伸。在往“以应用为中心”的迁移过程中,对基础架构提出了更多的要求:
基础架构的标准化:在大规模的实践中,基础架构在应用部署、灰度发布、资源调度、隔离性、运维监控、日志、安全、管理等基础性的能力仍有待进一步成熟和标准化。应用可通过标准化的方式来描述其所需要的能力,基础架构则通过这些标准化的描述来为应用配置日志、监控、安全等,并执行相应的管理功能。
基础架构的应用管理能力:基础架构应该可以管理服务、任务、大数据平台和算法框架等,通过提供通用的框架,降低相关组件、框架等的部署和优化成本,广泛支持在线服务、离线计算、流式计算、实时计算到算法决策等多种类型的业务。
基础架构的自管理能力:基础架构的稳定性对于保证应用的运行至关重要。除了对应用进行管理之外,基础架构需对其自身的相关组件进行自我诊断、自我修复和自我优化,使得其本身能够保持健康的状态。
动态资源分配和调整:提供自动化智能化的手段来管理并动态调整应用所需的CPU、内存等资源,使得应用研发者将更多的精力关注应用的业务研发,而不是应用的性能优化。同时,通过动态资源分配和调整机制,能够帮助节省成本。
多环境管理:多环境管理不仅指私有数据中心、混和云等多个线上环境、也包括应用的开发、测试环境。这些环境可能由不同云提供商提供,跨越多个地域,基础架构需要提供环境和地域感知的应用部署和动态迁移,并尽可能的屏蔽不同环境的差异(例如,在测试环境中,会要求计算测试覆盖率,线上环境则无此要求)。
总结
长久以来,应用交付的核心诉求一直是更快的迭代速度、更快的开发效率、更高的易用性和可迁移性,更低的整体成本。从IaaS,PaaS到CaaS,我们逐步摆脱了对资源的关注,从不关注机房网络机架等,到不关注应用所使用的资源的物理位置。虚拟化、容器化和云计算等技术演进使得应用研发和基础架构两个方向越来越独立,耦合性越来越低,促进其从“以资源为中心”往“以应用为中心”迁移。其中,基础架构负责管理应用的生命周期,管控应用的部署、发布、日志、监控、动态扩缩容,应用依赖、应用配置等,保障应用的高可用、高性能,提高应用对基础架构的透明性,提高基础架构的灵活性。
未来,应用研发人员更关注于快速交付应用,关注于应用是否满足其定义的SLA和成本等约束,聚焦于使用基础架构,而不用关注底层的基础设施,不用关注应用运行在Amazon Web Services或者是阿里云之上。也许有一天,我们仅需要关注应用研发,而将包括主动性能优化之内的其他任何事情都交给基础架构。
CIO之家 www.ciozj.com 公众号:imciow