自動化工具後起之秀Ansible的部署實踐

本文轉自微信號EAWorld。掃描下方二維碼,關注成功後,回覆“普元方法+”,將會獲得熱門課堂免費學習機會!

從早期手動加腳本的部署方式,到後來自動化工具(chef, puppet, saltstack, ansible等)的出現,再到如今DevOps的盛行,企業應用部署正式進入平臺部署階段,CD(持續部署)已經成爲企業對應用部署的標準需求,運維的交付也不再是以周或天爲單位,而是以分鐘爲單位。

本文主要介紹自動化工具Ansible,及其在普元DevOps平臺中的應用部署和日常應用部署中的實踐。

本文目錄:
一、如何選擇合適的自動化工具?
二、Ansible架構圖及工作流程
三、DevOps基於Jenkins+Ansible+GitLab的部署實踐
四、Ansible日常應用部署實踐
五、總結

一、如何選擇合適的自動化工具?

面對衆多的自動化工具(chef, puppet, saltstack, ansible等),我們該如何選擇適合自己的呢?總的來說,無外乎從以下幾點來權衡利弊。

活躍度(GitHub活躍度,社區活躍度)
學習成本
使用成本
編碼語言
性能

圖片描述

各種開源的自動化工具在GitHub的關注度是其活躍度最直觀的體現,從圖中Contributors這一項就可以看出Ansible和SaltStack的開源項目貢獻者遠遠多於其它幾種自動化工具。越活躍的開源項目往往意味着更完善的功能和更高效的問題解決率。

Ansible Galaxy和Salt Formulas都提供了豐富的第三方工具,基本覆蓋了日常部署應用的所有需求。

圖片描述

Puppet和Chef使用的開發語言是Ruby,而Saltstack和Ansible使用的開發語言則是在運維開發這個圈子相對吃得開的Pythen,這也是SaltStack和Ansible相對於Puppet和Chef更容易被接收的原因。

很多選擇Ansible的朋友,大多都是覺得Ansible上手簡單,因爲Ansible默認採用SSH連接的方式,不需要安裝配置Client,只需要在Server端配置SSH連接信息即可。這也是Ansible相對其他自動化工具的一大優勢,但是這一優勢帶來的影響就是實現機制的差異導致在大規模環境下,Ansible的性能確實要比SaltStack差很多,當然,規模大概在一兩百臺機器左右Ansible的性能也是可以接受的。如果是做少量機器應用部署的話,性能問題也就不是那麼關鍵了。

綜合以上因素,最後我們選擇Ansible作爲我們DevOps部署功能底層實現的自動化工具。

二、Ansible架構圖及工作流程

先來看看這張架構圖(來源於網絡),看起來是不是很簡單,首先對Ansible架構圖的各個組成部分作一個說明。

圖片描述

核心引擎:即圖中所看到的Ansible。

核心模塊(Core Module):和大多數運維工具一樣,將系統和應用提供的能力模塊化,一個模塊有點像編程中一個功能接口,要使用的時候調用接口並傳參就可以了。比如Ansible的service模塊,你要保證名爲nginx的service處於啓動狀態,只需要調用service模塊,並配置參數name: nginx,state: started即可。

自定義模塊(Custom Modules):顯而易見,如果Ansible的核心模塊滿足不了你的需求,你可以添加自定義化的模塊。

插件(Plugins):模塊功能的補充,如循環插件、變量插件、過濾插件等,也和模塊一樣支持自定義,這個功能不常用(我沒用到過),就不做細說了。

劇本(playbooks):說到這個,先說說Ansible完成任務的兩種方式,一種是Ad-Hoc,就是ansible命令,另一種就是Ansible-playbook,也就是ansible-playbook命令。他們的區別就像是Command命令行和Shell Scripts。

連接插件(connectior plugins):Ansible默認是基於SSH連接到目標機器上執行操作的。但是同樣的Ansible支持不同的連接方法,要是這樣的話就需要連接插件來幫助我們完成連接了。

主機清單(host inventory):爲Ansible定義了管理主機的策略。一般小型環境下我們只需要在host文件中寫入主機的IP地址即可,但是到了中大型環境我們有可能需要使用動態主機清單來生成我們所需要執行的目標主機(需要雲環境支持動態生成Ansible host inventory)。

圖片描述

Ansible工作流程大致就是這個樣子,之後在日常應用部署實踐部分對一個應用部署的調用流程再做說明。

三、DevOps基於Jenkins+Ansible+GitLab的部署實踐

既然已經決定用Ansible來完成應用部署的底層實現,那我們如何將Ansible和DevOps結合起來呢?

