与销售人员联系
注册登录ZA Tech
返回上一页

【大咖分享】众安科技鄢晶:基于云原生技术构建新一代DevOps实践

2021/07/22作者:鄢晶

分享嘉宾介绍:

 

鄢晶,众安科技平台架构部技术负责人。经历保险业务开发和基础架构开发,有丰富的应用层与基础架构层架构设计经验,主要研究微服务、云原生方向,在微服务、DevOps、云原生技术领域有丰富的实践经验,主导了众安新一代智能运维平台的建设。

 

 

分享文字实录:

 

一、基础架构演进路线
 

互联网保险行业,从刚孵化到现在,业务特性越来越复杂,现在已慢慢成为保险行业未来的发展方向。众安的运维体系就像是一部运维编年史,众安成立之初也是“人肉运维”,业务部署在云服务之上,运维手段是通过“堆人肉”来做的。随着业务越来越复杂,团队规模不断壮大,慢慢发现业务增长瓶颈来自于研发效能和交付速率,而运维体系和基础架构体系则是研发效能提升的关键。我们也在慢慢思考,基于已经沉淀的工具、脚本建立了一整套研发一体化体系。

 

随着容器化技术的兴起,我们也开始拥抱容器技术,基于Docker Swarm建设了第二代运维平台,随着Kubernetes慢慢成为容器编排的事实标准,强大的调度能力以及开放标准的API接口让我们转向Kubernetes建设了第三代平台,现在则是更多将重心放在监控及运维数据沉淀上,形成智能运维体系。同时,应用架构也伴随着运维体系的转变在慢慢发生变化,从单体架构到现在,当前众安全部业务都已实现微服务化与容器化。

 

众安第四代运维体系,基于云基础设施、Kubernetes建设容器服务,这个容器服务作为整个运维体系的核心,通过监控平台、安全平台实现数据的输入、分析和决策。通过运维控制管道来实现异构化资源的调度,包含容器、数据库、Git等方向。平台覆盖整个研发生命周期,在开发侧基于Kubernetes和docker将异构化的运行环境真正实现不可变的基础设施,同时做到开发语言不受限。众安内部有各种技术栈,包括GO、Python、JAVA,这些都是在我们体系之内的技术栈。线上运维侧主要是基于Kubernetes带来的能力,提供自动扩缩容、自动上下线的能力。

 

 

刚才是运维体系的视角,接下来看看运维体系之下的应用视角。

 

应用方面,着重讲一下微服务架构服务治理。在应用规模越来越庞大的今天,我们会慢慢发现客户端维护消费实例数据,以及准实时的服务实例信息变更可能会给客户端带来非常大的负担。服务发现机制是为了解决什么问题呢?是在微服务多实例的情况下,我们消费端需要实时感知到服务实例的变化。

 

微服务应用体系的支撑层面建设有全链路监控,所谓全链路,是指监控覆盖从前端、网络、应用、安全到数据、基础设施的完整链路。同时在系统调用方面以Opentracing作为链路规范标准,实现从前端到后端、到中间件全链路的追踪。在C端,我们会通过埋点的形式来进行远端数据收集,实现C端APP或者H5的性能监控,比如可能会有图片加载不出来或者APP卡顿的问题,这些问题一般情况下业务方是无法感知到的。在这之上,我们同时建设有Aiops体系,主要关注的点是异常检测、容量规划、归因分析、故障自愈。比较典型的场景,比如归因分析,我们可以根据链路数据来形成事件传播链分析,达到根因分析的效果。

 

二、运维1+N:基础运维建设

 

第二部分主要介绍DevOps建设的理念,叫做运维1+N模式。运维1+N简单的说就是指基础运维+应用运维的模式,1个基础运维平台,N个应用运维场景,第二部分我将介绍基础运维平台的建设思路。

 

基础运维平台的核心组件是CMDB,CMDB传统的叫法是配置管理数据库,这里简单介绍一下新一代CMDB应该具备的核心能力是什么。

 

首先,CMDB应该是灵活面向抽象的设计。企业的运维场景是丰富多变、复杂多样的,在这个前提下,CMDB维护的数据就不仅限于传统的人、组织或者资源、应用,CMDB应该是面向抽象的设计,如何设计一款抽象的CMDB?我们应该从CMDB的模型层出发,一个模型有哪些东西,首先模型有模型项,比如主机有IP或者区域属性。另外,模型具备模型之间的关联关系,比如人和应用的关系,应用和主机的关系。我们会对接一些数据源,有数据进来,模型可能会有校验、清洗规则。同时,对于审计的要求,模型会有可变更、可追踪的机制。

 

