查看原文
其他

怎样成为一名 DevOps 的忍者

2017-11-01 莫源 DevOps时代

本文整理自 Jenkins 北京线下沙龙,沙龙完整 PPT 请在文末下载

作者简介:

莫源
阿里云高级研发工程师。在加入阿里巴巴之前,先后在北京天方地圆科技有限公司、微软亚洲研究院任职。现主要负责阿里云容器服务产品的底层服务发现系统、集群管理系统的研发,从事容器的持续交付、持续集成的方案的设计与实现。在云计算、分布式系统、图像识别与虚拟现实方向有多年的开发经验。

前言

大家好,我叫莫源,2012年-2013年在微软的亚洲研究院,2013年加入到阿里云。刚开始的时候做前端,写页面做控制台,后来开始做 Docker 、容器虚拟化、 DevOps ,还有阿里云这边对外开源的产品。

一、DevOps 到底是啥

什么叫 DevOps ,这张图讲的是基于 MEAN 的 DevOps 的 Workflow ,上面有大家耳熟能详的工具和流程。

每个人看到这张图的关注点不一样:有的人关注的是上面的 github ,关注的是工具;有的人关注的是底下的 local 、 integration 、 stage ,关注的是流程;有的人关注的是 workflow 该怎么设置。每个人看 DevOps 的观点不一样,每个人的角度不一样。

比如这张图,有人摸到大象的尾巴,像一个绳子;有的人摸到肚子,像一堵墙。每个人从不同的会议上或者书籍上获取 DevOps 观念的时候没有统一的观念,最终实现 DevOps 的方案也不同。实现的好的话就像顾宇老师或者华强大哥那种,有明确的方案产生。实现得不好就会变成这样,一个很畸形的大象。

原本 DevOps 帮你解决问题,但是发现 DevOps 变成一个累赘,制约你前进的方向。

二、DevOps 的价值

提到 DevOps ,大家都知道这个概念已经提出了很久,为什么一直没火起来?是因为一些概念的东西,如果有一个落地的模型或者工具甚至是语言,这个东西就会很快火起来。但是刚开始 DevOps 兴起的时候只是一个方法论,没有具体到工具或者语言的东西,所以一直没有火起来。

2.1 解决时间问题

我认为 DevOps 是什么,它像一个哲学问题,哲学里面很多人会说哲学有三大问题:我是谁,从哪来,到哪去。但是你说要用一个问题来解决哲学里所有的问题是什么,那么就是时间,时间是世界的主宰。 DevOps 也一样的,它解决的根本是一个时间问题。

你可以想一下,大家引入 DevOps 要解决的根本的点:我要自动化一些流程,我要能快速的完成发布,我要提高质量,这些实际上根本都是一个时间问题, DevOps 其实就是来帮你节省你的时间。有人会说我提高代码质量和节省时间有什么关系,提高了代码质量就省去了返工的时间。

DevOps 节约时间的方法我们分为以下四个点:

  • DevOps 是和工具流或者流程化相关的,流程化、标准化减少脱节环节时间浪费

  • DevOps 和文化相关,节约时间人人有责

  • DevOps 是自动化,自动化可以降低人工的时间消耗

  • DevOps 和质量相关,质量可以避免返工

DevOps 的核心概念是和时间相关,当你实践 DevOps 的时候,你觉得这个东西能提升效率、节省时间,这就是一个好的 DevOps 。

2.2 DevOps 工具链

上面分享的是一些概念性的东西,下面我会给大家推荐一些我认为比较合适的 DevOps 工具,大家拿到这些工具之后回去自己看一下该怎么用。

这张图可能有人看过,这是描述当今 DevOps 工具的工具周期表。这个工具很酷,到底该选哪个,这也是在实践 DevOps 时大家的一个困扰,就像 Jenkins 一样,有那么多插件,如何去选择这是现在比较大的一个问题。

三、云怎么做 DevOps

我们今天要谈的问题是在云上,云原生的应用之间怎么做 DevOps ?

