「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]。
以上就是我關於自動化運維的一些實踐,可是還在演進的路上,但願能與你們交流。