@gaoxiaoyunwei2017
2017-10-27T16:45:46.000000Z
字数 7285
阅读 722
毕宏飞
莫源
大家好,我叫莫源,2012年-2013年在微软的亚洲研究院,2013年加入到阿里云。刚开始的时候做前端,写页面做控制台,后来开始做 Docker 、容器虚拟化、 DevOps ,还有阿里云这边对外开源的产品。
什么叫 DevOps ,这张图讲的是基于 MEAN 的 DevOps 的 Workflow ,上面有大家耳熟能详的工具和列成。
每个人看到这张图的关注点不一样:有的人关注的是上面的 github ,关注的是工具;有的人关注的是底下的 local 、 integration 、 stage ,关注的是流程;有的人关注的是 workflow 该怎么设置。每个人看 DevOps 的观点不一样,每个人的角度不一样。
比如这张图,有人摸到大象的尾巴,像一个绳子;有的人摸到肚子,像一堵墙。每个人从不同的会议上或者书籍上获取 DevOps 观念的时候没有统一的观念,最终实现 DevOps 的方案也不同。实现的好的话就像顾宇老师或者华强大哥那种,有明确的方案产生。实现得不好就会变成这样,一个很畸形的大象。
原本 DevOps 帮你解决问题,但是发现 DevOps 变成一个累赘,制约你前进的方向。
提到 DevOps ,大家都知道这个概念已经提出了很久,为什么一直没火起来?是因为一些概念的东西,如果有一个落地的模型或者工具甚至是语言,这个东西就会很快火起来。但是刚开始 DevOps 兴起的时候只是一个方法论,没有具体到工具或者语言的东西,所以一直没有火起来。
我认为 DevOps 是什么,它像一个哲学问题,哲学里面很多人会说哲学有三大问题:我是谁,从哪来,到哪去。但是你说要用一个问题来解决哲学里所有的问题是什么,那么就是时间,时间是世界的主宰。 DevOps 也一样的,它解决的根本是一个时间问题。你可以想一下,大家引入 DevOps 要解决的根本的点:我要自动化一些流程,我要能快速的完成发布,我要提高质量,这些实际上根本都是一个时间问题, DevOps 其实就是来帮你节省你的时间。有人会说我提高代码质量和节省时间有什么关系,提高了代码质量就省去了返工的时间。
DevOps 节约时间的方法我们分为以下四个点:
DevOps 的核心概念是和时间相关,当你实践 DevOps 的时候,你觉得这个东西能提升效率、节省时间,这就是一个好的 DevOps 。
上面分享的是一些概念性的东西,下面我会给大家推荐一些我认为比较合适的 DevOps 工具,大家拿到这些工具之后回去自己看一下该怎么用。
这张图可能有人看过,这是描述当今 DevOps 工具的工具周期表。这个工具很酷,到底该选哪个,这也是在实践 DevOps 时大家的一个困扰,就像 Jenkins 一样,有那么多插件,如何去选择这是现在比较大的一个问题。
我们今天要谈的问题是在云上,云原生的应用之间怎么做 DevOps ?
这张图大家可能见过类似的,平时不会这么画。这个图讲的是一般的云平台提供的三个层次的云服务的结构:第一层是 IaaS ,基础设施层;第二是 PaaS ,平台层;第三层是 SaaS ,服务层。平时我们一般会画成金字塔型,为什么会这么画?金字塔有一个特性,底下越来越宽广,越往上越来越小,当你的 IaaS 足够大的时候,你才能做一个 PaaS 层, DevOps 在这个塔的塔尖。如果没有基础的 IaaS 层, SaaS 层或者 PaaS 完善的基础设施,你很难把 DevOps 流程做得比较完善。
这张图是大家日常工作的一个写照,代码提交、构建与编译、测试、环境准备、部署与发布、监控与运维,其他的流程可能会交给云平台的基础设施去完成。在这个流程里阿里云怎么做?代码提交部分,阿里云有云 Code ;构建与编译,阿里云有镜像服务;测试有PTS压力测试;环境准备和部署与发布这部分阿里云以前是空的;监控与运维有云监控。在通用的 DevOps 能力上我们做了一个产品叫 CodePipeline ,环境准备上我们有 Packer 、 Terraform 、 Ansible 。
以前大家在AWS上常见的一些Code的行为可以通过这些工具一样在阿里云上可以完成。
刚才提到我们做了一个产品叫 CodePipeline ,这也是今天想跟大家核心讨论的一部分,大家都讨论 Jenkins ,为什么我们要讨论 CodePipeline ?这个也是迫不得已的一个选择,在很久以前我们自己内部也是用 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 改造的一个困难点。
在社区里或者大家对 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 。
要想 Jenkins 用得好,插件不能少。但是 Jenkins 的插件会带来一些性能问题,每一个插件都是在项目启动的时候就会加载到内存里,当插件越大的时候,对性能的损耗越大。要选择自己合适的插件去构建自己的 Jenkins 。
第一个是插件,要选择一些合适数量的插件,满足需求的插件,尽量少的插件会比较好;
第二个是job,在 Jenkins 官方的文档上讲,当你的job超过1000个以上的时候, Jenkins 就会有一些性能问题。手动创建 user 80个以上就会有卡顿,job那个地方是第一次都加载进来的,而 user 是每次都会去扫盘,然后去加载XML;
第三个是slaves;
第四个是每一个节点上的 executor 。
阿里云有一个产品,会同步当前所有的漏洞库,从外侧以黑盒的方式来看大家是否具备漏洞库,如果具有给你相应的诊断信息。在阿里云上有非常多的用户装了 Jenkins ,但是很多没有做权限的控制,没有做特定的配置,导致安全上有很大的问题。
这几个是在谷歌里可以看到的常见的 Jenkins 的一些漏洞。比如第一是命令执行漏洞,这种是可以越权的;第二个是未授权代码;第三个是 Jenkins 漏洞探测、用户抓取爆破。
Jenkins 的插件那么多,到底该选哪一个?而且出现很多问题是1+1小于2,有时候必须安装第二个插件来满足,两个插件组合的时候又可能达不到很好的合力,这导致很多业务场景不得不去装很多额外的插件来满足自己的需求,其实很多插件我们可能只用了其中的一个功能或者两个功能。
Jenkins 是一个通用领域的集成,这是一个标准的持续集成的步骤。
这是我们做的一个产品,和 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 。
第一部分存储
第二部分安全
第三部分表现
第四部分集成
这张图是一个 Demo ,讲的是通过 CodePipeline 部署到两个 Region 。
首先是创建一个job,这个地方会提供一个向导页,很多时候我们会做一些标准项目的模板,比如配置一个项目,然后配置一个证书,这个都是大家比较熟悉的 Jenkins 的操作。我们会内置一些标准语言的持续集成、持续构建的模板,上传到OSS的什么位置。再往下是部署到ECS上,选择哪几台ECS做部署,这两台ECS分别是处在杭州和北京的两个 Region 。导到标准的 Jenkins 配置页,大家可以检查当前生成的 Jenkins 的配置,到底是什么样的,是不是正确的。当你检查没有问题之后,直接点击提交,提交一下 Code ,比如简单改一行,这个地方需不需要在部署的位置让你来选择一下到底部署还是不部署。阿里云在最开始做 CodePipeline 的时候考虑到这个问题,因为我们当时人数有限,所以这个部分直接做了自动。在 CodePipeline 这个产品出来之后,刚才部署那个位置其实是下发一条部署任务,而你真正选择部署的时候可以点击选择是部署还是不部署,这个是在两个 Region 下的 Demo 。
我不期望大家能够从我的分享里得到一个完整的 DevOps 流程该怎么做或者 DevOps 的想法该怎么去想,大家能够得到两件事情就好了。一个是大家记住 DevOps 能节省大家的时间,第二个是我给大家推荐的比较合适的 DevOps 工具,大家拿到这些工具之后回去自己看一下该怎么用。