申明
本站点所有文章,仅代表个人想法,不代表任何公司立场,所有数据都来自公开资料
转载请注明出处
去年年底我们在深圳内部一起探讨了很多 DevOps 在客户实际落地过程中的挑战及我们能帮客户做哪些事情,非常惊喜看到不断有经验丰富的新伙伴加入,也有很多令人耳目一新的实际客户项目落地,社区、AWS 开发者工具以及理论和工程实践的不断完善,客户在云计算大时代背景下落地 DevOps 有了更好的技术基础,本文借助客户沟通机会,更新下我们在 DevOps 企业研发团队效能这块的思考和总结,由于时间篇幅,开头阐述研发过程的挑战,创新的困境,后半部分主要集中在工具层面的探讨。
汽车行业创新:软件驱动
朋友圈土豪,最近又惦记上新纯电玩具 BMW i4,巧合的是刚结束不久的 AWS reinvent 2019 大会上,BMW Group 同事分享了一个数据平台建设主题 AUT306_Creating a data-driven, cloud-native ecosystem at the BMW Group,电动车+不断远程软件升级的大时代越来越快的融入我们的生活。
下面我们可以欣赏下 BMW 的一个视频广告:
汽车行业的竞争规则在不断被改写:汽车持续从一个纯硬件产品向软件驱动的电动智能设备发展;国内也在紧密制定智能网联汽车(ICV)的行业标准,汽车作为交通出行体验的载体,需要持续加持物联网(车联网)、大数据和人工智能等技术,以改善提升车主整个服务旅程~~
研发驱动创新的挑战
我们探讨的前提是,哪怕是“传统”的制造行业,我们也要正视软件研发在整个业务创新方面帮助,如 BMW 从车联网做起,到如今更智能的车主语音交互,背后有大量的技术研发投入;软件研发的复杂度通常是非专业玩家容易轻视和低估的,整个软件交付复杂度涉及业务复杂度、技术复杂度以及项目管理复杂度;在软件研发和交付领域,有相当多的理论和实践指导,比如设计模式,敏捷软件开发原则、模式与实践,TOGAF,领域驱动设计等等;关于挑战我们来看看几个具体的例子:
代码急剧膨胀 vs 交付周期
网上有很多单体架构和微服务架构的探讨,当代码量到达一个恐怖量级,就不是一两个大牛可以满足业务快速发展的需求了,需要的是团队作战,比如亚马逊电商早期从网上书城开始,一直做到 2000年左右,业务上品类不断扩展,全球化,站点的一个前端聚合模块,精简之后的二进制代码大小有 1GB,这样的结果就是,加入一个新需求,耗费的工程师人天成本很不经济,而且大量后台不断打“补丁”(定时脚本任务)的过程中,团队根本没有时间来投入创新的业务,在线业务的可用性也受到了影响;
我们前面一篇也跟大家分享过 AirBnB 的服务从单体到 SOA的心路历程《客户案例分析:Airbnb单体到微服务改造之旅(1)》,“到2018年,仅仅4年时间,AirBnB 的工程师数量超过了 1000名;原本的站点是一个非常典型的 Ruby on Rails 单体架构,意味着 MVC 三层在唯一的代码库中,底层是一个集中式的数据库。业务和工程师团队的增长意味着,代码行不断膨胀,从2014年50万行左右到2018年400万行代码。”
因此分而治之,单元化,团队解耦是我们解决此类问题的核心诉求。
交付困境:结果和业务如何对齐?
“大多数公司编写这个软件,他们把这个软件全部运行起来,然后把它们扔到市场部门,说‘这里是我们建的,去写新闻稿’,那个过程实际上应该是相反的。” 这是贝索斯对于亚马逊逆向工作机制的通俗说明;很多公司的困惑在于团队如何组织扩大?从亚马逊的经验来说,创新都是从两个披萨团队开始慢慢开花结果或者被证伪,新的披萨团队的成立,首先要做的就是从新闻稿、常见问题出发,先在计划书层面纸上探讨通过你的“创意”理论和数据上说明是合理的,再快速研发迭代发布通过最终你锚准的客户进行反馈验证你的业务场景;鼓励实验和尝试是创新的一个基础土壤,当你的创意经过时间的考验,业务组织上,从一个披萨团队会发展成 N个披萨团队,每个小团队的边界是相对清晰的,因此每个团队都可以并发自主创新,慢慢形成一个良好的飞轮效应,无数的微创新,带来企业的百花齐放的研发局面;
在组织解耦成两个披萨团队,应用架构上自然匹配的从单体演进成微服务;这样的机制可以延缓大企业病的痛苦,保持精业创新,不忘业务初心的不断演进交付的进化成长。
目前社区比较火的话题是领域驱动设计(DDD),相对于逆向工作法,DDD里面的战略建模,强调打破组织墙的一个很重要的方面是“统一语言”及“领域模型”,统一语言是统一的对于业务领域无歧义的术语和行为的理解,从而更好的划分业务领域边界;统一语言的落地,从实操和机制角度,“事件风暴”形式的开放式研讨会是一个很好的形式;
无论是亚马逊的逆向工作法还是社区的事件风暴,追求的目标都是围绕业务出发,对齐最终的开发交付结果。
企业双模困境
对企业用户而言,创新困境还在于,有大量的内部传统企业应用需要运维和改善,注重的是稳定和可用,占据企业 IT 和研发团队大量的精力,而创新业务更多关注推陈出新,快速获得市场反馈,更需要敏捷快速迭代;把企业的 IT和研发精力分成基础设施运维、已有的企业应用维护升级以及创新业务,研发团队赋能的目标就是在同等研发资源的前提下提升企业投入在整个创新业务的比例,降低其他两块的人力消耗。
什么是 DevOps?
我的理解,所谓 DevOps 最理想的就是打破所有的墙,从业务、产品、开发到测试、运维,这就是亚马逊 DevOps的内涵,随着 DevOps 在国内企业的落地实践,产生了诸如运维开发,开发运维,业务开发等新的岗位来打通不同部门之间的隔阂;而亚马逊的做法就是,把这些角色全部装进一个小的全职能团队,从而从该小产品团队内而言,所有的墙就不存在的;
对于敏捷、持续集成(CI)、持续交付(CD)的细微差别,主要看就是打破了哪些部门之间隔阂墙;
亚马逊的 DevOps 的成功实践核心包含两点:微服务架构以及 2个披萨的全能产品小团队,从解耦软件系统(单体架构)开始,转型研发团队更多关注业务(逆向工作法),利用 DevOps加速产品发布,从而可以实现更多的创新尝试,快速收集客户反馈并持续改进,从而提升了用户的价值;
2019年最创新的公司的转型实践
组织架构和文化机制在实施 DevOps的时候常常会忽略,但根据康威定律,”设计系统的组织,其产生的设计和架构等价于组织间的沟通结构“,同时Gartner 在 2015年发布一个报告称 “We estimate that, by 2018, 90 percent of I&O organizations attempting to use DevOps without specifically addressing their cultural foundations will fail.” ,如下图,实施 DevOps 要考量的点包括人员、技术、流程和文化四部分,文化里面包括信任文化、协作文化、持续改进以及工程师文化等等;
德鲁克研究会一份关于美国管理成效2019年评估报告指出,亚马逊的创新方面的得分远超其他公司,那对于拥有如此庞大的一个研发团队而言,创新的一个秘诀是什么呢?
三句话总结,“组织内思维理念协调一致”+“工程技术实践赋能”+“自服务工具链助力“!
接下来我们更新些最新的工程实践和自服务工具链的消息。
亚马逊的持续交付实践及工具篇
关于 DevOps 工具链,最核心的如何友好贴心围绕开发者构建一套自服务平台,比如以一个 K8S 作为应用平台来说,主要的干系人至少包括最终用户,应用开发测试,SRE工程师,以及基础设施运维;不同的干系人会有不同的关注点,因此需要不同的访问边界和控制面边界。
AWS 开发者工具主要分成,持续集成和持续交付工具,基础设施即代码,监控和日志,开发 IDE及其插件,命令行及语言包,开源企业级 Java以及移动开发等等。
推荐大家观看一个最新的 Developer Tools On AWS 的视频
亚马逊内部的 Builder 通常使用 Cloud Desktop 对应的 AWS服务有 Amazon Worspaces远程桌面或最新的 Web IDE Cloud9,对于本地的第三方 IDE,AWS 提供了比较多的插件支持集成,包括 PyCharm,Intelli,VS Code,Visual Studio,WebStorm等等;
去年 reinvent 发布的新功能里面,对于 IDE 的一个增强功能是“远程调试”,支持本地断点,在 AWS 这侧自动利用无服务器的容器集群,自动部署启动最新的代码,提升复杂项目的开发调试效率,降低本地测试环境构建时间和资源消耗。
JetBrains 的 IDE 操作可以参考:https://www.jetbrains.com/devops/amazon-aws/
还有一个特别好的功能是基于人工智能的代码静态扫描,识别代码的坏味道,同时也包含一个代码性能 Profiling 的工具,找出消耗资源或者影响延迟的低效率代码,除了找出这些代码问题,还会提供修改建议:
了解更多请参考费老师的这篇博文《送你一个编程教练可好?你应当了解的 Amazon CodeGuru》
对于持续交付管道,这次我们进一步公开了亚马逊工程师内部的自动化交付管道的基本情况,首先所有的源代码,配置以及基础设施代码都提交到代码库管理,提交之后,会进行代码的静态扫描和安全扫描,再开始自动化构建,构建后面紧跟着3个测试阶段,alpha=》beta=》gamma,每个环节都集成自动化测试工具,从单个项目的单元测试,到自动化集成,性能甚至浏览器交互测试,再到冒烟和综合测试;通过测试后的部署,先在一个可用区少量部署新的版本,集成监控和分析工具,再逐渐部署新的版本到本区域其他可用区,再到全球其他区域。
基于容器平台的推和拉模式流水线
所谓的推模式的流水线,持续集成完成代码到容器镜像的发布,之后通过手动或事件触发 kubectrl 将更改推送到 K8S 集群;这里的一个弊端是 kubectrl 是运行在集群外部,有一定的安全风险;在 AWS 平台上,流水线可以利用 CodePipeline构建,镜像可以在企业私有的托管镜像库 ECR(Elastic Container Registry)进行管理,部署阶段可以在流水线构建之后触发外部的 AWS Lambda 函数,函数实现利用 K8S的 Python SDK 部署更新最新的服务容器镜像。或者可以自建 Jenkins 集群,利用 Linux 脚本命令方式进行部署。
社区包括 INTUIT、WEAVEWORKS 等活跃玩家贡献了实现 GitOps 拉模式的容器服务持续交付流水线;拉模式中,以代码库比如 Github 为核心,系统的最终状态都由代码库进行版本控制,开发人员只要提交代码或回滚变化, GitOps 工具会驱动集群满足代码声明的最终状态,由于代码库中保存了集群的状态,因此集群崩溃后可以快速重建;
GitOps 的遵循的原则:
- 任何能够被描述的内容都必须存储在Git库中
- 不应直接使用Kubectl
- 和 K8S 交互应遵循 Operator 模式
持续集成这块跟上面的流水线一致,负责构建最新的容器镜像,差别在于部署这块,GitOps 的引入了两个关键的新组件,包括:
- Config Update:检查是否有新镜像,如果有,就从镜像库中提取该镜像并在代码库中更新其 YAML 定义
- Deploy Operator(部署在K8S集群内):会检测到集群的服务状态过期,从代码库中获取最新配置清单,并更新集群
GitOps 中的集群状态可观察性,K8S是一个声明式的基础设施,所有的配置信息是保存在代码库,因此 GitOps 工具要确保集群状态和代码库中记录的状态是一致的,这里就需要一个状态对比工具 Diffs 用来监控对比集群系统状态;提醒开发人员不一致状态的详细情况,或验证最近一次代码提交是否完全反应到线上。
目前支持 GitOps 持续交付的工具有:
- Jenkins X:动手实验参考 http://985.so/jY54
- Argo CD
- Weave Flux:动手实验可以参考 https://eksworkshop.com/
- Spinnaker
总结
亚马逊内部从 2000年开始转型,经历了组织和应用架构解耦,自服务开发者门户,逆向工作法机制以及相应的鼓励实验的工程师文化的沉淀,在大量的创新尝试下,孵化出了 AWS云计算,Prime会员,Kindle,Alexa 等一系列满足客户不断增长的体验需求;对于研发团队转型而言,核心三句话,“组织内思维理念协调一致”+“工程技术实践赋能”+“自服务工具链助力“,如果你也正在经历类似的挑战,欢迎一起来探讨!
诞生于 2019,遇见 2020。
感谢关注,欢迎动动手指标星和置顶;
这样就不会错过少但精彩的技术探讨、团队建设、案例分享!
每周至少一更,转发是对我的最大鼓励!
学习之路漫漫,走走停停,
偶有所感,随心所记,
言由心声,问心无愧!
从客户中来,到客户中去!