这张图大家可能见过类似的,平时不会这么画。这个图讲的是一般的云平台提供的三个层次的云服务的结构:第一层是 IaaS ,基础设施层;第二是 PaaS ,平台层;第三层是 SaaS ,服务层

平时我们一般会画成金字塔型,为什么会这么画?金字塔有一个特性,底下越来越宽广,越往上越来越小,当你的 IaaS 足够大的时候,你才能做一个 PaaS 层, DevOps 在这个塔的塔尖。如果没有基础的 IaaS 层, SaaS 层或者 PaaS 完善的基础设施,你很难把 DevOps 流程做得比较完善。

这张图是大家日常工作的一个写照,代码提交、构建与编译、测试、环境准备、部署与发布、监控与运维,其他的流程可能会交给云平台的基础设施去完成。

在这个流程里阿里云怎么做?代码提交部分,阿里云有云 Code ;构建与编译,阿里云有镜像服务;测试有PTS压力测试;环境准备和部署与发布这部分阿里云以前是空的;监控与运维有云监控。在通用的 DevOps 能力上我们做了一个产品叫 CodePipeline ,环境准备上我们有 Packer 、 Terraform 、 Ansible 。

  • Packer 是做什么,你可以基于你的配置文件打出一个镜像,这个在弹性伸缩里是特别有用的功能

  • Terraform ,你可以通过一个配置文件,来动态的生成一些基础设施,通过这个配置文件的更改来更改当前基础设施的状态

  • Ansible ,做配管时的工具

以前大家在AWS上常见的一些Code的行为可以通过这些工具一样在阿里云上可以完成。

四、CodePipeline 诞生

刚才提到我们做了一个产品叫 CodePipeline ,这也是今天想跟大家核心讨论的一部分,大家都讨论 Jenkins ,为什么我们要讨论 CodePipeline ?这个也是迫不得已的一个选择,在很久以前我们自己内部也是用 Jenkins ,我们也有自己很多的实践。

4.1 Jenkins 历史滞留问题

这个是 Jenkins 大致的一个图,有非常多的环境可以与它做集成,大家通过插件的集成满足自己的业务需求。 Jenkins 很酷,但是不完美,也有自己的问题。原来我们的想法是把 Jenkins 做成一个 SaaS 化的产品提供出来,但是如果每人一个 Jenkins ,成本 cover 不了, CodePipeline 对 Jenkins 的改造使其怎么做到高可用。

首先 Jenkins 是一个巨石系统,它是一个单体的结构,大家一般情况下跑单体的实例,做持续集成。为什么到现在为止大家好像没有看过特别成熟的 Jenkins 集群级的方案,或者大家没有看到过一个高可用的方案,大部分情况下大家看到的是给不同的团队或者是不同的部门分配多个 Master ,而不是共用一个大的 Master ,其实这个主要取决于 Jenkins 内部的实现原理和机制。

传统意义上来讲一个服务会有两层,一层是你的服务层,一层是你的数据层。数据层可能会在DB,现在比较流行都是在DB或者 cache 层做,但是 Jenkins 因为历史的一些原因,导致所有的存储都是以文件的方式存储在磁盘上,存储在磁盘上就会一个比较大的性能问题。

Jenkins 对于这种场景,怎么做才能让大家感觉到我的性能没有太大的削弱,实际上这个取决于 Jenkins 内部的资源加载机制。有时大家可以看,在 Jenkins home 里有一个 jobs ,里面存储的就是大家构建的每一个任务,还会存构建任务的配置等等。一系列的东西都以文件的方式,以特定的目录结构存储在磁盘上。

当 Jenkins 第一个步骤,比如你重启 Jenkins 的时候,它会做什么?先把磁盘上 jobs 目录都扫一遍,加载到自己的内存里里,再去做后续的东西。比如刚才说的高可用的方案,假如用共享存储,现在在一台 Jenkins Master 上写了一个job,其实另一台 Jenkins 是没有感知的,因为没有加载这个job。

