歡迎光臨
每天分享高質量文章

一些小團隊的自動化運維實踐經驗

行業內各巨頭的自動化運維架構都各種功能各種酷炫,如下圖,讓人可望不可及。現在最終的樣子大家都知道了,但問題是如何根據自己團隊當前的情況一步步向那個標的演進?

筆者所在團隊,三個半開發,要維護幾十臺雲機器,部署了十來個應用,這些應用 90% 都是遺留系統。應用系統的編譯打包基本在程式員自己的電腦上。分支管理也清一色的 dev 分支開發,測試透過後,再合併到 master 分支。生產環境的應用配置要登入上具體的機器看才知道,更不用說配置中心及配置版本化了。
對了,連基本的機器級別的基礎監控都沒有。
我平時的工作是 50% 業務開發,50% 運維。面對這麼多問題,我就想啊,如何在低成本情況下實現自動化運維。本文就是總結我在這方面一些經驗和實踐。希望對讀者有幫助。

別說話,先上監控和告警

事情有輕重緩急,監控和告警是我覺得一開始就要做的,即使業務開發被拖慢。只有知道了當前的情況,你才好做下一步計劃。
現在市面上監控系統很多:Zabbix、Open-Falcon、Prometheus。最終作者選擇了 Prometheus。因為:
  1. 它是拉樣式的

  2. 它方便使用文字方式來配置,有利於配置版本化

  3. 外掛太多了,想要監控什麼,基本都會有現成的

  4. 以上三者,我基本都要重新學,我為什麼不學一個 Google SRE 書上推薦的呢?

之前我們已經介紹過,人少機器多,所以,安裝 Prometheus 的過程也必須要自動化,同時版本化。筆者使用的是 Ansible + Git 實現。最終樣子如下:

這裡需要簡單介紹一下:
  1. Prometheus Server 負責監控資料收集和儲存

  2. Prometheus Alert manager 負責根據告警規則進行告警,可整合很多告警通道

  3. 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 以上的版本已經原生集成了Consule: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 如何對我們的業務程式碼進行編譯打包。有兩種方法:
  1. 介面上設定

  2. 使用 Jenkinsfile:類似於 Dockerfile 的一種文字檔案,具體介紹:Using a Jenkinsfile[7]

作者毫不猶豫地選擇了第2種,因為一是利於版本化;二是靈活。
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。具體操作:
  1. 在 Jenkins 安裝 Ansible 外掛[8]

  2. 在 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]
            ]
}
這裡需要解釋下:
  1. ansiblePlaybook 是 Jenkins ansible 外掛提供的 pipeline 語法,類似手工執行:ansible-playbook 。

  2. withCredentials 是 Credentials Binding[9] 外掛的語法,用於取用一些敏感資訊,比如執行 Ansible 時需要的 ssh key 及 Ansible Vault 密碼。

  3. 一些敏感配置變數,我們使用 Ansible Vault[10] 技術加密。

Ansible 指令碼應該放哪?

我們已經知道各個專案各自負責自己的自動化構建,所以,Jenkinfile 就放到各自專案中。那專案的部署呢?同樣的道理,我們覺得也應該由各個專案自行負責,所以,我們的每個要進行部署的專案下都會有一個 ansible 目錄,用於存放 Ansible 指令碼。類似這樣:

但是,怎麼用呢?我們會在打包階段將 Ansible 目錄進行 zip 打包。真正部署時,再解壓執行裡面的 playbook。

快速為所有的專案生成 Ansible 指令碼及Jenkinsfile

上面,我們將一個專案進行 Jenkins 化和 Ansible 化,但是我們還有很多專案需要進行同樣的動作。考慮到這是體力活,而且以後我們還會經常做這樣事,所以筆者決定使用 cookiecutter[11] 技術自動生成 Jenkinsfile 及 Ansible 指令碼,建立一個專案,像這樣:

小結

總結下來,我們小團隊的自動化運維實施的順序大概為:
  1. 上基礎監控

  2. 上 Gitlab

  3. 上 Jenkins,並整合 Gitlab

  4. 使用 Jenkins 實現自動編譯打包

  5. 使用 Jenkins 執行 Ansible

以上只是一個架子,基於這個“架子”,就可以向那些大廠的高大上的架構進行演進了。比如:
  • CMDB的建設:我們使用 ansible-cmdb[12] 根據 inventory 自動生成當前所有機器的情況

  • 釋出管理:Jenkins 上可以對釋出的每個階段進行定製。藍綠釋出等釋出方式可以使用透過修改 Ansible 指令碼和 Inventory 實現。

  • 自動擴縮容:透過配置 Prometheus 告警規則,呼叫相應 webhook 就可以實現

  • ChatOps:ChatOps實戰[13]

以上就是筆者關於自動化運維的一些實踐。還在演進路上。希望能與大家交流。
相關連結:
  1. https://github.com/prometheus/node_exporter

  2. https://github.com/ernestas-poskus/ansible-prometheus

  3. https://github.com/timonwong/prometheus-webhook-dingtalk

  4. https://www.digitalocean.com/community/tutorials/how-to-manage-multistage-environments-with-ansible

  5. http://docs.ansible.com/ansible/latest/modules/consul_module.html

  6. https://github.com/geerlingguy/ansible-role-jenkins

  7. https://jenkins.io/doc/book/pipeline/jenkinsfile/

  8. https://wiki.jenkins.io/display/JENKINS/Ansible+Plugin

  9. https://jenkins.io/doc/pipeline/steps/credentials-binding/

  10. http://docs.ansible.com/ansible/2.5/user_guide/vault.html

  11. https://github.com/audreyr/cookiecutter

  12. https://github.com/fboender/ansible-cmdb

  13. https://showme.codes/2017-10-08/chatops-in-action/

原文連結:http://showme.codes/2018-06-07/devops-in-action/

Kubernetes入門與進階實戰培訓

本次培訓內容包括:Docker基礎、容器技術、Docker映象、資料共享與持久化、Docker三駕馬車、Docker實踐、Kubernetes基礎、Pod基礎與進階、常用物件操作、服務發現、Helm、Kubernetes核心元件原理分析、Kubernetes服務質量保證、排程詳解與應用場景、網路、基於Kubernetes的CI/CD、基於Kubernetes的配置管理等,點選瞭解具體培訓內容

6月22日正式上課,點選閱讀原文連結即可報名。
贊(0)

分享創造快樂