首先想到的是API,Ansible倒是有一套Python的API接口,但想來在DevOps中做Ansible Python接口的集成封裝不太容易,再就是Ansible通過命令行提供服務,並沒有啓動進程及監聽端口,沒想通如何在DevOps中調用Ansible接口,自己對Python亦不是太熟,因此便放棄了這種方式。

之後便瞭解到了Ansible Tower,Ansible Tower是Ansible的web界面,採用REST API作爲接口,先安裝起來看看效果。

圖片描述
圖片描述

上圖爲首頁及任務執行頁面截圖,從它相對簡潔的頁面我們就能看出它提供的大部分功能。

首頁推送最近使用的Job和最近Job執行情況。
主機管理。
實時的playbooks輸出和瀏覽。
執行歷史數據預覽及報表。
基於角色的訪問控制。
REST API。

任務頁面截圖是一個安裝部署Nexus的Task,在它的歷史任務執行頁面可以清晰的看到任務執行的實時輸出,任務執行的變量信息,以及任務每一步的耗時情況等。

Ansible Tower看起來還是挺不錯的,不僅提供了主機管理,任務管理,任務歷史及實時輸出等能力,還提供了直觀實用的報表。奈何,因爲它收費的原因,還是被PASS掉了。

正苦思冥想之際,有幸得見一篇文章《Jenkins+Ansible+Gitlab自動化部署三劍客》,文中提到的這種使用方式與我們DevOps本身的很多設計點不謀而合。

圖片描述

在CI(持續集成)的設計上,我們本身也是將Jenkins作爲集成工具來使用的,同時Jenkins2版本的Pipeline as Code也給CD(持續部署)帶來了無限的可能。當然,也增加了一定的學習成本,那就是Pipeline的核心Groovy,一種基於JVM(Java虛擬機)的敏捷開發語言。

Jenkins給我映像較深的一點就是它強大的擴展性,它同樣支持Ansible的擴展插件Ansible plugin,在Pipeline中使用插件和其他類型的Job略有不同,創建一個Pipeline Job之後,可以使用Pipeline Syntax配置插件和參數,然後Jenkins會自動生成可以在Pipeline中使用的代碼片段。

再來說GitLab,當然,也可以是其他Jenkins支持的代碼版本控制系統。它在整個過程中擔任什麼樣的角色呢?試想,我們所需要管理的部署機器和產品對應着的部署腳本,如果單單只是保存在某個Server端,如何進行編寫維護以及更新,如何形成運維日積月累過程中的經驗與知識產物。

這裏GitLab可以很好的幫助我們進行Playbooks的管理,我們只需要將Playbooks提交到倉庫,然後在通過Jenkins執行部署之前,將Playbooks拉取到Job的workspace中,然後調用執行就可以了。

如何將DevOps與這種Jenkins+Ansible+GitLab的實現方式結合起來呢?

圖片描述

我們DevOps部署大致操作流程如下:

資源:創建部署需要的環境信息,可以是物理機,虛擬機以及容器雲環境。
設計:設計部署容器,比如部署mysql和tomcat並設置tomcat依賴mysql的關係。然後提交設計。
轉換:配置部署策略以及部署模式,設置部署容器的參數,創建部署計劃並執行部署。
運維:部署容器運維,啓停、卸載、伸縮、回滾等操作。

實現方式大致可以簡化爲:根據模板化的表設計動態生成部署配置頁面,頁面參數傳遞結合靜態的部署模板(groovy)生成Jenkins的config.xml文件,然後調用Jenkins的API接口創建Jenkins的部署Job。

那我們要進行一個部署容器的擴展,我們需要做哪些工作呢?

1.在模板化的表設計中新添加部署容器(如mysql)的相關信息(組件依賴,屬性定義字段等)。

2.按照既定的規則在腳本目錄添加groovy模板(安裝,卸載,運維等)。

3.在腳本庫中添加groovy模板中對應調用的ansible playbooks。

四、Ansible日常應用部署實踐

因爲DevOps應用及其集成的第三方工具也需要自動化部署,剛好又接觸了Ansible這樣一款自動化工具,所以就寫了一套快速部署DevOps應用及一些第三方工具的playbooks。

圖片描述

單看這張圖,大家可能覺得有點不明所以,我們結合DevOps平臺部署的playbooks目錄結構及文件類容對此部署設計做一個說明。

圖片描述

Ansible機器分組:就是Ansible的host inventory文件,內容爲機器分組信息及組變量,在DevOps平臺部署中擔任配置文件的角色,部署前只需要修改此文件即可(修改應用的安裝配置和對應每個分組的部署機器)。

DevOps部署角色:對應的site.yml是應用部署的入口文件,這裏將DevOps應用分成8個角色,分別是devops、mysql、jenkins、nexus、sonarqube、gitlab、cmdb、jira。每個部署角色對應多個role。

