“java
行业内各巨头的自动化运维架构都各类功能,各类酷炫,让人可望不可及。node
以下图,如今行业内各巨头自动化运维架构的最终样子你们都知道了,可是如何根据本身团队当前的状况一步步向这个目标演进?获取更多技术知识点+v186 142 996 20,豌豆×××姐在线解答哦~程序员
笔者所在团队,三个半开发,要维护几十台云机器,部署了十来个应用,这些应用 90% 都是遗留系统。web
应用系统的编译打包基本在程序员本身的电脑上。分支管理也清一色的 dev 分支开发,测试经过后,再合并到 master 分支。微信
生产环境的应用配置要登陆上具体的机器看才知道,更不用说配置中心及配置版本化了。对了,连基本的机器级别的基础监控都没有。cookie
我平时的工做是 50% 业务开发,50% 运维。面对这么多问题,我就想,如何在低成本状况下实现自动化运维。网络
本文就是总结我在这方面一些经验和实践,但愿对读者有帮助。架构
别说话,先上监控和告警并发
事情有轻重缓急,监控和告警是我以为一开始就要作的,即便业务开发被拖慢。只有知道了当前的状况,你才好作下一步计划。运维
如今市面上监控系统不少:Zabbix、Open-Falcon、Prometheus,可是最终我选择了 Prometheus。
缘由有以下几点:
它是拉模式的。
它方便使用文本方式来配置,有利于配置版本化。
插件多,想要监控什么,基本都会有现成的插件。
以上三者,我基本都要从新学,我为何不学一个 Google SRE 书上推荐的呢?
以前咱们已经介绍过,人少机器多,因此安装 Prometheus 的过程也必需要自动化,同时版本化。我使用的是 Ansible + Git 实现。
最终样子以下:
这里须要简单介绍一下:
Prometheus Server 负责监控数据收集和存储。
Prometheus Alert manager 负责根据告警规则进行告警,可集成不少告警通道。
node-exporter[1] 的做用就是从机器读取指标,而后暴露一个 http 服务,Prometheus 就是从这个服务中收集监控指标。固然 Prometheus 官方还有各类各样的 exporter。
使用 Ansible 做为部署工具的一个好处是太多现成的 role 了,安装 Prometheus 时,我使用的是现成的:prometheus-ansble[2]。
有了监控数据后,咱们就能够对数据进行可视化,Grafana 和 Prometheus 集成得很是好,因此咱们又部署了 Grafana:
在 Grafana 上查看 nodex-exporter 收集的数据的效果图大概以下:
但是,咱们不可能 24 小时盯着屏幕看 CPU 负载有没有超吧?这时候就要上告警了,Promehtues 默认集成了 N 多告警渠道,惋惜没有集成钉钉。
但也没有关系,有好心的同窗开源了钉钉集成 Prometheus 告警的组件:prometheus-webhook-dingtalk[3]。
接着,咱们告警也上了:
完成以上工做后,咱们基础监控的架子就完成了,这为咱们后期上 Redis 监控、JVM 监控等更上层的监控作好了准备。
配置版本化要从娃娃抓起
在搭建监控系统的过程当中,咱们已经将配置抽离出来,放到一个单独的代码仓库进行管理。之后全部部署,咱们都会将配置和部署逻辑分离。
关于如何使用 Ansible 进行配置管理,能够参考这篇文章:How to Manage Multistage Environments with Ansible[4] 。
咱们就是使用这种方式来组织环境变量的。
├── environments/ # Parent directory for our environment-specific directories│ │ │ ├── dev/ # Contains all files specific to the dev environment│ │ ├── group_vars/ # dev specific group_vars files│ │ │ ├── all│ │ │ ├── db │ │ │ └── web │ │ └── hosts # Contains only the hosts in the dev environment│ │ │ ├── prod/ # Contains all files specific to the prod environment│ │ ├── group_vars/ # prod specific group_vars files│ │ │ ├── all│ │ │ ├── db │ │ │ └── web │ │ └── hosts # Contains only the hosts in the prod environment│ │ │ └── stage/ # Contains all files specific to the stage environment│ ├── group_vars/ # stage specific group_vars files│ │ ├── all│ │ ├── db │ │ └── web │ └── hosts # Contains only the hosts in the stage environment│
现阶段,咱们全部的配置都以文本的方式存储,未来要切换成使用 Consul 作配置中心,也很是的方便,由于 Ansible 2.0 以上的版本已经原生集成了Consul:consul_module[5]。
Tips:Ansible 的配置变量是有层次的,这为咱们的配置管理提供了很是大的灵活性。
Jenkins 化:将打包交给 Jenkins
咱们要将全部项目的打包工做交给 Jenkins。固然,现实中咱们是先将一些项目放到 Jenkins 上打包,而后逐步将项目放上 Jenkins。
首先咱们要有 Jenkins,搭建 Jenkins 一样有现成的 Ansible 脚本:ansible-role-jenkins[6]。
注意了,在网上看到的大多文章告诉你 Jenkins 都是须要手工安装插件的,而咱们使用的这个 ansible-role-jenkins 实现了自动安装插件,你只须要加一个配置变量 jenkins_plugins 就能够了。
官方例子以下:
---- hosts: all vars: jenkins_plugins: - blueocean - ghprb - greenballs - workflow-aggregator jenkins_plugin_timeout: 120 pre_tasks: - include_tasks: java-8.yml roles: - geerlingguy.java - ansible-role-jenkins
搭建好 Jenkins 后,就要集成 Gitlab 了。咱们原来就有 Gitlab ,因此不须要从新搭建。
最终 Jenkins 搭建成如下这个样子:
关于 Jenkins master 与 Jenkins agent 的链接方式,因为网络环境各不相同,网上也有不少种方式,你们自行选择适合的方式。
如今咱们须要告诉 Jenkins 如何对咱们的业务代码进行编译打包,有两种方法:
界面上设置
使用 Jenkinsfile:相似于 Dockerfile 的一种文本文件,具体介绍:Using a Jenkinsfile[7]
我坚决果断地选择了第二种,由于一是利于版本化;二是灵活。
Jenkinsfile 相似这样:
pipeline { agent any stages { stage('Build') { steps { sh './gradlew clean build' archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true } } } }
那么 Jenkinsfile 放哪里呢?答案是和业务代码放在一块儿,相似这样每一个工程各自管理本身的 Jenkinsfile:
这时,咱们就能够在 Jenkins 上建立一个 pipleline Job了。关于分支管理,咱们人少,因此,建议全部项目统一在 master 分支进行开发并发布。
让 Jenkins 帮助咱们执行 Ansible
以前咱们都是在程序员的电脑执行 Ansible 的,如今咱们要把这项工做交给 Jenkins。
具体操做:
在 Jenkins 安装 Ansible 插件[8]
在 Jenkinsfile 中执行
withCredentials([sshUserPrivateKey(keyFileVariable:"deploy_private",credentialsId:"deploy"),file(credentialsId: 'vault_password', variable: 'vault_password')]) { ansiblePlaybook vaultCredentialsId: 'vault_password', inventory: "environments/prod", playbook: "playbook.yaml", extraVars:[ ansible_ssh_private_key_file: [value: "${deploy_private}", hidden: true], build_number: [value: "${params.build_number}", hidden: false] ] }
这里须要解释下:
ansiblePlaybook 是 Jenkins ansible 插件提供的 pipeline 语法,相似手工执行:ansible-playbook 。
withCredentials 是 Credentials Binding[9] 插件的语法,用于引用一些敏感信息,好比执行 Ansible 时须要的 ssh key 及 Ansible Vault 密码。
一些敏感配置变量,咱们使用 Ansible Vault[10] 技术加密。
Ansible 脚本应该放哪?
咱们已经知道各个项目各自负责本身的自动化构建,因此 Jenkinfile 就放到各自项目中。
那项目的部署呢?一样的道理,咱们以为也应该由各个项目自行负责,因此咱们的每一个要进行部署的项目下都会有一个 Ansible 目录,用于存放 Ansible 脚本。
相似这样:
可是,怎么用呢?咱们会在打包阶段将 Ansible 目录进行 zip 打包,到真正部署时,再解压执行里面的 playbook。
快速为全部的项目生成 Ansible 脚本及Jenkinsfile
上面,咱们将一个项目进行 Jenkins 化和 Ansible 化,可是咱们还有不少项目须要进行一样的动做。
考虑到这是体力活,并且之后咱们还会常常作这样事,因此我决定使用 cookiecutter[11] 技术自动生成 Jenkinsfile 及 Ansible 脚本,建立一个项目,像这样:
小结
总结下来,咱们小团队的自动化运维实施的顺序大概为:
上基础监控
上 Gitlab
上 Jenkins,并集成 Gitlab
使用 Jenkins 实现自动编译打包
使用 Jenkins 执行 Ansible
以上只是一个架子,基于这个“架子”,就能够向那些大厂高大上的架构进行演进了,好比:
CMDB 的建设:咱们使用 ansible-cmdb[12] 根据 inventory 自动生成当前全部机器的状况。
发布管理:Jenkins 上能够对发布的每一个阶段进行定制。蓝绿发布等发布方式能够经过修改 Ansible 脚本和 Inventory 实现。
自动扩缩容:经过配置 Prometheus 告警规则,调用相应 webhook 就能够实现。
ChatOps:ChatOps 实战[13]。
以上就是我关于自动化运维的一些实践,可是还在演进的路上,但愿能与你们交流。