我们内部用 Jenkins 的时候,大概用了半年时间,整个的目录结构可能在60GB左右,做任何操作需要同时同步给别人,再去 reload ,这个办法基本没法忍受。存储结构能不能改,如果能改,是不是就能解决这个问题?这个取决于 Jenkins 内部如何实现存储。

每一个job的配置或者插件的配置,是把一个 JAVA 的对象序列化一个XML文件,如果转成数据库里会出现什么问题?比如你在XML里设定一个A=1,在正常的时候你可能会查A=1,但实际上你用XML的方式是查不到A=1的,这也局限了很多想以插件的方式对 Jenkins 改造的一个困难点。

4.2 Jenkins 高可用

在社区里或者大家对 Jenkins 的高可用的方案怎么做,下图是 OpenStack 的一个方案。

我在 OpenStack 社区的时候,他们的方案其实很有特点,当时 OpenStack 是每天大约单日构建最高的时候可以到8000次,同一时间在跑的任务最高的可以到800,单个 Jenkins Master 实际上没有办法满足这个需求。

OpenStack 做了一层叫 Gearman 的插件,大家以前用 Jenkins 的时候是用了Web端的 Jenkins ,有很多人也知道 Jenkins 有一个工具叫 Jenkins job Builder ,可以通过命令行的方式创建一个job。

当时 OpenStack 的一个方式是它把 Jenkins Master 作为一个资源的二级调度器,有多个 Jenkins Master ,在跑这个任务,最后通过 Gearman 完成相应的任务调度。

这种方式的弊端是没有一个可视化的界面直接操作,而 OpenStack 是通过上层封装了一下 Jenkins 的结构,然后通过 Zuul 的方式来做整个结构的改造。

上图是 CloudBees 的方案,这个公司是 Jenkins 商业版支持比较完善的公司,这个是他们推出的 CloudBees Jenkins Platform 项目。有一个上层的概念,比如这两个是企业的两个部门,都是通过中间这个 operations Center 到自己的 Jenkins ,底下还是单独的 Jenkins Master 。

4.3 性能影响因素

4.3.1 插件

要想 Jenkins 用得好,插件不能少。但是 Jenkins 的插件会带来一些性能问题,每一个插件都是在项目启动的时候就会加载到内存里,当插件越大的时候,对性能的损耗越大。要选择自己合适的插件去构建自己的 Jenkins 。

第一个是插件,要选择一些合适数量的插件,满足需求的插件,尽量少的插件会比较好;

第二个是job,在 Jenkins 官方的文档上讲,当你的job超过1000个以上的时候, Jenkins 就会有一些性能问题。手动创建 user 80个以上就会有卡顿,job那个地方是第一次都加载进来的,而 user 是每次都会去扫盘,然后去加载XML;

第三个是slaves;

第四个是每一个节点上的 executor 。

4.3.2 安全

阿里云有一个产品,会同步当前所有的漏洞库,从外侧以黑盒的方式来看大家是否具备漏洞库,如果具有给你相应的诊断信息。在阿里云上有非常多的用户装了 Jenkins ,但是很多没有做权限的控制,没有做特定的配置,导致安全上有很大的问题。

这几个是在谷歌里可以看到的常见的 Jenkins 的一些漏洞。比如第一是命令执行漏洞,这种是可以越权的;第二个是未授权代码;第三个是 Jenkins 漏洞探测、用户抓取爆破。

4.3.3 选择

Jenkins 的插件那么多,到底该选哪一个?而且出现很多问题是1+1小于2,有时候必须安装第二个插件来满足,两个插件组合的时候又可能达不到很好的合力,这导致很多业务场景不得不去装很多额外的插件来满足自己的需求,其实很多插件我们可能只用了其中的一个功能或者两个功能。

4.3.4 步骤

