丁崎诗,前游族网络MOB云平台运维负责人、前趣医网运维总监,中科大自动化系软件工程专业硕士,8年互联网运维工做经验,4年运维管理经验,带过20人的团队,也负责过近万台设备,擅长云原生技术、容器云建设、监控体系、持续集成等领域。nginx
Jenkins在K8s下的有几种部署模式?
如何使用原生控制器和资源?
包管理器是什么?怎么使用?
自定义控制器如何部署?web
通常来讲,Jenkins在K8s上部署,不管是有状态运维也好,或者无状态运维也好,无非经过如下三个手段进行:第一,原生控制器和资源,即利用已有的K8s基础架构和技术控制器,如deployment、service、基础资源来作部署;第二,包管理器Helm2来作部署;第三,自定义控制器,这部分主要是指Operator。下面就这三种模式分别展开论述。编程
1. 传统架构不管是云上仍是云下,最外层有一个负载均衡器SLB,下面是LVS,到后面就直接到nginx这一层,以后到app和应用,到最后的DB。整体来讲,传统架构的服务自愈性是比较欠缺的。为何要用K8s?正是由于能够解决这一问题:它可让咱们把单体应用本身拉起来,让用户指望的状态和运行状态保持一致。安全
正以下面右图所示,外面一层是不变的,让SLB/LVS流量进来,下面开始就发生了变化,到了nginx的一个模块后,这个模块会把流量分发到nginx pod上面去,经过nginx pod controller让用户指望的状态和运行状态保持一致,这样一来,即便在nginx pod少一个的状况下,在nginx pod controller的做用下也能保持始终有两个nginx pod的运行。App service也是相似的,先到app service的一个模块,再把流量分发到app pod上面去,具体到app pod的运行数量和运行状态也都由K8s 的组件app pod controller来负责,再到最后的DB。
2. K8s下面有不少基础资源,不管是跑Jenkins仍是Grafana或者其余,如何选用这些基础资源是部署时首先要考虑的问题。
2.1 service。service有五种,比较常见的有Headless、NodePort、ClusterIP。以NodePort型service为例,它提供了一种外部流量访问K8s集群中service入口的方式。当外部用户要访问K8s集群中的一个web应用时,那么咱们能够配置对应service类型为NodePort。
2.2 Volume。对于K8s来讲,有两大类的存储:经过PVC+PV来定义静态的存储,经过PVC+SC(存储类)+PV来定义动态的存储。初学者容易混淆的是,PVC是用户指望定义的一个东西,PV才是它的存储时限。
2.3 RBAC。即基于角色的访问控制,首先会定义一个服务帐号ServiceAccount。这个服务帐号是给应用用的,好比Jenkins确定也要用到一个ServiceAccount。规则是Role、ClusterRole。咱们能够把ServiceAccount经过RoleBinding绑定到Role上,则该用户拥有role定义的权限;经过Clusterrolebinding绑定到Clusterrole,则该用户拥有Clusterrole定义的权限。对于namespace内的受权使用RoleBinding,集群范围内使用ClusterRoleBinding。
2.4 ConfigMap&Secret。这两个都是用来保存K8s上面应用的配置。它们两个惟一的区别就是ConfigMap是保存非敏感的信息,Secret能够保存敏感信息。这两个组件的申请、使用、加载其实都是大同小异的。
2.5其余须要注意的点。其一,调度指望和调度机制。机器不少时要管理好运维类pod和业务pod的分离。同时要努力实现真正的业务高可用;其二,网络策略。当有不少pod在运行时,网络策略是必须考虑的;其三,安全。在K8s上面把一个pod跑起来其实很简单,难的是如何跑好,安全也是须要考虑的一大因素。
3. 如何用原生控制器和资源区部署一个Jenkins应用。
3.1划分所需的名称空间。这一条不是非必选的,咱们对于一个应用会划分一个专门的namespace,能够按环境来分,也能够按业务组来分。
3.2基础控制器选型。基础控制器有哪些?Deployment控制器、SatefulSet控制器、DaemonSet控制器、job控制器、cronjob控制器。对于Jenkins来讲,无疑选择Deployment来作基础控制器。
3.3基础资源选型。应用跑起来以后,怎么让K8s集群外的人能访问到咱们的应用?简单来讲,能够直接用NodePort来作,在存储上选的是PVC+PV,PV是使用NFS来实现。
3.4服务暴露(可选)。由于解决Jenkins是南北流量的问题,而不是集群内访问东西流量的问题,因此服务暴露是咱们须要考虑的。对于Jenkins来讲能够用NodePort直接来作,也能够后面去接Ingress nginx作服务暴露,也能够挂到SLB后面作服务暴露。
3.5网络策略、安全、调度机制。要让一个Jenkins应用跑起来、能用以外还能跑的好,就须要考虑全面周到一点。网络
前述提到,原生控制器缺什么?配置文件的生命周期管理是原生控制器所欠缺的。哪些文件该是我考虑的,这个文件变动了怎么办?怎么作版本管理?这就是Helm要解决的问题。
1. Helm2的拓扑架构。以下图所示,charts是基础配置模板,config是charts配置参数,helm是命令行客户端,经过grpc协议,向tiller发送请求,用来作版本发布、回滚、打包、升级。tiller存储在CM里面的,而后在Helm3里已经移除了,由于它有一些局限性。要注意的是,Helm和Docker是同样的,有一个仓库的概念。对于一个成熟的软件来讲,第三方的支持是不多的,不可能让全部的helm都本身写,因此对于helm来讲,它有本身成熟的远程仓库,我是写在集群外的。事实上还有一个集群内的,版本管理以后会有一个local仓库,能够把本身的发版应用打包,而后发布到local仓库,作内部的版本管理。架构
2. 部署流程。
2.1工具的部署安装。对于基础选型来讲并无不少选择,无非是选Helm2或Helm3。
2.2 charts制做。Helm有两种类型的repo,一个是已有chart使用,直接在repo中搜索和安装,不用本身造轮子;第二个是自定义chart制做。 以Jenkins为例,能够经过Helm create Jenkins帮咱们生成一个树状结构的整个东西(以下图)。再看外面两个文件,这里templates是K8S内置的,就是它本身的基础控制器的文件。templates以外的这两个charts、values是Helm本身定义的东西。app
咱们把前面参数定义好以后,能够经过Helm install -n “namespace” Jenkins,把Jenkins目录下的项目装起来。第一步,初始deployment;第二步,相关pod在建立;下一步,service,pod去跑,全部运行完成以后,跟你说“你是经过这些命令去拿到你对应的URL”。最后能够经过helm list看到刚才发布的应用,Jenkins版本发了1版,发布的时间点、状态是已部署,chart是Jenkins-0.1.0,namespace是default。
2.3 release迭代。对于自定义好的create以后的charts怎么玩?不可能发了一版后就彻底不动了,更新(upgrade)怎么作?若是不符合预期,多是产品预期、业务预期、技术预期,须要回滚(rollback),又要怎么作?
2.3.1更新。看下图中的chart.yaml文件,先要去变动helm的描述清单,appVersion变动,version也要变动。除了以前变动以外,把镜像仓库版本也进行变动。
2.3.2回滚。回滚是用命令helm rollback,后面跟位置参数。Jenkins须要回滚哪一个应用?第一个位置参数是业务名,第二个字段是有一个default值,是默认后帮你回滚到1版本,写一个1。回滚以后,前面进行第一次初始化发版,第二次更新,第三次回滚,为何这个版本仍是3呢?这里是让咱们每次发版都有记录可查,因此记录是递增的。
2.4打包和发布。当这两个状态结束以后,要进行打包和发布,打包到哪里?打包到咱们定义好的local repo里来。第一步就是用Helm package打包项目,而后建立项目存放路径,把打包好的项目丢过来,再经过helm.serve的命令指定好本地仓库的地址是哪里,最后就能够在本地仓库里找到刚才的项目了。
3. 小结。关于现状和挑战。
3.1 Helm完善l k8s资源生命周期的管理,如:升级、回滚、下线、发布等;解决了单体应用建立时的配置依赖问题;提供了更上层的编排能力,交付的标准颗粒度是应用,而不是k8s基础对象或组件;Helm的生态圈和官方提供的众多包含有最佳实践的chart包。
3.2 挑战在于:须要充分了解k8s原生组件和资源细分的应用场景和区别;Helm工具自己架构设计和用户体验的不足:如Tiller权限控制、数据存储(CM)、发布体验等。负载均衡
1.自定义控制器(Operator)的诞生。2016年秋天,CoreOS在福斯特城(Foster City)公寓结对编程。当时两我的作了一个小项目,也就是Operator。由于他们发现K8S原生的东西并不能知足用户指望。好比在传统架构之上,MySQL集群,不管是主从也好,Mango集群,分片、副本级也好,怎么作数据备份,怎么作数据迁移,怎么作回滚,怎么作备份,用K8S原生的基础组件、基础资源其实根本作不了。Operator所作的就是教咱们定义平常运维的经验、操做代码化。less
2.自定义控制器(Operator)作了什么?总体能够分为四点。其一,用户指望。K8S的维护者确定但愿用户能更简单、更方便地去用,帮助他本身的产品去上集群;其二,研发实现。除了帮助用户支撑所须要的第三方组件快速上K8S集群以外,完善和本土化这些复杂应用集群的运维功能也相当重要;其三,K8s赋能,容许用户添加 API 对象的插件能力。若是K8S没有一个暴露的API或暴露接口让研发人员去作事也是纸上谈兵;其四,社区推广。使用方能够在Operatorhub.io和awesome-Operators快速分享或找到Operator。
3.如何经过Operator部署一个Jenkins应用。简言之,先定义CRD,再定义Controller,最后定义他的用户状态,帮用户去识别化他的应用集群。
3.1定义CRD。CRD是K8s给用户可以本身写Controller的一个API,扩展K8s API的地方。
3.2定义Controller。对Jenkins来讲,Jenkins Operator0.3.3是Jenkins官方已经写好的一个Operator,咱们只要拿下来去用。
3.3定义用户指望的状态。
4. Jenkins operator帮咱们简化了什么?
4.1自动化发现和配置。以seed job为例。和传统玩法相比,运维人员须要作的只是把这些job写成Jenkinsfile,保存在Git里面去,这样就能够作一键迁移了。这让咱们有更多的视角去看到底哪些好、哪些很差。
4.2配置代码。这里所有基于配置代码的方式去作,而不是传统的基于磁盘的备份,这么作的好处显而易见。
4.3备份和还原。backup and restore内置字段,清楚地告诉你这一块是作backup的,这一块是作restore的。这样作至关于把用户习惯直接分装掉了,所见即所得。
5 小结。关于现状和挑战。
5.1完善复杂应用的部署逻辑;本土化用户的使用习惯;自由度高,用户能够可定制化开发controllers。
5.2挑战在于:须要充分了解k8s原生组件和资源细分的应用场景和区别;须要充分了解CRD和K8s API;须要必定的研发能力。运维
Jenkins其实部署在K8S上三种模式,不必定说只教会你们用Jenkins,其实别的东西也同样。但这三种模式都离不开一点:都须要去了解K8s下面全部的基础控制器、基础资源怎么去使用、怎么去定义。当你把全部基础控制器和资源都摸透以后,用Helm三、Helm2也好,网上去查Operator也好,都是能够的。只有底子打好,知道哪一个东西是干什么的时候,才能知道它们的应用场景。