第二个设计要点是CMDB应该具备数据发现的能力。运维成功的关键要素是CMDB,CMDB成功的关键则是CMDB数据的一致性、实时性和准确性。我们发现传统CMDB数据一般都是通过某个组织,比如运维,或者通过ITSM流程来管控的,数据的一致性以及准确性受到的最大挑战是来自于人本身,所以对于CMDB而言,应该能自动发现数据。发现数据有很多手段,比如使用云服务的场景,发现数据可以来自于CMP系统、也就是多云管理系统,通过云API多云管理系统可以实现对CMDB数据的上报。对于自建IDC场景,通过Agent手段,比如Osquery来实现数据采集。数据具备自动发现的能力,才能保证CMDB中维护的数据是准确的。

 

 

接下来介绍CMDB设计思路中的第三点,应该存在以应用中心和以人为中心的两种视图。CMDB比较典型的两个场景,一个场景是以人为中心的,面向管控层的ITSM流程,也就是就是ITSM场景。另外一个比较典型的场景则是以应用为中心的面向执行层的持续交付场景。在这两个场景之下,我们应该具备以应用为中心和以人为中心的两种视图。

 

 

上面说到CMDB的建设思路,有CMDB这个平台还不够,有CMDB平台之后怎么给CMDB数据建模呢?我们觉得CMDB的数据建模应该是自上而下面向场景的建模。我们认为CMDB的数据有没有价值其实还是看它能不能支撑上层的场景。比如刚才说到的ITSM流程场景以及持续交付场景,以持续交付场景为例,怎么进行数据建模?持续交付的过程有创建发布,创建发布之后会执行构建动作,CI之后有CD,CD之后有线上运维,每个场景都会有需要的对应API,API下面需要模型支撑,比如选择人和应用,在这个场景之下,人和应用需要哪些模型项以及人的模型跟应用模型之间应该存在什么关系。面向场景的建模,才能保证我们在CMDB中的数据能服务于场景,而不是存在那儿的死数据,死数据除了给数据维护带来成本之外没有任何作用。

 

刚才说到基础运维平台第一个比较重要的组件CMDB,CMDB能给基础运维平台提供数据基础。第二个部分则是基础运维平台另外一个比较重要的概念,我们称之为运维的生命线,叫做运维控制管道,它能给基础运维平台提供调度的基础,运维过程中可能涉及很多资源的调度,包括服务器、Redis,面向GitFlow的运维流程可能还会有Git的调度。我们可以基于Kubernetes的CRD来建设调度执行层,对于主机的调度则可能会选用saltstack或者Ansible作为调度介质。

 

运维控制管道,简单来说它就是一个工作流引擎。展开来说,工作流引擎可能涉及到选型,目前众安内部的选型是通过云原生生态上的工作流引擎,使用Tekton来建设。运维控制管道设计可以类比微服务,微服务有一个服务编排的概念,目的是将运维涉及到的所有调度动作通过Kubernetes的CRD能力抽象成一个个原子调度任务,基于工作流的能力来编排实际运维场景,这就是基础运维的概念。有了编排的能力,我们可以很快构建上层应用运维,比如发布场景,可能是一层,或者两层、三层流水线模型,基于我们的编排,可以快速构建CI/CD场景。

 

刚才说到CMDB和Pipeline,下面回到运维1+N模式。什么是运维1+N模式?我们对1+N模式的定义是在云基础设施之上,云基础设施包含云原生运行时、云原生存储和云原生网络,在云基础设施之上建设“1”,这个“1”是指基础运维平台,CMDB提供了运维需要的数据能力,Pipeline提供了整个运维过程中的需要的调度能力。“N”是基于一个基础运维平台来建设N个应用运维场景,比如故障处理场景,我们接触更多的是发布,发布是典型的变更场景。另外,我们也有ChatOps的概念,会有一些客服场景,还有一块是容量基础场景。

 

运维1+N模式能带来哪些收益?

 

 

刚才我们强调了在这个设计思路下可以很快建设新的运维场景,比如数据能力跟调度能力我们这边已经有了,可能以低代码甚至零代码的形式做到新场景的建设,这是第一点。第二点是我们相当于将基础运维平台作为整个运维体系的实施标准,这样就能避免系统烟囱式建设。第三点是避免企业内的重复建设,比如各自团队有各自的运维场景,比如要用到容器服务,操作Git或者操作主机,Pipeline的存在避免了各个团队对调度、流程做重复性的建设

 

三、应用运维实践

 

接下来介绍一下“N”的部分,在应用运维上的实践。

 

第一个案例是持续交付场景,这是一个经典的CI流程,整个CI流程可能是通过开发者提交一次代码来触发的,比如通过Tekton CI任务来执行Git代码拉取,基于代码构建镜像。同时可能会执行自动化测试或者安全扫描。成功之后,会推送到Harbor中,推送到镜像仓库,Kubernetes要做的事情就是同时执行一次开发环境的部署动作,拉取镜像,启动镜像。整个过程通过之后,CI流程结束,通知开发者或者合并代码或者触发CD。这是一个典型的CI流程。

 