Jenkins 是一个通用领域的集成,这是一个标准的持续集成的步骤。

  • 第一个是一般模型,SCM 、Build 、 Test 、 Deploy;

  • 第二个是领域特定模型,你在某一个场景之下来完成的持续交付流程。比如这是一个mvn的项目,这是一个面向 JAVA 领域的模型,这个东西其实并不足以满足大家实际生活中的一些场景。有人可能在阿里云上,有人可能在腾讯云或者华为云上,你要依托于这些云架构来确定该怎么做;

  • 第三个是领域模型实现,比如原来的时候, checkout 这边需要有协议, package 需要有特定版本的,需要有一个构建完之后的中间产物放置的位置,可能会涉及到一些 mirror 、 cache 。这都是一些细节的东西,但是又和你最终使用 Jenkins 环境相关。比如在阿里云上你可能会把中间的构建产物放在私有的oss上;

  • 最后一个步骤是部署,标准的 Jenkins 肯定支持通用的部署,问题在于不会和特定领域去做集成,只提供的是通用协议,比如你在阿里云上你会直接SSH,在腾讯云上还是SSH,但是这个是不是最优的?还有像雇主策略,原则上来讲,如果云平台来帮你提供,不需要大家在部署模型这一层做任何的修改。

五、Jenkins 到 CodePipeline 进化之路

这是我们做的一个产品,和 Jenkins 非常像,为什么和很多的开源产品不太一样?我们直接把 Jenkins 页面级的东西拿出来。 Jenkins 最强的能力在插件支持上,我们的开发者对 Jenkins 熟识的程度大部分在于自己插件的使用经验和自己部署的集成上。而下面这张图是 CodePipeline 所略版的图,我只把核心的几个部分拿出来。

  • 第一个部分是 CodePipeline 一个U内里会有两台 Jenkins CodePipeline Service 的 Master ,再往下是一个 slave 库,我们是基于阿里云的容器服务来做的 slave 库。 slave 库比较大的特点,在阿里云容器服务里有一个能力叫 auto scaling ,在流量里比较大的时候,CPU会飙高,我们会做两级资源扩展,一级是在做容器级,第二级是做资源级。如果容器池不够了,帮你做容器池的拓展。构建服务也一样,比如我今天一天可能构建就10次,明天上了一个大客户,800次,这时候我构建服务怎么扩展?其实是把我们 CodePipeline 任务的调度策略调度下去,做了一个集群级的资源监控,来弹性伸缩整个资源池的大小,完成这部分的调度。

  • 第二个部分是右边这个 Deploy Service ,帮你做各种各样环境下服务的部署。大家传统意义上理解,如果想要部署到你的集群上,可能需要和你的集群有一个安全策略上的交互, deploy Service 是反打,装一个 Agent ,可以在你的VPC甚至你的IDC里来使用 Agent 。再往下是中间产物,比如你想构建一个放在VM级的目录,把 Jenkins 中间的部署末路上传到oss,由oss做分发,再往下则是 Docker Hub 。

这张PPT是我今天要着重讲的,我们怎么改造 Jenkins 完成 CodePipeline 。

第一部分存储

  • 把 Jenkins 文件级的存储变成 database ,哪怕说我们只把底层的结构改成DB,其实丝毫没有改变任何事情,因为只要 CodePipeline 这种机制在,还是解决不了高可用的问题。我们在 Jenkins 的上层做了一个 CodePipeline 的改造;

  • 从 full load 改成 lazy load ;

  • 从有状态的 Master 变成一个基本状态的 Master ,这有一个额外 slave 的问题, Jenkins 是通过 slave 来做相应的构建,那你的一个 slave 其实属于一个 Master 。

    怎么来保证你的两个 Master 可以共用同一个 slave ,这个地方是一个比较严重的问题。如果使用SSH,这里没有任何影响,可能下发任务是一个 Master ,但是在另一个 Master 可以看到状态。