Ansible Role:可以理解爲Ansible中可複用的最小的操作單元,這裏考慮的不只是DevOps的部署了,考慮到playbooks文件在今後的日常使用中也會使用到,比如要安裝一個jenkins,只需要在inventory中添加機器信息,然後定義入口文件使用repo(考慮到無外部網絡訪問權限情況,配置內網源)和jenkins兩個role即可。

執行命令行ansible-playbook –i devops.inventory site.yml即可開始執行部署,首先會根據site.yml入口文件中hosts中配置的信息去devops.inventory中獲取主機及主機變量信息,然後根據remote_user配置和ansible.cfg中配置的SSH連接信息去執行連接,然後根據roles配置的角色去執行相應的Task。接下來我們看看Ansible Role的目錄結構和內容。

圖片描述

Roles主要依賴於目錄及文件的命名和擺放。目錄說明如下:
file:copy模塊文件默認路徑,這裏存放安裝文件和一些不需要修改的固定文件。

handlers:在發生改變時執行調用的task。如在tasks目錄下main.yml中有一步修改配置文件後調用handlers,當執行時該步狀態爲changed就會調用handlers中的task。

tasks:存放role任務文件的目錄,main.yml就是任務入口文件。

templates:template模塊文件默認路徑,用於存放配置文件和會改變的文件,文件中會定義變量信息,在傳遞時進行變量的替換。

vars:role的變量目錄,可以存放role的變量配置信息,爲了方便用戶統一配置,這裏未使用role變量,而是採用了inventory中的組變量。

以下爲在Playbooks中用到的一些技巧

圖片描述

register:註冊變量。

場景:在mysql5.6版本安裝完成後會生成默認root用戶的密碼並寫進~/.mysql_secret文件,那我們要在安裝完成之後用這個root密碼執行初始化操作就可以使用這種註冊變量的方式。

擴展用法:判斷某個文件或文件夾是否存在,來控制task是否執行。當when語句的結果爲true時才執行task。

Include:文件加載,在一個任務文件中調用另一個任務文件。

場景:一個常用的任務片段在現今或之後的任務文件中都可能用到,我們可以將它單獨抽離編寫一個任務文件,然後再其它文件通過include引用即可。

擴展用法:通過定義變量或註冊變量的方式,動態控制是否執行一個任務文件。

ignore_errors:是否忽略錯誤。

場景:執行某一步,即使該步返回錯誤依然繼續其他的任務。常用與command和shell模塊。如示例,在安裝mysql時先去刪除機器可能自帶的mariadb-libs,在不存在mariadb-libs包時會報錯,忽略此錯誤。

wait_for: 校驗文件或端口的狀態。

場景:等待一個端口啓動、關閉或一個文件的生成、刪除,常見於啓動應用後等待應用端口啓動,然後執行接下來的任務。

擴展用法:用來校驗端口是否啓動或文件是否存在。

setup:獲取目標機器信息,並註冊成主機變量。

場景:獲取目標主機ip信息,並將ip寫進某個配置文件。任務執行第一步就會默認會調用setup模塊獲取目標機器信息,只需要在腳本中直接使用變量ansible_default_ipv4.address就可以引用主機ip地址。

template:自定義模板。

場景:大多數情況,我們只需要把配置文件中某些需要變更的變量抽成配置即可,但像nginx這種需要動態配置或相對複雜的配置文件,就可能會用到Jinja2強大的模板自定義的能力了,最後這張圖是安裝DevOps集羣環境是根據group分組中的ip以及組變量中的端口配置動態生成nginx config文件的一個片段。

五、總結

Ansible作爲自動化工具中的後起之秀,因其簡單易用,無代理架構的特性,已經被廣大的自動化運維愛好者和初學者所接受並使用,如果不做二次開發,甚至都不需要對Python有深入的瞭解,實際上它豐富的模塊也已經基本滿足日常運維所有的需求。依稀記得第一次接觸到Ansible是在部署openshift(基於k8s的容器雲平臺)的時候,這種複雜應用的部署通過簡單的幾行配置就完成了,不只是運維,相信對Linux系統有所瞭解的研發人員也可以通過Ansible完成複雜應用的部署。

關於作者
張子康
普元研發工程師,曾參與神華災備雲平臺、萬達DevOps平臺等項目。對雲計算相關技術有濃厚的興趣,熟悉IaaS,k8s,docker等技術,在DevOps項目中主要負責集成環境的搭建以及部署功能的底層實現。

圖片描述

關於EAWorld
微服務,DevOps,元數據,企業架構原創技術分享,EAii(Enterprise Architecture Innovation Institute)企業架構創新研究院旗下官方微信公衆號。

掃描下方二維碼,關注成功後,回覆“普元方法+”,將會獲得熱門課堂免費學習機會!
微信號:EAWorld,長按二維碼關注。

圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章