云原生微服务应用的平台工程实践
The following article is from 阿里巴巴中间件 Author 纳海
微服务应用云原生化
微服务是一个广泛使用的应用架构,而如何使得微服务应用云原生化却是近些年一直在演进的课题。国内外云厂商对云原生概念的诠释大同小异,基本都会遵循 CNCF 基金会的定义:
云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式 API。
这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段,云原生技术使工程师能够轻松地对系统作出频繁和可预测的重大变更。在云原生领域,有一个广泛知晓的 Pets vs Cattle 比喻:在传统运维上,我们习惯把服务器当做“宠物”,这些服务器一旦出现问题我们会非常紧张;而在云原生阶段,服务器更应该被当做“牛群”,它不再具有特殊性,出现问题后可以通过自动化机制进行替换修复。在 Kubernetes 上,这一点尤其体现的淋漓尽致。如果某个 Pod 容器出现问题,那么我们应该能通过 Liveness 探针检测到容器异常,然后完成容器退出,并自动重启容器。
云原生浪潮的新问题
云原生浪潮释放了巨大的技术能量,但同时也带来了许多新的问题,这些问题广泛存在于企业的开发、测试、CICD 和运维场景。首当其冲的是 DevOps 实践。
如何构建这样的平台和工具链,称为平台工程(Platform Engineering)。如果说云原生和 DevOps 带来了各种各样的定义,对研发人员是一个熵增的过程,那么平台工程就是屏蔽复杂定义、提供简单清晰交互的熵减工程。
平台工程
平台工程概念并非最近才诞生,这个词早在 2011 年已经有人开始使用(见 what-is-platform-engineering[1]),并在 2017 年见之于技术雷达(见 platform-engineering-product-teams[2])。而在云原生技术日益繁杂的今天,容器、编排、服务网格、可观测等各种产品及工具涌现,CNCF 云原生版图已经有超过 1000 个产品,在这种背景下平台工程的诉求愈加强烈。
翻译过来也就是,平台工程是设计和构建工具链和工作流的学科,使软件研发组织能够在云原生时代具备自服务能力。平台工程师提供一个称为“内部开发者平台”(IDP,Interal Developer Platform)的集成产品,涵盖整个应用生命周期的运维需求。
开发场景; 测试场景 CI/CD 场景;
开发场景工具链
在开发场景上,我们认为工具链的核心是程序员的 IDE。在方向上,Cloud IDE 当然是酷炫的,它是一种在线集成开发环境,允许开发人员通过浏览器即可完成开发、测试和应用部署。但实际上国内采用 Cloud IDE 进行开发的企业并不多见,根本原因在于 Cloud IDE 的体验还比不上本地 IDE 的体验。当然在某些场景下 Cloud IDE 可能是唯一方案,例如要求代码不落盘的高密项目。但在综合考虑下,我们还是暂不提供 Cloud IDE 的解决方案。
开发联调
本地调试:通过 IDE 一键启动本地 Nacos 注册中心[5],完成本地开发调试。对于简单的应用,开发人员在本地就可以通过这个注册中心完成调试,无其他外部依赖,简单且高效。
端云互联:通过 IDE 在本地启动应用,底层通过插件代理自动跟云上网络打通,本地节点跟云上其他微服务节点具备同样的能力,可相互调用。这种方式对于复杂微服务开发调试非常有用,研发人员的调试效率大大提高。
根据实际使用情况来看,这两个能力都备受客户青睐,而端云互联能力更是命中微服务开发调试的痛点。端云互联不仅可以使得应用跟云上互联互通,还把云的能力下沉到研发人员的开发端,比如分布式链路跟踪和全链路流量控制等等。
应用部署
API 调试
API 调试也集成了分布式链路追踪能力,如果中间链路调用出错,点击界面上的调用链即可一键打开调用链页面,异常信息一清二楚。
测试场景工具链
在测试场景,我们优先关注接口级别测试和集成测试。而集成测试本身也是依赖对每一个系统接口的测试,并且对接口响应结果进行断言,最终生成整个系统的质量报告。
CI/CD 场景工具链
CI/CD 即持续集成(Continuous Integration)和持续交付(Continuous Delivery),《The Product Managers’ Guide to Continuous Delivery and DevOps》[10]对持续集成、持续交付和持续部署三个概念定义如下:
持续集成:强调开发人员提交了新代码之后,立刻进行构建和单元测试。根据测试结果来确定新代码和原有代码能否正确地集成在一起。
持续交付:在持续集成的基础上,将集成后的代码部署到类生产环境,并完成自动化测试,确保可以以可持续的方式快速向客户发布新的更改。如果在类生产环境验证通过后,证明该制品已达到可交付状态,可手工部署至生产环境。
持续部署:在持续交付的基础上,把部署到生产环境的过程自动化。
CI/CD 领域的产品有 ArgoCD、Jenkins 和云效等开源和商业化产品,这些产品都具备了很高的成熟度。开发者只需要在这些产品的流水线上设置构建、单元测试、集成测试和环境部署等多个流程即可。而在这些流程中,最容易出错、损失最大的莫过于生产环境部署。
单批部署:一次性把应用中所有节点都更新到新版本。此部署动作常用于开发测试环境,生产环境不建议使用。
分批部署:按照所设定的批次和间隔来逐步更新应用节点,可以在完成上一批次后,选择手动或自动进行下一批次发布。
金丝雀部署:在分批部署基础上,将第一批节点设置为金丝雀节点,支持设置金丝雀节点的流量比例、接口参数或者泳道策略,在满足条件的情况下生产流量才会转发到金丝雀节点。比如,如果我们希望只有广东地域的客户端请求才转发到金丝雀节点,那么就可以针对流量中的特征(例如参数中带有 Guangdong 字符)来制定金丝雀流量策略。
目前我们支持 Intellij IDEA、Maven、Jenkins 和云效等多种工具来部署至环境中:
Intellij IDEA https://help.aliyun.com/document_detail/2362337.html
Maven https://help.aliyun.com/document_detail/186680.html
Jenkins
https://help.aliyun.com/document_detail/171313.html
云效
https://help.aliyun.com/document_detail/199501.html
例如使用云效实现应用的持续集成和部署,我们只需要将开发好的新版本应用代码提交到代码库,云效流水线 Flow 会监听代码事件,当满足触发事件时会触发流水线运行,部署新版本应用到 EDAS K8s 环境。
总结
事情从来都不是一蹴而就的,搭建平台需要相关领域的专业知识和持续的人力投入才有可能做好。当我们选择构建一个平台时,我们构建的是一个有生命的东西,组织架构变迁和技术的更新换代都会对 IDP 产生影响。构建 IDP 不是一锤子买卖,这些变量在最初就要有充分考虑,否则 IDP 最终会演变成一个烂摊子。在云原生化改造过程中,我们可能会遇到很多新的概念,诸如 Helm、IaC、Terraform、Kubernetes 等等。如果时间和成本对你比较重要,而且团队不是这方面的专家,那么选择一个成熟的 PaaS 平台可能是一个更好的选择。
明确使命和角色。 像对待产品一样对待你的平台。 关注共同问题。 粘合剂是有价值的。 不要重复造轮子。
除此之外,我们提出一点建议:云原生已经非常复杂,平台工程应当在保留灵活性的同时尽量暴露简单清晰的交互,而非一味增加新的逻辑定义以增加研发团队负担。EDAS 产品一直遵循着这个设计理念。一方面我们支持松管控,支持你可以用最云原生的方式来灵活运维;另一方面,我们暴露最简单的上层应用模型,屏蔽底层的复杂定义,并将云的能力集成到研发团队最熟悉的工具里,做到润物细无声。
https://diff.wikimedia.org/2011/08/17/what-is-platform-engineering/
https://www.thoughtworks.com/radar/techniques/platform-engineering-product-teams
https://platformengineering.org/blog/what-is-platform-engineering
https://www.infoq.cn/article/qepvmrlawsw735wwunmb
https://github.com/alibaba/nacos
https://help.aliyun.com/document_detail/2362342.html
https://help.aliyun.com/document_detail/2362337.html
https://help.aliyun.com/document_detail/2362352.html
https://help.aliyun.com/document_detail/2264132.html
https://www.mindtheproduct.com/what-the-hell-are-ci-cd-and-devops-a-cheatsheet-for-the-rest-of-us/
往期推荐