行業(yè)內(nèi)各巨頭的自動(dòng)化運(yùn)維架構(gòu)都各種功能,各種酷炫,讓人可望不可及。
如下圖,現(xiàn)在行業(yè)內(nèi)各巨頭自動(dòng)化運(yùn)維架構(gòu)的最終樣子大家都知道了,但是如何根據(jù)自己團(tuán)隊(duì)當(dāng)前的情況一步步向這個(gè)目標(biāo)演進(jìn)?
筆者所在團(tuán)隊(duì),三個(gè)半開發(fā),要維護(hù)幾十臺(tái)云機(jī)器,部署了十來個(gè)應(yīng)用,這些應(yīng)用 90% 都是遺留系統(tǒng)。
應(yīng)用系統(tǒng)的編譯打包基本在程序員自己的電腦上。分支管理也清一色的 dev 分支開發(fā),測試通過后,再合并到 master 分支。
生產(chǎn)環(huán)境的應(yīng)用配置要登錄上具體的機(jī)器看才知道,更不用說配置中心及配置版本化了。對了,連基本的機(jī)器級別的基礎(chǔ)監(jiān)控都沒有。
我平時(shí)的工作是 50% 業(yè)務(wù)開發(fā),50% 運(yùn)維。面對這么多問題,我就想,如何在低成本情況下實(shí)現(xiàn)自動(dòng)化運(yùn)維。
本文就是總結(jié)我在這方面一些經(jīng)驗(yàn)和實(shí)踐,希望對讀者有幫助。
別說話,先上監(jiān)控和告警
事情有輕重緩急,監(jiān)控和告警是我覺得一開始就要做的,即使業(yè)務(wù)開發(fā)被拖慢。只有知道了當(dāng)前的情況,你才好做下一步計(jì)劃。
現(xiàn)在市面上監(jiān)控系統(tǒng)很多:Zabbix、Open-Falcon、Prometheus,但是最終我選擇了 Prometheus。
原因有如下幾點(diǎn):
它是拉模式的。
它方便使用文本方式來配置,有利于配置版本化。
插件多,想要監(jiān)控什么,基本都會(huì)有現(xiàn)成的插件。
以上三者,我基本都要重新學(xué),我為什么不學(xué)一個(gè) Google SRE 書上推薦的呢?
之前我們已經(jīng)介紹過,人少機(jī)器多,所以安裝 Prometheus 的過程也必須要自動(dòng)化,同時(shí)版本化。我使用的是 Ansible + Git 實(shí)現(xiàn)。
最終樣子如下:
這里需要簡單介紹一下:
Prometheus Server 負(fù)責(zé)監(jiān)控?cái)?shù)據(jù)收集和存儲(chǔ)。
Prometheus Alert manager 負(fù)責(zé)根據(jù)告警規(guī)則進(jìn)行告警,可集成很多告警通道。
node-exporter[1] 的作用就是從機(jī)器讀取指標(biāo),然后暴露一個(gè) http 服務(wù),Prometheus 就是從這個(gè)服務(wù)中收集監(jiān)控指標(biāo)。當(dāng)然 Prometheus 官方還有各種各樣的 exporter。
使用 Ansible 作為部署工具的一個(gè)好處是太多現(xiàn)成的 role 了,安裝 Prometheus 時(shí),我使用的是現(xiàn)成的:prometheus-ansble[2]。
有了監(jiān)控?cái)?shù)據(jù)后,我們就可以對數(shù)據(jù)進(jìn)行可視化,Grafana 和 Prometheus 集成得非常好,所以我們又部署了 Grafana:
在 Grafana 上查看 nodex-exporter 收集的數(shù)據(jù)的效果圖大概如下:
可是,我們不可能 24 小時(shí)盯著屏幕看 CPU 負(fù)載有沒有超吧?這時(shí)候就要上告警了,Promehtues 默認(rèn)集成了 N 多告警渠道,可惜沒有集成釘釘。
但也沒有關(guān)系,有好心的同學(xué)開源了釘釘集成 Prometheus 告警的組件:prometheus-webhook-dingtalk[3]。
接著,我們告警也上了:
完成以上工作后,我們基礎(chǔ)監(jiān)控的架子就完成了,這為我們后期上 Redis 監(jiān)控、JVM 監(jiān)控等更上層的監(jiān)控做好了準(zhǔn)備。
配置版本化要從娃娃抓起
在搭建監(jiān)控系統(tǒng)的過程中,我們已經(jīng)將配置抽離出來,放到一個(gè)單獨(dú)的代碼倉庫進(jìn)行管理。以后所有部署,我們都會(huì)將配置和部署邏輯分離。
關(guān)于如何使用 Ansible 進(jìn)行配置管理,可以參考這篇文章:How to Manage Multistage Environments with Ansible[4] 。
我們就是使用這種方式來組織環(huán)境變量的。
├── 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│
現(xiàn)階段,我們所有的配置都以文本的方式存儲(chǔ),將來要切換成使用 Consul 做配置中心,也非常的方便,因?yàn)?Ansible 2.0 以上的版本已經(jīng)原生集成了Consul:consul_module[5]。
Tips:Ansible 的配置變量是有層次的,這為我們的配置管理提供了非常大的靈活性。
Jenkins 化:將打包交給 Jenkins
我們要將所有項(xiàng)目的打包工作交給 Jenkins。當(dāng)然,現(xiàn)實(shí)中我們是先將一些項(xiàng)目放到 Jenkins 上打包,然后逐步將項(xiàng)目放上 Jenkins。
首先我們要有 Jenkins,搭建 Jenkins 同樣有現(xiàn)成的 Ansible 腳本:ansible-role-jenkins[6]。
注意了,在網(wǎng)上看到的大多文章告訴你 Jenkins 都是需要手工安裝插件的,而我們使用的這個(gè) ansible-role-jenkins 實(shí)現(xiàn)了自動(dòng)安裝插件,你只需要加一個(gè)配置變量 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 搭建成以下這個(gè)樣子:
關(guān)于 Jenkins master 與 Jenkins agent 的連接方式,由于網(wǎng)絡(luò)環(huán)境各不相同,網(wǎng)上也有很多種方式,大家自行選擇適合的方式。
現(xiàn)在我們需要告訴 Jenkins 如何對我們的業(yè)務(wù)代碼進(jìn)行編譯打包,有兩種方法:
界面上設(shè)置
使用 Jenkinsfile:類似于 Dockerfile 的一種文本文件,具體介紹:Using a Jenkinsfile[7]
我毫不猶豫地選擇了第二種,因?yàn)橐皇抢诎姹净?;二是靈活。
Jenkinsfile 類似這樣:
pipeline { agent any stages { stage('Build') { steps { sh './gradlew clean build' archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true } } }}
那么 Jenkinsfile 放哪里呢?答案是和業(yè)務(wù)代碼放在一起,類似這樣每個(gè)工程各自管理自己的 Jenkinsfile:
這時(shí),我們就可以在 Jenkins 上創(chuàng)建一個(gè) pipleline Job了。關(guān)于分支管理,我們?nèi)松?,所以,建議所有項(xiàng)目統(tǒng)一在 master 分支進(jìn)行開發(fā)并發(fā)布。
讓 Jenkins 幫助我們執(zhí)行 Ansible
之前我們都是在程序員的電腦執(zhí)行 Ansible 的,現(xiàn)在我們要把這項(xiàng)工作交給 Jenkins。
具體操作:
在 Jenkins 安裝 Ansible 插件[8]
在 Jenkinsfile 中執(zhí)行
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 語法,類似手工執(zhí)行:ansible-playbook 。
withCredentials 是 Credentials Binding[9] 插件的語法,用于引用一些敏感信息,比如執(zhí)行 Ansible 時(shí)需要的 ssh key 及 Ansible Vault 密碼。
一些敏感配置變量,我們使用 Ansible Vault[10] 技術(shù)加密。
Ansible 腳本應(yīng)該放哪?
我們已經(jīng)知道各個(gè)項(xiàng)目各自負(fù)責(zé)自己的自動(dòng)化構(gòu)建,所以 Jenkinfile 就放到各自項(xiàng)目中。
那項(xiàng)目的部署呢?同樣的道理,我們覺得也應(yīng)該由各個(gè)項(xiàng)目自行負(fù)責(zé),所以我們的每個(gè)要進(jìn)行部署的項(xiàng)目下都會(huì)有一個(gè) Ansible 目錄,用于存放 Ansible 腳本。
類似這樣:
但是,怎么用呢?我們會(huì)在打包階段將 Ansible 目錄進(jìn)行 zip 打包,到真正部署時(shí),再解壓執(zhí)行里面的 playbook。
快速為所有的項(xiàng)目生成 Ansible 腳本及Jenkinsfile
上面,我們將一個(gè)項(xiàng)目進(jìn)行 Jenkins 化和 Ansible 化,但是我們還有很多項(xiàng)目需要進(jìn)行同樣的動(dòng)作。
考慮到這是體力活,而且以后我們還會(huì)經(jīng)常做這樣事,所以我決定使用 cookiecutter[11] 技術(shù)自動(dòng)生成 Jenkinsfile 及 Ansible 腳本,創(chuàng)建一個(gè)項(xiàng)目,像這樣:
小結(jié)
總結(jié)下來,我們小團(tuán)隊(duì)的自動(dòng)化運(yùn)維實(shí)施的順序大概為:
上基礎(chǔ)監(jiān)控
上 Gitlab
上 Jenkins,并集成 Gitlab
使用 Jenkins 實(shí)現(xiàn)自動(dòng)編譯打包
使用 Jenkins 執(zhí)行 Ansible
以上只是一個(gè)架子,基于這個(gè)“架子”,就可以向那些大廠高大上的架構(gòu)進(jìn)行演進(jìn)了,比如:
CMDB 的建設(shè):我們使用 ansible-cmdb[12] 根據(jù) inventory 自動(dòng)生成當(dāng)前所有機(jī)器的情況。
發(fā)布管理:Jenkins 上可以對發(fā)布的每個(gè)階段進(jìn)行定制。藍(lán)綠發(fā)布等發(fā)布方式可以通過修改 Ansible 腳本和 Inventory 實(shí)現(xiàn)。
自動(dòng)擴(kuò)縮容:通過配置 Prometheus 告警規(guī)則,調(diào)用相應(yīng) webhook 就可以實(shí)現(xiàn)。
ChatOps:ChatOps 實(shí)戰(zhàn)[13]。
以上就是我關(guān)于自動(dòng)化運(yùn)維的一些實(shí)踐,但是還在演進(jìn)的路上,希望能與大家交流。
-
監(jiān)控系統(tǒng)
+關(guān)注
關(guān)注
21文章
3933瀏覽量
175670 -
自動(dòng)化
+關(guān)注
關(guān)注
29文章
5599瀏覽量
79460 -
機(jī)器
+關(guān)注
關(guān)注
0文章
784瀏覽量
40765
原文標(biāo)題:超實(shí)用:小團(tuán)隊(duì)如何從零搭建一個(gè)自動(dòng)化運(yùn)維體系?
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論