第二部分安全

  • Jenkins 社区里的插件大约有几千个,我们不能保证每一个插件都是安全的,所以在 CodePipeline 开放插件的时候一定会先做一次安全扫描和安全加固。

    给大家一个建议,选择什么样的插件会比较合适,首先这个插件在社区里的 start 数超过1000以上,一般没有太大问题。

    如果你发现这个插件维度很低,大家尽量不要用,因为很多时候插件是可以到 Jenkins 系统级的,那个地方是没有权限控制的,只有自己实现权限控制才能去做额外的事情;

  • 我们在API级上面加了一个服务叫 watch-dog ,80%以上的漏洞是由于插件以及大家的不当使用或者不当配置导致的;

  • 大家用 Jenkins 时可能会创建各种各样的 user ,每个 user 来做权限的限制。这个时候大家会发现一个问题,比如我是一个有低权限的人,你是一个有高权限的人,咱们两个从job的维度上讲是没有区别的,我能创建一个job,你也能创建一个,咱们两个job之间是没有办法重名的,这个其实是不合理的一个概念。

    Jenkins 默认的机制是在前面加一个约定大于配置,然后来生成 namespace 来做,应该有一个组概念或者每个 user 有各自能力,在这个地方支持RAM有子账号,去共享父账号的job,但是不同账号之间的job可以有重名。

第三部分性能

  • jod的数量几乎没有限制;

  • 动态的来生成 slave ,以支持更多的 slaves;

  • 重新改造了一下 Jenkins 的任务调度器, Jenkins 原生的调度器里会去编译所有人的所有job来做事情,是非常低效的

第四部分集成

  • Code无缝集成;

  • 和OSS无缝集成,不需要再关注OSS的一些情况;

  • 和容器服务无缝集成;

  • 针对阿里云 Linux 更好的整合

  • 现在我们正在做的是和阿里云的 Function Compute 。

这张图是一个 Demo ,讲的是通过 CodePipeline 部署到两个 Region 。

首先是创建一个job,这个地方会提供一个向导页,很多时候我们会做一些标准项目的模板,比如配置一个项目,然后配置一个证书,这个都是大家比较熟悉的 Jenkins 的操作。我们会内置一些标准语言的持续集成、持续构建的模板,上传到OSS的什么位置。

再往下是部署到ECS上,选择哪几台ECS做部署,这两台ECS分别是处在杭州和北京的两个 Region 。导到标准的 Jenkins 配置页,大家可以检查当前生成的 Jenkins 的配置,到底是什么样的,是不是正确的。

当你检查没有问题之后,直接点击提交,提交一下 Code ,比如简单改一行,这个地方需不需要在部署的位置让你来选择一下到底部署还是不部署。阿里云在最开始做 CodePipeline 的时候考虑到这个问题,因为我们当时人数有限,所以这个部分直接做了自动。

在 CodePipeline 这个产品出来之后,刚才部署那个位置其实是下发一条部署任务,而你真正选择部署的时候可以点击选择是部署还是不部署,这个是在两个 Region 下的 Demo 。

我不期望大家能够从我的分享里得到一个完整的 DevOps 流程该怎么做或者 DevOps 的想法该怎么去想,大家能够得到两件事情就好了。

  • 一个是大家记住 DevOps 能节省大家的时间

  • 第二个是我给大家推荐的比较合适的 DevOps 工具,大家拿到这些工具之后回去自己看一下该怎么用。


福利时间:

Jenkins 北京线下沙龙全部 PPT 链接: https://pan.baidu.com/s/1gffBFQr 密码: w5qm



END


更多相关文章阅读

什么是 DevOps 三步工作法?

什么样的团队结构才能适应 DevOps 的蓬勃发展?

基于 jenkins 的 CI/CD 实践

大规模团队如何采用标准化的持续交付模式

基于 k8s 的 Jenkins 构建集群实践

《凤凰项目》读书笔记(上篇)

《凤凰项目》读书笔记(下篇)

无服务器化的微服务持续交付

基于DevOps、微服务以及k8s的高可用架构探索与实现


古语有云能动手就别吵吵

快来参加  Jenkins训练营让你在动手中掌握Jenkins核心技能

掌握实施 DevOps 与持续交付的核心工具


点击阅读原文,参与 Jenkins 用户大会

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存