接下来是在经典CI流程上GitOps设计。刚才的CI流程其实是典型的推式流水线,GitOps在最佳实践上有一点比较重要的概念叫做拉式流水线,区别于推式流水线,我们会在Kubernetes集群中部署一个服务,叫Seaman,GitOps遵循IAC设计,即基础设施及代码,我们认为应用服务它的状态是可以在Git中声明的。Seaman这个组件的职责是实时获取当前集群的状态,对比Git中的声明来产生差异,通过差异分析,在集群内执行调度,自动将整个集群状态达到Git声明的状态。这跟Kubernetes的设计理念非常相似,命令式编程跟声明式编程的差异,声明式编程能给我们带来什么优势呢?命令式可能会产生命令丢失的问题,需要辅助手段来保证最终一致性。

 

GitOps在拉式流水线的场景之下能带来哪些收益呢?

 

一个很典型的收益,比如推式流水线自然而然要将集群的密钥暴露到平台当中,这对安全性是一个挑战。对于拉式流水线来说不需要,因为是通过事件驱动,集群自感知,通过集群的自动差异分析达到部署动作,集群无需暴露证书。这是第一点。

 

第二点收益,来自于Git天然具备一些能力,一个是版本控制的能力,另外一个是操作审计、操作留痕,分别从这些能力介绍一下GitOps给我们带来的优势。

 

首先是版本,运维或多或少会面临回滚场景,GitOps将整个应用声明性的架构存放到Git当中,相当于Git作为应用期望状态的事实标准,通过git版本的回滚,我们能非常简单的做到整个环境的全回滚,这是对于版本控制带来的优势。另外一块是操作审计,刚才也提到了,金融行业监管部门可能会对我们有非常严格的要求,服务的任何变更应该都是可被记录、可被追溯的,我们会天然用到Git的这些能力来实现操作审计。接下来是用Git天然的rbac策略来实现角色和权限的控制。

 

刚才说到的是服务变更的上的实践,第二点分享的是基础设施及代码的实践,服务部署以及变更流程的设计。

 

 

我们认为服务的变更不仅仅是软件制品或者代码的变更,这只是服务的一部分。一个服务由什么组成?包括应用本身以及围绕应用相关的配置,以及初始化数据库脚本或者服务依赖的中间件。再延伸,甚至是服务依赖的IaaS层基础资源。我们可以基于基础设施及代码的理念将它做到可声明,我们这边叫做“工程”。基于工程的声明,怎么设计一键部署的逻辑?刚才也看到了整个运维控制管道集成了所有运维相关的调度,对于工程声明的要素而言,比如APP,我们声明它之后可能就要触发Kubernetes deployment的调度。不同的点是我们会同时声明它是什么中间件,触发不一样的调度动作,对于虚拟机部署的中间件而言,会触发ansible下发中间件部署启动命令,对于容器化而言,可以是apply一个statefulSet,也就是创建一个容器的调度。

 

在这个理念之下,我们发现通过声明式的设计,将整个应用环境通过工程的定义来进行声明,同时通过声明、通过事件来驱动,触发运维控制管道的工作流去执行各个组件的调度。在系统设计上也就比较简单了,调度是触发工作流API,有API我们就知道可能需要哪些参数,有参数就可以基于参数来定义DSL,可能是基于JSON的DSL,也可能是基于YML的DSL,DSL给到开发者一个视角,我们可以基于DSL字段快速创建用户界面,通过用户界面,开发者可以基于一些编排配置动作来实现对于环境的定义以及环境的一键拉起。

 

基于工程来声明应用的环境,服务变更流程就可以变得很简单了,所谓的发布,就可以设计为通过交付流水线来修改各个环境工程的定义。

 

最后一块要分享的应用运维实践则是DevSecOps体系的建设,一开始也提到金融行业对公司安全性的要求,对于安全跟DevOps的集成,我们也有一些思考,我们觉得对于安全的扫描也好、管控也好,应该尽量左移,而不是将安全问题暴露在生产运行时。左移会有一些策略,比如在CI/CD层,我们可以集成自动化安全扫描或者代码安全扫描,同时基于质量门禁体系,比如每次变更不能有高危漏洞,同时不能有超过多少个中危漏洞,通过这种机制来达到在CI/CD过程中控制安全漏洞,减少安全事件产生的目的。在系统层,运行环境层有多个层面,一个是主机层面,有主机安全扫描的手段,在容器层面有镜像安全扫描手段以及引用安全容器。在应用层可能会通过一些反欺诈行为或者加密存储行为来做到应用层的安全管控。在业务层,C端业务比较典型的是有一些登录场景,这个时候就会引入多因素认证服务。

 

DevSecOps体系就是将安全管控纳入到运维体系当中,不管是从运行环境这一层也好,还是到变更流程也好,都要进行深度集成。

 

云先行,智未来。我们现正在云原生的道路上深耕,基于云原生建设的运维体系是我们正在进行的事情,同时我们认为,运维体系的未来一定是智能化的,我们希望未来可以更多使用人工智能的技术代替现有的一些规则化的场景。

 

 

 ——————

 

 

 

 

 

原创文章,作者:鄢晶,内容编辑:郝俊伟

 

 

 

版权归众安科技所有