天天看點

Ansible權威指南.

Ansible權威指南.

linux/unix技術叢書

ansible權威指南

李松濤 魏 巍 甘 捷 著

圖書在版編目(cip)資料

ansible權威指南 / 李松濤,魏巍,甘捷著. —北京:機械工業出版社,2016.11

(linux/unix技術叢書)

isbn 978-7-111-55329-8

i. a… ii. ①李… ②魏… ③甘… iii. 程式開發工具-指南 iv. tp311.561-62

中國版本圖書館cip資料核字(2016)第258615号

出版發行:機械工業出版社(北京市西城區百萬莊大街22号 郵政編碼:100037)

責任編輯:高婧雅 責任校對:殷 虹

印  刷: 版  次:2016年11月第1版第1次印刷

開  本:186mm×240mm 1/16 印  張:21.75

書  号:isbn 978-7-111-55329-8 定  價:79.00元

凡購本書,如有缺頁、倒頁、脫頁,由本社發行部調換

客服熱線:(010)88379426 88361066 投稿熱線:(010)88379604

購書熱線:(010)68326294 88379649 68995259 讀者信箱:[email protected]

版權所有 ? 侵權必究

封底無防僞标均為盜版

本書法律顧問:北京大成律師事務所 韓光/鄒曉東

praise?本?書?贊?譽

以下推薦人按姓名音序排序。

随着資訊時代發展,全球運維體系不斷更新,靈活多變、安全穩定、自動高效的持續保障迫在眉睫。開源運動為it奠定了堅實的基礎環境,使得我們可以不斷吮吸着其中的養分而茁壯成長。然而,為适應快速、高效運維,自動化基礎設施勢必成為運維必備技能。縱觀自動化工具,如puppet、saltstack、func、chef、ansible,基于linux原生ssh(不需要agent),并糅合衆多老牌運維工具的優秀特性,內建了批量指令執行和檔案處理等諸多功能。相信不少朋友已經在使用這些工具,作者也從中直接受益,并結合實戰經驗彙總成本書,以幫助更多熱愛開源的朋友。我們堅信,集衆人智慧的結晶,專注開源事業,定能讓更多人享受開源運動帶來的豐碩成果。而ansible也将成為專業人員必備技能,這本集合基礎原理和實戰案例的書籍會成為運維人員必備寶典。

——馬永亮,馬哥教育創始人

ansible可以說是配置管理領域的新銳,一經推出便受到了很多運維及客戶的青睐。ansible的架構設計簡潔,上手也非常簡單,學習成本很低。在我們的客戶自動化方案中,考慮到安全性、穩定性、便捷性等多方面要求,我們也把對ansible的相容作為首選。非常感謝stanley和其他筆者不辭辛勞地編寫此書,值得大家欽佩。相信本書能給讀者帶來很大的收益。

——王津銀(網際網路運維雜談老王),優維科技創始人

目前,雲計算正在快速落地,雲使資源的利用更高效,但是雲隻解決了系統層面資源使用的問題,業務層面的運維自動化還必須借助運維自動化工具、結合具體的業務場景來解決。在衆多的自動化工具中,使用python開發的ansible無疑是運維人員的最愛,因為它符合python簡單高效的原則。但是ansible入門容易精通難。很高興看到李松濤和他的朋友們撰寫的這本書的出版,本書使快速精通ansible成為可能。相信通過閱讀本書,沒有接觸過ansible的讀者可以快速入門,已經在使用ansible的讀者可以從中學到更多知識。

——肖力,《深度實踐kvm》作者

有一種距離叫菜鳥到高手的進階,有一種練級捷徑叫活學活用《ansible權威指南》。本書案例通用、好使、接地氣。

菜鳥得之如獲至寶,穩紮穩打中輕松晉級;高手用之簡潔高效,深度實踐中融會貫通。

資深腳本運維有一天會發現,越做越累,正所謂:成也腳本,累也腳本。

場景化運維,可能嗎?playbook幫你實作操作通用或者簡化,把紛繁複雜的腳本變為場景中一個個的步驟,讓你可以邊維護邊遊戲,提升運維人員的工作效率。

還在為serverlist的管理發愁嗎?invertory幫你實作伺服器分層管理,架構拓撲圖一目了然。

還在為生成配置檔案時感歎“時間都去哪了”嗎?jinjia的高效配置生成速度,讓生成1萬個複雜配置檔案由30分鐘變為1分鐘,并且減少了業務停機時間。

本書對ansible的周邊擴充介紹得比較實在,理論聯系實踐。作者從豐富的工作經驗總結出案例,詳細列舉了celery、子產品擴充等具體應用,讓ansbile更加貼合實際的應用場景。

如果你想成為場景化運維人員,如果你想提升工作效率,本書就是為你量身定制的不二選擇。

——張志浩,騰訊遊戲營運規劃專家

随着網際網路和雲計算的蓬勃發展,資料中心基礎設施急速增加,it運維逐漸成為現代企業生産經營的核心,而且要求越來越高。而要實作海量系統運維和devops,兼顧穩定和效率,就離不開運維自動化軟體。

回顧運維自動化的發展曆程,最早的運維自動化是腳本自動化,依靠ssh通道批量執行腳本。但人們很快就發現,每個運維人員習慣寫一堆腳本,腳本的管理維護成為問題,誤操作也時有發生。為了解決這個問題,puppet、saltstack、ansible等一批優秀的開源軟體應運而生,運維正式進入自動化時代。

目前中國大部分資料中心還是處于“人肉運維”的時代,自動化運維的需求非常強。但對于初學者來說,要駕馭好這些軟體也不容易。很多初學者會誤認為運維自動化的核心是批量執行,其實不然,運維自動化的核心是配置管理,自動化隻是最終效果。

ansible是運維自動化軟體的後起之秀,發展非常快。其特點是簡單易用、無代理架構,使用python這樣的運維語言易于二次開發,這使得ansible非常适合網際網路的運維場景和初學者。

本書作者之一李松濤是行業中少有的“能文能武”運維從業者,經過了騰訊海量系統運維的鍛煉,又承擔了ansible中國“布道者”的角色,不辭辛苦地在社群和行業中分享經驗,最終,花費了大量心血促成了本書的誕生。“授人以魚,不如授人以漁”,本書不但介紹了ansible的基礎知識,還介紹了ansible的實踐經驗和高階的二次開發,對讀者深入了解ansible、建構自動化運維體系非常有幫助。

我把運維自動化分為:人肉運維、操作自動化、資源統一配置、一體化運維、營運指揮5個成熟度階段,廣大運維同行可以做的事情還很多。衷心祝願李松濤再接再厲,通過著書立說和傳道授業的方式,惠及更多的運維從業者,讓天下沒有難運維的資料中心。

——智錦,資深運維從業者,杭州雲霁科技有限公司ceo

前  言?preface

為什麼要寫這本書

首次接觸ansible是緣于一次杭州出差。當時接觸網際網路3年左右,正是技能的儲備階段,看到ansible這樣的新興自動化工具不免充滿好奇。當時騰訊的藍鲸還沒有出來,但abs腳本和ijobs自動化體系已經應用多年,并在整個ieg中心廣泛應用。大型企業講究分工精細化,各司其職,強大的自我研發能力。但伴随業績和kpi的壓力,很多人其實是沒有多餘精力關注外界技術領域的發展,尤其是遊戲行業,行業自身屬性對開發人員的技術能力要求非常高,前沿開源技術與業務特殊性需求并不能很好地融合,緻使多數工具依賴于開發人員,整體運維體系以應用、發現、維護、服務方向為主,底層運維沒有技術能力和資源協調能力為業務創造直接價值。進階運維和上司層更需着眼于高層面的業務拓展和整體運維體系規劃,是以多數網際網路前沿技術以技能儲備的方式被引入,待機蓄力而發。

後來藍鲸和ijobs融合後,在強大技術力的驅動下,運維的技術能力進一步淡化,對應的業務能力、需求發現、服務意識被強化,并提出更高的要求,devops的崗位定義更加明确。藍鲸平台類似于蘋果公司的app store,是一個載體,隻要有開發能力就可以編寫自己的應用。隻要應用的通用性足夠高,所有業務都可以下載下傳使用,而通用性則是開源技術最講究的點。同時開源工具也是非常好的學習對象,往往經過簡單的修改即可變成自己的産品,是以運維對開源技術的關注度越來越高,而筆者也正是在這樣的背景下接觸到ansible。

對比主流的自動化工具saltstack、puppet等,ansible給人最直覺的感覺就是比較簡單,而這也是筆者選擇使用ansible最重要的理由之一。因為筆者一直認為每個人精力有限,如騰訊早期的ops技能教育訓練希望個人同時兼備ops和dev的戰略,但直到現在身邊真正同時具備dev和ops能力于一身的人鳳毛麟角。類似于puppet和saltstack這樣的工具,進階使用均需涉及諸如class類開發這樣的技能才可運用,而初級運維和沒有開發經驗的運維掌握面向對象技術去開發進階應用确實沒有那麼妥當。ansible早期的官網也是以stupid simple來形容其簡單程度的,其前沿的去中心化思想和近期被redhat(紅帽)官方收購的消息,也更堅定了筆者使用ansible的想法。

但當時ansible在國内公司應用的并不多,且其官網屢屢被破解,使得雖然自動化的理念早已家喻戶曉,但國内ansible的文檔和社群卻始終不溫不火。無獨有偶,筆者發現騰訊也開始在自家藍鲸平台使用ansible,并結合業務進行了深入應用,是以就産生了編寫一本ansible書籍的想法。是以,也有了後來的ansible官網中文翻譯團隊和本書寫作團隊,再後來也就有了ansible中文權威網站、運維部落微信公衆号、ansible部落微信群、ansible中文權威qq群。更為幸運和開心的是,在堅持的過程中也遇到了一批自動化工具愛好者。http://www.ansible.com.cn/将ansible官網中大家日常常用的部分功能翻譯成中文,是以起名為ansible中文權威指南。而後google、baidu的關鍵字搜尋結果僅次于官網,這使得我們的信心大增。這裡要特别感謝馬哥linux團隊成員的薛定谔的章魚、guli、以馬内利、黃博文、coocla、雲中鶴、stanley,這些朋友們曆經數月,辛勤翻譯多達5萬字文檔。

在一次和朋友聊天中,朋友問到你們ansible已經應用這麼久,同時也有自己獨立開發的界面,現在國内ansible的勢頭雖高,但文檔和書籍欠缺,何不把你們的經驗總結出來分享給更多朋友呢。我當時一怔,但也有擔心:一方面精力不支,另一方面老婆懷孕,我擔心生活工作不能兼顧。後來在老婆的鼓勵下,經肖力和黃博文兄的引薦認識了華章公司的高編輯,正式開始書籍的編寫之旅。在這個過程中,很高興又有新的夥伴騎行牛人魏巍和python能力出衆的甘捷陸續加入,也使得個人的壓力和精力有更多的釋放,書籍的内容也有更完整、豐富的互補。在整個寫書過程中我們也在成立的運維部落、ansible公衆号和qq群,定期分享書籍内容,收集使用者回報和體驗。到目前為止,qq群近1300人,公衆号也有2000多人在關注。群中也專門請行業應用經驗豐富的專員來解答ansible的技術類問題,同時成立專門的qa站點,收集使用者qq群問題處理方案,并對積極回答問題勇于分享的朋友定期寄送禮品以示鼓勵。團隊很高興也很幸運能通過這樣的方式為國内ansible的發展貢獻自己的力量。

本書特色

從技術層面講,運維自動化理論及思想在國内日趨成熟,自動化工具更是遍地開花。現在運維不再糾結于沒有工具可用,而是惆怅于選擇何種工具。而ansible正是在這樣的大環境下産生,并且迅速脫穎而出。ansible去中心化思想和“簡單就是一切”的原則也使其在運維圈快速流行。但正如所有事物一樣,入門簡單并不代表深入簡單,這也正是本書的意義所在。

從适合讀者閱讀和掌握知識的結構安排上講,本書分為“基礎入門篇”“進階進階篇”“web自動化開發篇”。本書在介紹新技術應用的同時更注重讀者對技術的消化和接受程度,整個過程都秉承原理→練習→實戰的思路,讓讀者輕松逐漸深入,不會有生硬和突兀感。在介紹ansible的核心技術應用playbook章節更是不惜用50頁左右的篇幅,通過企業實際案例講解分析playbook的使用技巧和經驗心得。在ansible企業應用實戰相關章節,詳細介紹ansible與現今流行技術的結合使用,以及如何自我發展、自我完善技能。

在由淺入深介紹ansible的同時,本書所有的應用案例按章節順序全部上傳至github,附帶自研的web自動化頁面,也全部開源至github(同時本書寫作團隊收入的20%将捐贈給開源組織,捐贈金額和去向也會通過公衆号和網站的方式對外公開)。

讀者對象

it網絡運維工程師

業務運維工程師

devops技術人員

中小型企業無運維崗但需運維伺服器的開發人員

虛拟化技術人員

對自動化理念感興趣的技術人員

如何閱讀本書

本書分為三篇,共14章,其中第1~3、6、8~10由李松濤編寫,第4、5、7、11由魏巍編寫,第8、12~14章由甘捷編寫。

第一篇為基礎入門篇(第1~5章),該篇着重介紹ansible發展史,工作原理,基礎元素組成,playbook入門。該部分内容雖簡單,卻是掌握ansible進階技巧的基石,如沒有接觸過相關自動化工具和ansible,還需認真閱讀。

第二篇為進階進階篇(第6~11章),該篇也是本書内容的最大構成部分,着重結合企業實際需求場景,以大量的實際案例拓展介紹ansible的進階文法進階和實際應用技巧,涉及的技術點有roles、inventory、jinja2、galaxy等。結合的行業主流技術包括(但不限)zabbix、except、memcache、inotify、logio、gitlab、docker、lnmp、redis、mysql、node.js等,并提供豐富的實戰案例供大家參考學習。

第三篇為web自動化開發篇(第12~14章),該篇内容主要針對不想購買tower産品,但又有web全自動化釋出界面需求的人而專門撰寫。該部分内容使用目前最流行成熟的python,并結合django前後端技術,通過ansible celery管理背景任務隊列。雖該部分内容從零基礎部分開始介紹,逐漸引導上手,但考慮時間和精力成本,建議具備一定的python、django、前端基礎後進行學習。

本書前11章,各章沒有強關聯,如覺得内容已掌握可跳躍式閱讀,遇到不了解的地方回頭再看也問題不大。從第12章開始為web化自動開發章節,需要循序漸進地學習,建議按順序閱讀。

勘誤和支援

ansible的發展非常快,當我們開始着手寫這本書的時候ansible的版本還是1.9.4,但沒過多久2.0穩定版本就更新出來,但1.9版本分支還一直在維護,随後又陸續更新了1.9.5和1.9.6的穩定版,這對我們的寫作也造成一定的困擾。當時多數公司使用的還是1.9版本的分支,2.0分支也陸續收到朋友們回報各類問題。是以本書的寫作過程總體還是基于1.9分支的基礎,1.9和2.0的差别主要在于api接口和頁面開發上,後者功能子產品更加完善豐富,但對于普通使用者整體差别不大,有差别的地方書中均會提到。

由于筆者的水準有限,編寫時間倉促,所有的寫作過程都在深夜和周末,書中難免會出現一些錯誤或者不準确的地方,懇請讀者批評指正。如果您有更多的寶貴意見,歡迎您關注我們的公衆号linux178,或加入我們的qq群:ansible中文權威-2号群(486022616),或通路我們的問答平台http://www.178linux.com/qa,我們會盡量提供最滿意的解答。期待能夠得到你們的真摯回報,在技術之路上互勉共進。

我想和作者聊聊

微信公衆号:

linux178

或掃以下二維碼

qa公共平台:

http://www.178linux.com/qa

普通使用者請加群:

ansible中文權威-2号群 486022616

書籍讀者請加群:

中文權威讀者群577479881

緻謝

感謝翻譯團隊在ansible官網文檔翻譯過程中的無私付出。

感謝魏巍、甘捷兩位“筆友”在我狂轟濫炸的“淫威”下堅持寫作,并持續輸出高品質的内容。感謝機械工業出版社華章公司的策劃編輯高婧雅,在近一年的時間中始終支援我的寫作。你們的鼓勵和幫助引導我們順利完成全部書稿。

特别緻謝

最後,我要特别感謝我的太太yolanda,為寫作這本書,我犧牲了很多陪伴她的時間,但也正因為有了她的付出與支援,我才能堅持寫下去。

同時,也要鄭重感謝馬哥教育在我寫作的過程中提供不遺餘力的資源支援,讓我們得以放開手腳無所束縛地完成寫作工作。

謹以此書獻給我最親愛的家人,以及衆多熱愛開源技術的朋友們!

李松濤(stanley)

2016年8月

contents?目  錄

本書贊譽

前言

第一篇 基礎入門篇

第1章 ansible基礎入門  2

1.1 ansible是什麼  2

1.2 ansible發展史  4

1.3 為什麼選擇ansible  5

1.4 ansible是如何工作的  6

1.5 ansible通信發展史  8

1.6 ansible應用場景  11

1.7 ansible的安裝部署  12

1.7.1 pip方式  13

1.7.2 yum方式  13

1.7.3 apt-get方式  14

1.7.4 源碼安裝方式  14

1.7.5 驗證安裝結果  15

1.8 python多環境擴充管理  16

1.8.1 pyenv的部署與使用  16

1.8.2 virtualenv的部署與使用  18

1.9 本章小結  20

第2章 ansible基礎元素介紹  21

2.1 ansible目錄結構介紹  21

2.2 ansible配置檔案解析  23

2.3 ansible指令用法詳解  25

2.4 ansible系列指令用法詳解與使用場景介紹  28

2.4.1 ansible  28

2.4.2 ansible-galaxy  29

2.4.3 ansible-pull  31

2.4.4 ansible-doc  31

2.4.5 ansible-playbook  31

2.4.6 ansible-vault  32

2.4.7 ansible-console  32

2.5 ansible inventory配置及詳解  34

2.5.1 定義主機群組  34

2.5.2 定義主機變量  35

2.5.3 定義組變量  35

2.5.4 定義組嵌套及組變量  36

2.5.5 多重變量定義  36

2.5.6 其他inventory參數清單  37

2.6 ansible與正則  37

2.7 本章小結  39

第3章 ansible ad-hoc指令集  40

3.1 ad-hoc使用場景  40

3.2 ad-hoc指令集介紹  41

3.2.1 ad-hoc指令集用法簡介  41

3.2.2 通過ad-hoc檢視系統設定  46

3.2.3 通過ad-hoc研究ansible的并發特性  47

3.2.4 通過ad-hoc研究ansible的子產品使用  49

3.3 ad-hoc組管理和特定主機變更  52

3.3.1 ad-hoc組定義  52

3.3.2 ad-hoc配置管理:配置proxy與web servers實踐  54

3.3.3 ad-hoc配置後端:配置nosql與database servers實踐  56

3.3.4 ad-hoc特定主機變更  57

3.4 ad-hoc使用者與組管理  58

3.4.1 linux使用者管理  58

3.4.2 windows使用者管理  63

3.4.3 應用層使用者管理  64

3.5 本章小結  65

第4章 playbook快速入門  66

4.1 playbook文法簡介  66

4.1.1 多行縮進  67

4.1.2 單行縮寫  67

4.2 playbook案例分析  68

4.3 playbook與shell腳本差異對比  71

4.4 ansible-playbook實戰小技巧  71

4.4.1 限定執行範圍  71

4.4.2 使用者與權限設定  72

4.4.3 ansible-playbook:其他選項技巧  73

4.5 實戰一:ansible部署node.js企業實踐  73

4.5.1 添加第三方源  73

4.5.2 運作node.js程序  77

4.5.3 node.js app服務部署總結  78

4.6 實戰二:drupal基于lamp的自動化部署  78

4.6.1 定義變量并設定handlers  79

4.6.2 部署lamp基礎服務  80

4.6.3 配置apache  81

4.6.4 配置php  82

4.6.5 配置mysql  83

4.6.6 安裝drush和composer  84

4.6.7 通過git和drush安裝drupal  85

4.6.8 drupal部署過程總結  86

4.7 實戰三:ansible部署tomcat企業實戰  86

4.7.1 定義變量并設定handlers  86

4.7.2 安裝java  87

4.7.3 安裝tomcat 8  88

4.7.4 安裝apache solr  89

4.8 本章小結  91

第5章 ansible playbook拓展  92

5.1 handlers  92

5.2 環境變量  93

5.3 變量  95

5.3.1 playbook 變量  96

5.3.2 在inventory檔案中定義變量  97

5.3.3 注冊變量  98

5.3.4 使用高階變量  98

5.3.5 主機變量群組變量  100

5.3.6 facts(收集系統資訊)  101

5.3.7 ansible加密子產品vault  104

5.3.8 變量優先級  106

5.4 if/then/when——流程控制  107

5.4.1 jinja2 正則表達、python 内置函數和邏輯判斷  107

5.4.2 變量注冊器register  108

5.4.3 when條件判斷  109

5.4.4 changed_when、failed_when條件判斷  110

5.4.5 ignore_errors條件判斷  111

5.5 任務間流程控制  111

5.5.1 任務委托  111

5.5.2 任務暫停  112

5.6 互動式提示  112

5.7 tags标簽  113

5.8 block塊  115

5.9 本章小結  116

第二篇 進階進階篇

第6章 playbook進階技巧進階  118

6.1 巧用 includes  118

6.1.1 includes使用場景  118

6.1.2 includes用法  119

6.1.3 動态 includes  123

6.1.4 handler includes使用技巧  123

6.1.5 playbooks includes使用技巧  124

6.2 巧用roles  124

6.2.1 建構roles  125

6.2.2 使用roles重構playbooks  125

6.2.3 roles技巧之handlers:動态變更  129

6.2.4 roles技巧之files:檔案傳輸  131

6.2.5 roles技巧之templates:模闆替換  133

6.2.6 更多複雜的跨平台roles  135

6.3 jinja2實作模闆高度自定義  136

6.3.1 jinja2 for循環  136

6.3.2 jinja2 if條件  137

6.3.3 jinja多值合并  138

6.3.4 jinja default()設定  140

6.3.5 ansible結合jinja2生成nginx配置  141

6.3.6 ansible結合jinja2生成apache多主機配置  146

6.3.7 jinja2動态變量配置及架構優化  148

6.4 ansible galaxy  151

6.4.1 ansible-galaxy指令用法  151

6.4.2 使用galaxy  152

6.5 本章小結  154

第7章 inventory檔案擴充  155

7.1 inventory檔案實戰  155

7.2 獨立的inventory檔案  159

7.3 inventory變量  159

7.3.1 host_vars目錄  160

7.3.2 group_vars目錄  161

7.4 動态inventory  161

7.5 本章小結  168

第8章 ansible插件擴充  169

8.1 ansible 插件使用場景  169

8.2 ansible插件類型  170

8.3 如何編寫自己的插件  171

8.4 插件案例實踐  172

8.5 本章小結  174

第9章 ansible企業應用實戰  175

9.1 為新系統添加安全認證sshkey  175

9.1.1 ansible密碼認證  175

9.1.2 ssh-copy-id  176

9.1.3 kickstart  177

9.1.4 python paramiko  178

9.1.5 expect  179

9.2 企業高可用架構的ansible應用  180

9.2.1 playbook目錄編排  181

9.2.2 高可用架構基于ansible的自動化實作  181

9.2.3 使用includes銜接各服務配置  188

9.3 elk日志系統基于ansible的自動化實作  189

9.3.1 elk server的自動化實作  190

9.3.2 elk client的自動化實作  192

9.4 實時日志系統基于ansible的自動化實作  192

9.4.1 配置概覽  192

9.4.2 架構部署  193

9.5 zabbix基于ansible的自動化實作  195

9.5.1 zabbix server基于ansible的自動化實作  196

9.5.2 zabbix agent基于ansible的自動化實作  199

9.5.3 zabbix proxy基于ansible的自動化實作  201

9.6 ansible+git+gitlab實作自動化釋出  202

9.6.1 架構概覽  203

9.6.2 架構部署  203

9.7 docker的ansible自動化應用  206

9.7.1 docker容器入門  206

9.7.2 使用ansible建立和管理容器  207

9.7.3 基于ansible建立flask的docker容器  208

9.7.4 資料存儲容器配置  210

9.7.5 flask容器配置  211

9.7.6 mysql容器配置  213

9.7.7 啟動容器  215

9.8 本章小結  215

第10章 ansible基于windows的管理架構  217

10.1 ansible管理機部署安裝  218

10.2 windows系統預配置  219

10.3 windows下可用子產品  224

10.4 windows ansible子產品使用實戰  224

10.5 本章小結  226

第11章 ansible安全優化篇  227

11.1 ssh與遠端連接配接簡介  227

11.1.1 telnet  228

11.1.2 rlogin、rsh和rcp  228

11.1.3 ssh  228

11.1.4 ssh的發展和遠端通路的未來  229

11.2 通信加密  230

11.3 禁止root遠端登入  231

11.4 作業系統簡介  232

11.5 遵守權限最小化原則  233

11.5.1 使用者管理  233

11.5.2 檔案權限管理  233

11.6 定期維護更新  234

11.6.1 手動更新  234

11.6.2 自動定時更新  234

11.7 善用iptables防火牆  236

11.8 定期磁盤巡檢  238

11.9 系統登入日志審記  238

11.10 正确使用selinux和apparmor  239

11.11 本章小結  240

第三篇 web自動化開發篇

第12章 ansible子產品編寫  242

12.1 初步認識ansible子產品  242

12.2 ansible簡單子產品編寫  243

12.3 子產品變量添加  245

12.4 子產品狀态傳回的辨別及應用  246

12.5 子產品退出狀态處理  249

12.6 子產品其他功能補充  250

12.7 ansible子產品api的調用  251

12.8 本章小結  265

第13章 開發自己的ansible webui  267

13.1 搭建django開發環境  267

13.1.1 為什麼要使用web頁面做管理  267

13.1.2 系統及軟體環境  268

13.2 django配置檔案詳解  269

13.2.1 django的基礎配置及運作  269

13.2.2 django的主配置目錄介紹  270

13.2.3 django的app目錄介紹  271

13.3 編寫ansible的web接口  272

13.4 前端基礎知識介紹  278

13.4.1 html和css簡介  278

13.4.2 javascript簡介  279

13.5 ansible webui界面開發  280

13.5.1 對接前端頁面與ansible的web接口  280

13.5.2 配置web頁面傳參  282

13.6 本章小結  285

第14章 web與ansible結合的常用執行個體  286

14.1 web方式管理ansible的inventory  286

14.1.1 重新定制ansible的hosts檔案規則  286

14.1.2 使用configparser解析并生成ansible hosts檔案  287

14.1.3 使用資料庫的存儲資料生成的ansible hosts檔案  290

14.1.4 通過頁面來生成hosts檔案  293

14.2 使用celery背景執行任務  301

14.2.1 為什麼要使用celery  301

14.2.2 使用celery的前期準備  301

14.2.3 使用celery開始任務  303

14.2.4 使用celery取消正在進行的任務  305

14.3 運作yml檔案并實時讀取日志  306

14.4 通過頁面上傳檔案并基于ansible分發  313

14.5 在頁面上建構yml檔案注冊中心  316

14.6 操作者注冊中心界面  324

14.7 本章小結  331

第一篇 part 1

基礎入門篇

第1章 ansible基礎入門

第2章 ansible基礎元素介紹

第3章 ansible ad-hoc指令集

第4章 playbook快速入門

第5章 ansible playbook拓展

第1章

ansible基礎入門

“未來主體是傳統行業利用網際網路技術,以雲端用人工智能的方式處理大資料”,在騰訊“雲+未來”技術峰會上,馬化騰這樣形容未來。15年前,電腦還隻是少數人的專屬,那時的網吧還很火,還沒人知道“網咖”是什麼。而現在人手一部智能手機,物聯網更是讓日常生活中的普通家電也能在網際網路占據一席之地。這一切都推動着網際網路如火如荼發展,it技術的發展更是日新月異,it工種的分類日益精細專業化。

從早期all in one(所有應用部署在一台伺服器上)的簡單應用,到後期叢集、高可用、緩存、消息隊列、配置中心、主從分離、負載均衡、大資料存儲等尖端技術的複雜應用,對運維的技術專業度和綜合技能要求越來越高,運維的傳遞标準不再以周或天為機關,而是以分鐘為機關。在現在是如此,在未來更是如此。運維不再如早期一樣,手動一台台地登入伺服器、部署應用配置環境、手動傳遞(諸如亞馬遜、google等巨型企業早已實作自動擴縮容,配置應用自動化,流程自動傳遞等功能)。該方式耗時耗力,很難避免人為因素的錯誤,最主要的是這些重複手工勞動無法讓運維有更大的價值釋放,這一切都是不合理的,需要有更好的解決方式。

相信看到這裡,大家都明白,我們需要一套自動化管理工具來幫助運維更高品質、更有效地完成手頭工作,以證明運維能創造的價值不止于此,況且生活不止眼前的苟且,還有詩和遠方,不是嗎?但當下saltstack、puppet、fabric、chef等自動化工具遍地開花,為什麼還要推薦ansible呢?讀完本章你會有些許想法,未來已來,隻是尚未流行。

1.1 ansible是什麼

随着移動互聯、物聯網、網際網路+、大資料、雲計算等大規模應用的催生推動,以及人們日常生活的網際網路化,網際網路的蓬勃發展不僅沖擊影響着整個經濟體,更對人們的生活理念影響深遠。在體驗到網際網路帶來的便利和舒适的同時,人們也不再滿足于“可以用”,而是要“用得爽”,在政策、需求、利益、趨勢等原因的刺激下,網際網路的發展速度可想而知。衆所周知,智能的背後意味着複雜,這一現象在網際網路的發展中展現得淋漓盡緻。在網際網路迅猛發展的同時,運維這個工種也從默默無聞的背景逐漸走向公衆視野,被更多的人所知曉。早期公司業務有數十台、上百台伺服器已經是非常龐大的規模,每個運維同時操作10~20台機器,忙碌地奔波于各電腦之間配置重新開機服務,數十人摩肩接踵的場面是何等壯觀。隻是每個人都在數十台機器上做同樣的修改、配置、操作,如何保證每台機器的操作都完全一樣呢?又如何保證其他所有人的操作都能準确無誤、沒有遺漏過失呢?更何況,随着網際網路的迅猛發展,一個公司擁有幾十台上百台機器早已不是稀奇事,巨型公司數以萬計的機器都不在話下,再沿用老一套辦法一台台地人工修改配置已然不現實,這該怎麼辦呢?相信此時你已然明白運維自動化具體是什麼了。簡單來講,運維自動化就是将日常重複性的工作通過規則設定使其遵循預先既定規則,在指定的範圍時間内自動化運作,但整個過程無需人工參與。而ansible正是幫助運維人員實作自動化的工具之一。

ansible是近年越來越火的一款運維自動化工具,其主要功能是幫忙運維實作it工作的自動化、降低人為操作失誤、提高業務自動化率、提升運維工作效率,常用于軟體部署自動化、配置自動化、管理自動化、系統化系統任務、持續內建、零當機平滑更新等。它豐富的内置子產品(如acl、command、shell、cron、yum、copy、file、user等,多達569個)和開放的api接口,同時任何遵循gpl協定的企業或個人都可以随意修改和釋出自己的版本。

ansible在其官網上定義如下:ansible is a radically simple it automation engine。即ansible是一款極其簡單的it自動化工具。這裡特别使用了radically simple來形容ansible的簡單程度,在0.x版本的ansible官網中,更“過分”地使用stupid simple來形容ansible是“令人發指的簡單”。在ansible官網的通篇文檔中也不時使用incredibly simples、keep it simple、power+simplicity等字眼,可見ansible這款自動化工具的設計非常注重simple的理念。但ansible的功能卻非常不簡單,完全沒有因為使用方式上的簡單而縮水,其自身内置子產品的數量達500多個,而且還在快速地增加新子產品,以下是這些子產品的覆寫面的大緻分類。

系統層:支援的系統有linux、windows、aix等,對應的子產品有acl、cron、pip、easy_install、yum、authorized_key等大量的内置子產品;

知名第三方平台支援:支援的雲平台有aws、azure、cloudf?lare、openstack、google、linode、digital ocean等,對應的子產品有ec2、azure_rm_deployment、cloudflare_dns、clc_aa_policy、glance_image、gc_storage、digital_ocean等;

虛拟化:vmware、docker、cloudstack、lxc、openstack等,對應的子產品有vmware_vmkernel、docker、cs_account、lxc_container、glance_image等;

商業化硬體:f5、asa、citrix、eos等,對應的子產品有bigip_facts、asa_acl、netscaler、eos_command等;

系統應用層:apache、zabbix、rabbitmq、svn、git等,對應的子產品有apache2_module、zabbix_group、rabbitmq_binding、subversion、git等。

github上有衆多開源愛好者為ansible貢獻功能子產品,這些子產品完全可以滿足日常工作所需。官方對子產品也從使用者角度進行詳細分類,如cloud modules(雲主機子產品)、clustering modules(叢集子產品)、commands modules(指令子產品)、database modules(資料庫子產品)等。詳細的子產品分類可參考官方子產品清單:http://docs.ansible.com/ansible/modules_by_category.html,該網址内容的更新速度非常快,如果公司在使用ansible,建議最少兩周關注一次。

ansible名字其實是來源于其作者喜歡的一本書——奧森·斯科特·卡特的《安德的遊戲》,該書中ansible是一種能跨越時空的即時通信工具,使用ansible可以在相距數光年的距離遠端實時控制前線的艦隊戰鬥。michael dehaan希望借這個名詞比喻控制遠端大量的伺服器,是以便将自己的這款産品命名為ansible。

web界面是一款功能完善的管理工具的必備功能,tower是ansible的web化管理界面,但免費版的容量隻有10台主機,付費版則無容量限制。基于此原因,本書的第12~14章會介紹搭建屬于自己的web化管理界面的方法,并代碼全開源,具體位址大家可從github上下載下傳,同時讀者遇到的問題都可以通過qq群“ansible中文權威”咨詢,或在微信公衆号“運維部落”留言。

更多資訊請參考:

ansible官方位址:https://docs.ansible.com/;

github位址:https://github.com/ansible/ansible/blob/devel/docsite/rst/index.rst;

ansible中文權威位址:http://www.ansible.com.cn/。

1.2 ansible發展史

ansible的第一個版本是0.0.1,釋出于2012年3月9日,其作者兼創始人是michael dehaan。michael dehaan曾經供職于puppet labs、redhat、michael,在配置管理和架構設計方面有豐富的經驗。其在redhat任職期間主要開發了cobble,經曆了各種系統簡化、自動化基礎架構操作的失敗和痛苦,在嘗試了puppet、chef、cfengine、capistrano、fabric、function、plain ssh等各式工具後,決定自己打造一款能結合衆多工具優點的自動化工具,ansible由此誕生。

其第一個版本号被非常謹慎地定義為0.01。到目前為止共釋出107個版本,最新穩定版是stable 2.1.1.0-1,最新beat版beat 2.1.1.0-0.1.rc1。值得一提的是,作為自動化工具新秀,ansibe已被redhat官方收購,在github上被關注的勢頭也極為迅猛,star和fork數是當下紅極一時的saltstack的2倍多。同類自動化工具github關注程度如表1-1所示。從表可以看出ansible的受歡迎度。被redhat收購後,其未來發展潛力更是不可估量。

表1-1 同類自動化工具github關注程度(2016-07-10)

同類自動化工具 watch(關注) star(點贊) fork(複制) contributors(貢獻者)

ansible 1387 1?7716 5356 1428

saltstack 530 6678 3002 1520

puppet 463 4044 1678 425

chef 383 4333 1806 464

fabric 379 7334 1235 116

ansible版本更新速度非常快,有時會一天推出多個dev版本,7天推出一個穩定版本。是以使用ansible的過程中也需多留意官網的更新。

1.3 為什麼選擇ansible

ansible自2012年釋出以來,沒多久便在美國開始流行。快速被it人員接受的原因較大方面得益于michael dehaan在美國it圈的名氣和影響力。随後它逐漸在各國流行。而筆者選擇ansible的原因主要有如下幾個方面:

ansible完全基于python開發,而devops在國内已然是一種趨勢,python被逐漸普及,運維人員自己開發工具的門檻逐漸降低,得益于此,友善對ansible二次開發;

ansible豐富的内置子產品,甚至還有專門為商業平台開發的功能子產品,近600個子產品完全可以滿足日常功能所需;

在ansible去中心化概念下,一個簡單的複制操作即可完成管理配置中心的遷移;

agentless(無用戶端),用戶端無需任何配置,由管理端配置好後即可使用,這點非常誘人。在第10章會介紹如何部署配置windows系統的主機端,用後會有深切的感受。

自ansible釋出後,也陸續被aws、google cloudplatform、microsoft azure、cisco、hp、vmware、twitter等大公司接納并投入使用。關于筆者個人與ansible的一些故事,有興趣的朋友可以參考本書前言。

1.4 ansible是如何工作的

ansible沒有用戶端,是以底層通信依賴于系統軟體,linux系統下基于openssh通信,windows系統下基于powershell,管理端必須是linux系統,使用者認證通過後在管理節點通過ansible工具調用各應用子產品将指令推送至被管理端執行,并在執行完畢後自動删除産生的臨時檔案。ansible具體的工作機制官方有專欄介紹https://www.ansible.com/how-ansible-works,但整體稍過簡略。我們參考從官網視訊中的截圖來詳細了解下其工作方式,如圖1-1所示。根據ansible使用過程中的不同角色,我們将其分為:

使用者

ansible工具集

作用對象

(1)使用者

如圖1-1中ansible工作機制所示,ansible使用者來源于多種次元,圖中為我們展示了4種方式:

第一種方式:cmdb(conf?iguration management database,配置管理資料庫),cmdb存儲和管理着企業it架構中的各項配置資訊,是建構itil項目的核心工具,運維人員可以組合cmdb和ansible,通過cmdb直接下發指令調用ansible工具集完成操作者所希望達成的目标;

第二種方式:public/private方式,ansible除了豐富的内置子產品外,同時提供豐富的api語言接口,如php、python、perl等多種當下流行語言,基于public(公有雲)/private(私有雲),ansible以api調用的方式運作;

第三種方式:users直接使用ad-hoc臨時指令集調用ansible工具集來完成任務執行,ad-hoc将在第3章有詳細介紹;

第四種方式:users預先編寫好的ansible playbooks,通過執行playbooks中預先編排好的任務集按序完成任務執行。

(2)ansible工具集

ansible指令是ansible的核心工具,ansible指令并非自身完成所有的功能集,其隻是ansible執行任務的調用入口,大家可心了解為“總指揮”,所有指令的執行通過其“調兵遣将”最終完成。ansible指令共有哪些兵将可供使喚呢?大家看中間綠色框中有inventory(指令執行的目标對象配置檔案)、api(供第三方程式調用的應用程式程式設計接口)、modules(豐富的内置子產品)、plugins(内置和可自定義的插件)這些可供調遣。

(3)作用對象

ansible的作用對象,不僅僅是linux和非linux作業系統的主機(hosts),同樣也可以作用于各類公有雲/私有雲,商業和非商業裝置的網絡設施。

圖1-1 ansible工作機制

同樣,如果我們按ansible工具集的組成來講,由圖1-1可以看出ansible主要由6部分組成。

ansible playbooks:任務劇本(任務集),編排定義ansible任務集的配置檔案,由ansible順序依次執行,通常是json格式的yml檔案;

inventory:ansible管理主機的清單;

modules:ansible執行指令的功能子產品,多數為内置的核心子產品,也可自定義;

plugins:子產品功能的補充,如連接配接類型插件、循環插件、變量插件、過濾插件等,該功能不常用。

api:供第三方程式調用的應用程式程式設計接口;

ansible:該部分圖中表示的不明顯,組合inventory、api、modules、plugins的綠框大家可以了解為是ansible指令工具,其為核心執行工具;

ansible執行任務,這些元件互相調用關系如圖1-2所示:

圖1-2 ansible元件調用關系

使用者使用ansible或ansible-playbook(會額外讀取playbook檔案)時,在伺服器終端輸入ansible的ad-hoc指令集或playbook後,ansible會遵循預先編排的規則将playbooks逐條拆解為play,再将play組織成ansible可識别的任務(task),随後調用任務涉及的所有子產品(module)和插件(plugin),根據inventory中定義的主機清單通過ssh(linux預設)将任務集以臨時檔案或指令的形式傳輸到遠端用戶端執行并傳回執行結果,如果是臨時檔案則執行完畢後自動删除。

1.5 ansible通信發展史

ansible主推的賣點是其無需任何daemon維護程序即可實作互相間的通信,且通信方式是基于業内統一标準的安全可靠的ssh安全連接配接。同時因為ssh是每台linux主機系統必裝的軟體,是以ansible無需在遠端主機端安裝任何額外程序,即可實作agentless(無用戶端),進而助力其實作去中心化的思想。盡管穩定、快速、安全的ssh連接配接是ansible通信能力的核心,但ssh的連接配接效率一直被诟病,是以ansible的通信方式和效率在過去的數年中也在不停地改變和提高。基于以上認識,我們先來了解ansible ssh的工作機制,再來回顧其發展史。

1.?ansible ssh工作機制

ansible執行指令時,通過其底層傳輸連接配接子產品,将一個或數個檔案,或者定義一個play或command指令傳輸到遠端伺服器/tmp目錄的臨時檔案,并在遠端執行這些play/comand指令,然後删除這些臨時檔案,同時回傳整體指令執行結果。這一系列操作在未來的ansible版本中會越來越簡單、直接,同時快速、穩定、安全。通過了解其工作機制及其一直以來秉承的去中心化思想,我們可以總結,ansible是非c/s架構,自身沒有client端,其主要特點如下。

無用戶端,隻需安裝ssh、python即可,其中python建議版本為2.6.6以上。

基于openssh通信,底層基于ssh協定(windows基于powershell)。

支援密碼和ssh認證,因可通過系統賬戶密碼認證或公私鑰認證,是以整個過程簡單、友善、安全。建議使用公私鑰方式認證,因為密碼認證方式的密碼需明文寫配置檔案,雖然配置檔案可加密,但會增加ansible使用的複雜度。

支援windows,但僅支援用戶端,服務端必須是linux系統。

如ansible官方介紹,如上特性是希望實作以下最終目标:

clear(簡易):yaml文法,python語言編寫,易于管理,api簡單明了;

fast(靈活):快速學習,設定簡單,無需任何第三方軟體;

complete(全面):配置管理、應用部署、任務編排等功能集于一身,豐富的内置子產品滿足日常功能所需;

eff?icient(高效):沒有額外軟體包消耗系統性能;

secure(安全):沒有用戶端,底層基于openssh,保證通信的安全可靠性。

2.?ansible通信方式發展曆程

ansible底層基于安全可靠的ssh協定通信,但一直被人們诟病于其效率,通信功能作為ansible最核心的功能之一,官方也一直在做改進。本節我們來了解ansible通信發展史。

(1)paramiko通信子產品

最初,ansible隻使用paramiko實作底層通信功能,但是paramiko隻是python文法的一個第三方庫,發展速度遠不及openssh。同時,paramiko的性能和安全性較openssh稍遜一籌(在筆者眼裡)。

在後續釋出的新版本中,ansible仍繼續相容paramiko,甚至在諸如rhel 5/6等不支援controlpersist(隻在openssh 5.6+版本中支援)的系統中封裝其為預設通信子產品。

(2)openssh

從ansible 1.3版本開始,ansible預設使用openssh連接配接實作各伺服器間通信,以支援controlpersist(持續管理)。ansible從0.5版本起即支援openssh功能,但直到1.3版本開始才将其設定為預設。

多數本地ssh配置參數,諸如hosts、公私鑰檔案等是預設支援的,但如果希望通過非預設的22端口運作指令等操作,則需要在inventory檔案中配置ansible_ssh_port的值。openssh相比paramiko更快、更可靠。

(3)加速模式

據官網介紹:開啟加速模式後ansible通信速度有質的提升,是開啟controlpersist後的ssh的2~6倍,是paramiko通信速度的10倍。

盡管加速模式對ad-hoc指令不友好,但是playbook通過加速模式會收到更高的性能。加速模式抛棄ssh多次連接配接的方式,通過ssh初始化後,帶着aes key的初始化連接配接資訊通過特定的端口(預設5099,但可配置)執行指令傳輸檔案。使用加速模式唯一需要的額外包是python-keyczar,如此一來,幾乎所有的正常子產品openssh/paramiko均工作在加速模式,但如下使用sudo的情況例外:

1)sudoers檔案需要關閉其中的requiretty功能,注釋掉或者設定每個使用者的預設值為username !requiretty。sudoers的man文檔說明如下。

requiretty

if set, sudo will only run when the user is logged in to a real tty.  when this flag is set, sudo can only be run from a login session and not via other means such as cron(8) or cgi-bin scripts.  this flag is off by default.

2)開啟加速子產品必須事先設定sudo檔案nopasswd配置,禁用sudo後的password互動認證過程。加速模式相對openssh可以提供2~4倍的性能提升(尤其對于檔案傳輸功能),在playbook的應用中可以通過增加配置開關來實作。

---

- hosts: all

accelerate: true

accelerate_port: 5099

[...]

其中的端口也可以在ansible.cfg中單獨配置。

[accelerate]

accelerate_port = 5099

加速模式是現在已經被廢棄的fireball模式的進化版,類似于ansible加速通信方式,但需控制機事先安裝zeromq服務(這與ansible簡單、無依賴、無daemon的理念是相違背的),并且一點也不支援sudo操作。

(4)faster openssh in ansible 1.5+

ansible 1.5+版本中的openssh有了非常大的改進,舊版本中實作方式是複制檔案至遠端伺服器後運作,然後删除這些臨時檔案,而新版本的替代方案是通過openssh發送執行指令,将所有操作附帶在ssh連接配接過程中同步實作。該方式隻在ansible 1.5+版本有效,且需在/etc/ansible/ansible.cfg的[ssh_connection]區域開啟pipelining=true功能。

關于加速模式我們還需要關注如下内容:

pipelining=true需結合sudo的requiretty配置方可生效,請確定/etc/sudoers的defaults requiretty為注釋狀态。絕大多數現有流行系統預設開啟該選項。

在mac osx、ubuntu、windows的cygwin或其他流行os最好選擇5.6以上的openssh版本,這些版本對controlpersist有更友好的支援。

如ansible運作的主機系統是rhel或centos,然而希望更新目前openssh到最新版本以支援faster/persistent連接配接模式,可以通過yum update openssh更新最新版本。

本節内容可以通過如圖1-1所示的ansible通信方式發展史魚骨圖來概括,從最開始的paramiko,後來初步演變為openssh,加速模式官方推薦pipelining方式。

圖1-3 ansible通信方式發展史

在了解ansible通信原理及發展史後,我們進一步學習ansible自身的發展史。要知道,在chef、puppet、saltstack、fabric等自動化工具群雄争霸的市場背景下,ansible依然能夠殺出重圍,在github取得如此驚人成就,并且被紅帽官方收購,其發展史不得不讓人刮目相看。

1.6 ansible應用場景

ansible底層基于python,以簡單著稱,配置檔案格式也以ini和yaml為主,與其他管理工具相比,學習成本較低,學習曲線也很平滑,無論是基礎運維人員還是資深運維工程師都可以較快上手,稍加練習便可以熟練掌握。如果具備dev基礎,熟悉python、php等主流語言,基于ansible開放api接口做二次開發,可以靈活有效地發揮其價值。ansible自身也包括非常豐富的内置子產品,從windows系統到開源linux系統,從檔案同步到指令執行,從軟體的安全更新到配置的維護變更,從商業硬體a10、f5到公(私)有雲aws、digital、vmware、docker等,幾乎囊括了運維日常所有的技術應用。系統下所有的操作可從運維操作角度劃分為兩類。

檔案傳輸:檔案的本地傳輸和異地傳輸,所有檔案的空間形态、時間形态變化均構成檔案傳輸類操作。

指令執行:終端所有操作對系統來講都是指令的組成,最終轉換為基礎硬體可接受的電信号完成任務集。對運維操作的使用者行為來講,除檔案傳輸以外的其他操作均可稱為指令執行。

從自動化工作類型角度歸類如下。

(1)應用部署

現今的應用功能越來越強大,同步應用部署過程的依賴和規則也日趨複雜,但對應用運維的要求沒有随之降低,有效快速正确平滑的應用部署需求日趨強烈。ansible内置網絡、應用、系統、第三方雲平台擴充等完善的功能子產品,協助運維快速完成應用的安裝、解除安裝、更新、啟停、配置等部署類工作,即使對跨平台或知名的商業硬體也同樣支援。

(2)配置管理

配置管理(conf?iguration management,cm)是通過技術或行政手段對軟體産品及其開發過程和生命周期進行控制、規範的一系列措施。配置管理的目标是記錄軟體産品的演化過程,確定軟體開發者在軟體生命周期中各個階段都能得到精确的産品配置。在日益複雜的it環境和使用者需求下,ansible内置file、template,結合jinja、lineinf?ile等内置子產品,同時無縫結合github、gitlab、git、svn、jenkins等主流版本控制和ci持續內建工具,助力配置管理自動化。

(3)任務流編排

有效保證tasks任務流按既定規則和順序完成事先制訂的目标和計劃,同時roles編排方式又能在一定程度上從書寫習慣和代碼層編排上保證整體項目的可架構性和規範性,協助控制項目維護成本不緻過高。

如上場景适用于網絡管理者、系統運維、應用運維、桌面運維、devops、基礎架構運維等多領域運維行業,以及無運維崗但服務規模又需有一定精力投入維護的小型公司,開發人員經過簡單的了解即可初步上手。同樣也适用于中大型公司,可以投入人力、精力、财力對ansible進行二次開發,使其更加适用。

1.7 ansible的安裝部署

了解完ansible是什麼、通信原理及發展史、ansible發展曆程及其應用場景後,接下來為大家介紹ansible的安裝部署。

ansible的安裝部署非常簡單,其僅依賴于python和ssh,而系統預設均已安裝。除windows外,redhat、debian、centos、osx均可作為管理節點部署ansible。ansible被redhat紅帽官方收購後,其安裝源被收錄在epel中,如已安裝epel可直接yum或apt安裝,通過pip和easy_install的python第三方包管理器也可以便捷安裝ansible,下面我們詳細介紹部署方式。

1.7.1 pip方式

ansible底層也是基于python編寫,是以可以通過pip方式安裝ansible。

步驟1:安裝python-pip及python-devel程式包。

// 安裝python-pip程式包及python-devel,

yum install python-pip python-devel –y

傳回類似如下結果則表示安裝成功:

    installing : python-devel-2.7.5-34.el7.x86_641/2

    installing : python-pip-7.1.0-1.el7.noarch2/2

    verifying  : python-pip-7.1.0-1.el7.noarch1/2

    verifying  : python-devel-2.7.5-34.el7.x86_642/2

installed:

    python-devel.x86_64 0:2.7.5-34.el7        python-pip.noarch 0:7.1.0-1.el7

complete!

步驟2:安裝ansible服務。

// 安裝請前確定伺服器的gcc、glibc開發環境均已安裝,系統幾乎所有的軟體包編譯環境均基于gcc,如不确認可先執行如下指令:

yum install gcc glibc-devel zlib-devel  rpm-build openssl-devel –y

// 更新本地pip至最新版本

pip install --upgrade pip

// 安裝ansible服務

pip install ansible –upgrade

執行指令ansible --version,有類似如下傳回結果則表示ansible安裝成功并可正常使用。

ansible 2.1.1.0

    config file = /etc/ansible/ansible.cfg

    configured module search path = default w/o overrides

如下其他驗證安裝是否成功的方式也一樣,均可執行ansible––version驗證,後面不一一列出。

1.7.2 yum方式

yum(yellow dog updater,modif?ied)是一個在fedora和redhat以及centos中的shell前端軟體包管理器。基于rpm包管理,能夠從指定的伺服器自動下載下傳rpm包并且安裝,可以自動處理依賴性關系,并且一次安裝所有依賴的軟體包,無需煩瑣地一次次下載下傳、安裝。yum安裝ansible過程如下:

// 需事先安裝epel源後方可找到并安裝ansible

rpm -uvh https:// dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm

// 安裝ansible

yum install ansible –y

安裝速度視網絡情況而定,因為安裝過程會安裝非常多的依賴包,又因各系統環境的差異性,如傳回類似如下結果則表示安裝成功:

    ansible.noarch 0:2.1.1.0-1.el7

dependency installed:

    pyyaml.x86_64 0:3.10-11.el7          libtomcrypt.x86_64 0:1.17-23.el7

    libtommath.x86_64 0:0.42.0-4.el7     python-babel.noarch 0:0.9.6-8.el7

    python-httplib2.noarch 0:0.7.7-3.el7 python-jinja2.noarch 0:2.7.2-2.el7

    python-keyczar.noarch 0:0.71c-2.el7  python-markupsafe.x86_64 0:0.11-10.el7

    python-pyasn1.noarch 0:0.1.6-2.el7   python2-crypto.x86_64 0:2.6.1-9.el7

    python2-ecdsa.noarch 0:0.13-4.el7    python2-paramiko.noarch 0:1.16.1-1.el7

    sshpass.x86_64 0:1.05-5.el7

1.7.3 apt-get方式

apt-get全稱是advanced package tool,是一款适用于unix和linux系統的應用程式管理器,适用于ubuntu、debian等deb包管理式的作業系統,主要用于自動地從網際網路的軟體倉庫中搜尋、安裝、更新、解除安裝軟體或作業系統。

// 添加ansible源

apt-add-repository -y ppa:ansible/ansible

// 更新庫檔案

apt-get update

apt-get install -y ansible

1.7.4 源碼安裝方式

源碼安裝本身就是一道很高的門檻,作為剛接觸linux的新手不建議使用該方式。

在什麼情況下我們需要從源代碼安裝軟體呢?其實源碼安裝是相對于二進制安裝而言的,所謂的二進制安裝即前言講到的,pip、yum、apt-get都是二進制的安裝方式,一般當新軟體推出了新的版本,而所用的發行版并沒有及時跟進,這時候,想要“嘗鮮”的話,就非得靠自己而不可使用源碼編譯安裝;另一種情形是,不管是軟體的開發者還是現用的系統都沒有提供可直接使用的二進制包,而自己又非要使用該軟體,那麼也需源碼安裝才行。當然,還有其他的情形。總而言之,學會源碼安裝軟體方式是一項非常重要的技能,但又因其編譯環境準備起來複雜不堪,同時安裝過程又需人工逐一解決安裝過程中可能遇到的各項應用層依賴和系統庫依賴,是以門檻較高,故不建議初學者使用該方式。

// 不建議安裝beta版

// 安裝git用戶端

yum install git –y

整個安裝過程無報錯,有類似如下傳回結果則表示安裝成功。

    git.x86_64 0:1.8.3.1-5.el7

    libgnome-keyring.x86_64 0:3.8.0-3.el7 perl-error.noarch 1:0.17020-2.el7

    perl-git.noarch 0:1.8.3.1-5.el7       perl-termreadkey.x86_64 0:2.30-20.el7

安裝ansible軟體包。

// 使用git将拉取指定的ansible版本至本地目前目錄

git clone git:// github.com/ansible/ansible.git –recursive

// 切換至程式包目錄

cd ./ansible

// 執行env-setup腳本,安裝ansible軟體包

source ./hacking/env-setup

1.7.5 驗證安裝結果

如上列舉了網際網路主流系統的ansible安裝方式,如整個過程均無報錯,則執行如下指令應有類似結果傳回:

ansible --version

ansible 1.9.6

如上述指令能正常執行,表示ansible安裝成功,并可正常使用。通常情況下,ansible的安裝簡單順利,但确實會有安裝報錯的情況發生,多數情況是由本地複雜的系統環境導緻的。下面我們為大家介紹python多環境管理,來解決該類問題。

1.8 python多環境擴充管理

衆所周知,python發展至今,版本衆多,部分版本功能差異較大,在使用過程中經常遇到第三方庫依賴的python版本和系統python版本不一緻的情況。同時又因系統底層需調用目前版本python,是以不能随意變更目前系統python版本。如此情景下就會有python多版本共存的情況。于是,python多環境管理工具應運而生。這裡為大家介紹兩款工具,分别是pyenv和virtualenv。pyenv和virtualenv均為python管理工具,不同的是,前者是對python的版本進行管理,實作不同版本間的切換和使用;而後者則通過建立虛拟環境,實作與系統環境以及其他python環境的隔離,避免互相幹擾。

1.8.1 pyenv的部署與使用

pyenv是一個簡單的python版本管理工具,以前叫作pythonbrew。它讓你能夠友善地切換全局python版本,安裝多個不同的python版本,設定獨立的某個檔案夾或者工程目錄特異的python版本,同時建立python虛拟環境(virualenv's)。所有這些操作均可以在類unix系統的機器上(linux和os x)不需要依賴python本身執行,而且它工作在使用者層,不需要任何sudo操作。

(1)部署

pyenv作為python的版本管理工具,通過改變shell的環境變量來切換不同的python版本,以達到多版本共存的目的。該工具不支援windows系統。具體工作原理如下。

1)pyenv安裝後會在系統path中插入shims路徑,每次執行python相關的可執行檔案時,會優先在shims裡尋找python路徑~/.pyenv/shims:/usr/local/bin:/usr/bin:/bin;

2)系統選擇python版本,依如下順序選擇python的版本:

shell變量設定(執行pyenv shell檢視)

目前可執行檔案目錄下的.python_version檔案裡的版本号(執行pyenv shell檢視)

上層目錄查詢找到的第一個.pyenv-version檔案

全局的版本号在~/.pyenv/version檔案内(執行pyenv global檢視)

3)确定版本檔案的位置和python版本後,pyenv會根據版本号在~/.pyenv/versions/檔案夾中查找對應的python版本。執行指令pyenv versions可檢視系統目前安裝的python版本。

接下來開始部署pyenv,具體部署方式如下:

// clone pyenv至家目錄

git clone git:// github.com/yyuu/pyenv.git ~/.pyenv

// 修改環境變量

echo 'export pyenv_root="$home/.pyenv"' >> ~/.bashrc

echo 'export path="$pyenv_root/bin:$path"' >> ~/.bashrc

echo 'eval "$(pyenv init -)"' >> ~/.bashrc

// 重新開機目前 shell

exec $shell –l

執行pyenv versions指令,有類似如下傳回結果表示安裝正常:

* system (set by /home/o2o/.pyenv/version)

    2.7.8

接下來我們來了解pyenv的使用方式。

(2)通過pyenv管理多python版本

pyenv指令使用規則如下:

usage: pyenv <command> [<args>]

我們通過pyenv安裝python 3.4.1版本來熟悉其用法。

// 檢視可安裝的版本清單

pyenv install –list

// 安裝指定的python版本

pyenv install 3.4.1

// 切換目前目錄python版本為3.4.1

pyenv local  3.4.1

// 切換全局目錄python版本為3.4.1

pyenv global  3.4.1

// 重新整理shims

pyenv rehash

pyenv更多用法如下:

commands 列出pyenv的所有可用指令

local 設定或列出目前環境下python版本号

global 設定或列出全局環境下python版本号

shell 設定或列出shell環境下python版本

install 安裝指定的python版本

uninstall 解除安裝指定的python版本

rehash 重新加載pyenv的shims路徑(安裝完python版本後需執行該指令)

version 展示目前python版本号及其生效的路徑

versions 列出pyenv管控的所有可用python版本

which 列出要使用指令的絕對路徑

whence 列出字尾指令的所有可用版本

至此,pyenv介紹完畢,接下來再介紹一款python多管理工具virtualenv,它不是通過多版本管理的方式來實作系統同時相容多python環境。virtualenv是底層基于python開發的python環境隔離工具,其通過虛拟目錄的方式來實作多環境的并存。其工作原理很簡單:在你所需的地方建立工作目錄,該目錄類似系統安裝的python目錄,保留完整的python環境、解釋器、标準庫和第三方庫等,當我們需要時,切換環境變量激活即可使用。接下來我們進一步學習virtualenv的安裝部署及版本管理。

1.8.2 virtualenv的部署與使用

python的第三方包成千上萬,在一個python環境下開發時間越久、安裝依賴越多,就越容易出現依賴包沖突的問題。為了解決這個問題,開發者們開發出了virtualenv,它可以搭建虛拟且獨立的python環境。這樣就可以使每個項目環境與其他項目獨立開來,保持環境的幹淨,避免包沖突問題。另外,在開發python應用程式的時候,所有第三方的包都會被pip安裝到系統python版本的site-packages目錄下。但如果我們要同時開發多個應用程式,那這些應用程式會共用一個python,這意味着所有的包都安裝在系統的python目錄下,這不僅影響我們的正常開發工作,還有可能因為随意變更系統python版本資訊而造成系統的不穩定。這種情況下,每個應用可能需要各自擁有一套“獨立”的python運作環境。virtualenv就是用來為一個應用建立一套“隔離”的python運作環境的。下面我們來看看virtualevn的部署,以及它如何管理python環境。

假設你已經學習過我們上節内容并安裝好pip了,那麼virtualenv的安裝非常簡單,操作如下:

// 安裝virtualenv

pip install virtualenv

傳回如下結果表示安裝成功:

installing collected packages: virtualenv

successfully installed virtualenv-15.0.3

(2)通過virtualenv管理多python版本

需強調說明的是:virtualenv不是通過多版本管理的方式來實作系統同時相容多python環境的,而是其通過在工作目錄中虛拟完整的python環境來實作python多環境并存。接下來我們看virtualenv的使用方式。

virtualenv指令的使用格式如下:

virtualenv [options] dest_dir

中括号options表示參數選項,是可選項,即可有可無;dest_dir表示指令要執行的目錄,如:

// 建立/data/magedu/的虛拟目錄

virtualenv /data/magedu/

可用的options選項如下:

--version  顯示目前版本号。

-h, --help  顯示幫助資訊。

-v, --verbose  顯示詳細資訊。

-q, --quiet  不顯示詳細資訊。

-p python_exe, --python=python_exe  指定所用的python解析器的版本,比如--python=python2.5 就使用2.5版本的解析器建立新的隔離環境。預設使用的是目前系統安裝(/usr/bin/python)的python解析器。

--clear  清空非root使用者的安裝,并從頭開始建立隔離環境。

--no-site-packages  令隔離環境不能通路系統全局的site-packages目錄。

--system-site-packages  令隔離環境可以通路系統全局的site-packages目錄。

--unzip-setuptools  安裝時解壓setuptools或distribute。

--relocatable  重定位某個已存在的隔離環境。使用該選項将修正腳本,并令所有.pth檔案使用相應路徑。

--distribute  使用distribute代替setuptools,也可設定環境變量virtualenv_distribute達到同樣效果。

--extra-search-dir=search_dirs  用于查找setuptools/distribute/pip釋出包的目錄。可以添加任意數量的–extra-search-dir路徑。

--never-download  禁止從網上下載下傳任何資料。此時,如果在本地搜尋釋出包失敗,virtualenv就會報錯。

--prompt==prompt  定義隔離環境的指令行字首。

下面詳細看看virtualenv在工作中的應用方式。我們先建立一個/data/dataf?ile/software/virtualpy/的虛拟工作目錄,而後再切換至虛拟環境。

// 建立虛拟工作目錄

virtualenv /data/datafile/software/virtualpy/

// 通過source加載環境變量,使本地環境切換至虛拟工作目錄

source /data/datafile/software/virtualpy/bin/activate

看到如圖1-4所示的virtualenv虛拟工作目錄辨別,表示已切換至虛拟工作目錄。

圖1-4 virtualenv虛拟工作目錄

退出虛拟環境指令如下:

// 退出虛拟環境

deactivate

看到如圖1-5所示的退出虛拟工作目錄顯示正常的bash shell提示符,表示即已退出虛拟工作目錄。

圖1-5 退出虛拟工作目錄

至此,多版本python環境管理工具pyenv和virtualenv介紹完畢。如果基于系統預設python版本安裝有問題,可嘗試基于pyenv或virtualenv切換python版本後,再次重試1.7節ansible的安裝步驟。

1.9 本章小結

ansible是運維自動化工具的後起之秀。本章前半部分我們學習了ansible是什麼,底層通信發展史,ansible發展曆程等概念性知識。後半部分我們詳細介紹了ansible安裝部署方式,同時考慮本地複雜環境可能導緻的部署問題,本章後半部分我們也引申介紹了python多環境擴充管理,以友善大家應對部署過程中可能出現的各類問題。當然,ansible的部署總體非常簡單,一般出問題多數是因為系統的glibc、gcc等開發環境沒有安裝或不完整導緻。在學習過程中還請嚴格參考本章安裝操作步驟循序漸進,相信大家學完本章也有所體會。

第2章

ansible基礎元素介紹

第1章介紹了ansible的功能作用、通信發展史、基礎的安裝部署及處理ansible安裝問題所需的python多環境管理工具pyenv和virutalenv。在前期基本工作準備妥當的基礎上,本章進一步深入學習ansible的基礎元素,會相繼接觸ansible目錄結構簡介、ansible系列指令、ansible inventory配置規範、ansible模式比對規則等,其中部分内容,諸如inventory、ansible-playbook等在後續涉及章節會更深入介紹。本章主要是為大家呈現ansible及系列指令的基礎入門介紹,所介紹的内容互相之間沒有緊密關系,可選擇性地閱讀感興趣章節。

2.1 ansible目錄結構介紹

ansible是開源工具,整個開發過程或二次開發均遵循gpl協定,是以所有源碼均可見。作為一款日常工作所需的核心軟體,我們有必要知道其目錄分布及各目錄功能。通過如下指令我們可以擷取ansible所有檔案存放目錄:

# rpm -ql ansible

該指令輸出内容較多,大緻分為如下幾類:

配置檔案目錄/etc/ansible/

執行檔案目錄/usr/bin/

lib庫依賴目錄/usr/lib/pythonx.x/site-packages/ansible/

help文檔目錄/usr/share/doc/ansible-x.x.x/

man文檔目錄/usr/share/man/man1/

整體的目錄概要可參考如圖2-1所示的ansible目錄樹結構。

圖2-1 ansible目錄樹結構

其中,如下目錄運維常要配置,需熟練掌握。

1)配置檔案目錄/etc/ansible/,主要功能為:inventory主機資訊配置、ansible工具功能配置等。所有ansible的配置均存放在該目錄下,運維日常的所有配置類操作也均基于此目錄進行。

2)執行檔案目錄/usr/bin/,主要功能為:ansible系列指令預設存放目錄。ansible所有的可執行檔案均存放在該目錄下。

在/usr/lib/pythonxxx/site-packages/下,該目錄是系統目前預設的python路徑,因為ansible是基于python編寫的,是以ansible的所有lib庫檔案和子產品檔案也均存放于該目錄下。希望了解ansible源碼的話可至該目錄下檢視其工作原理,當然也可至github上下載下傳曆史或最新ansible版本。

2.2 ansible配置檔案解析

inventory用于定義ansible的主機清單配置,ansible的自身配置檔案隻有一個,即ansible.cfg,ansible安裝好後它預設存放于/etc/ansible/目錄下。ansible.cfg配置檔案可以存在于多個地方,ansible讀取配置檔案的順序依次是目前指令執行目錄→使用者家目錄下的.ansible.cfg→/etc/ansible.cfg,先找到哪個就使用哪個的配置。其ansible.cfg配置的所有内容均可在指令行通過參數的形式傳遞或定義在playbooks中。

配置檔案ansible.cfg約有350行語句,大多數為注釋行預設配置項。該檔案遵循ini格式,分為如下幾類配置。

(1)[defaults]

該類配置下定義正常的連接配接類配置,如inventory、library、remote_tmp、local_tmp、forks、poll_interval、sudo_user、ask_sudo_pass、ask_pass、transport、remote_port等。

[defaults]

# inventory = /etc/ansible/hosts # 定義inventory

# library = /usr/share/my_modules/ # 自定義lib庫存放目錄

# remote_tmp = $home/.ansible/tmp # 臨時檔案遠端主機存放目錄

# local_tmp = $home/.ansible/tmp # 臨時檔案本地存放目錄

# forks = 5 # 預設開啟的并發數

# poll_interval = 15 # 預設輪詢時間間隔

# sudo_user  = root # 預設sudo使用者

# ask_sudo_pass = true # 是否需要sudo密碼

# ask_pass  = true # 是否需要密碼

# roles_path = /etc/ansible/roles # 預設下載下傳的roles存放的目錄

# host_key_checking = false # 首次連接配接是否需要檢查key認證,建議設為false

# timeout = 10 # 預設逾時時間

# timeout = 10 # 如沒有指定使用者,預設使用的遠端連接配接使用者

# log_path = /var/log/ansible.log # 執行日志存放目錄

# module_name = command # 預設執行的子產品

# action_plugins = /usr/share/ansible/plugins/action # action插件的存放目錄

# callback_plugins = /usr/share/ansible/plugins/callback # callback插件的存放目錄

# connection_plugins = /usr/share/ansible/plugins/connection # connection插件的

# 存放目錄

# lookup_plugins = /usr/share/ansible/plugins/lookup # lookup插件的存放目錄

# vars_plugins = /usr/share/ansible/plugins/vars # vars插件的存放目錄

# filter_plugins = /usr/share/ansible/plugins/filter # filter插件的存放目錄

# test_plugins = /usr/share/ansible/plugins/test # test插件的存放目錄

# strategy_plugins = /usr/share/ansible/plugins/strategy # strategy插件的存放目錄

# fact_caching = memory # getfact緩存的主機資訊存放方式

# retry_files_enabled = false

# retry_files_save_path = ~/.ansible-retry # 錯誤重新開機檔案存放目錄

上述是日常可能用到的配置,這些多數保持預設即可。

(2)[privilege_escalation]

出于安全角度考慮,部分公司不希望直接以root的進階管理者權限直接部署應用,往往會開放普通使用者權限并給予sudo的權限,該部配置設定置主要針對sudo使用者提權的配置。

[privilege_escalation]

# become=true # 是否sudo

# become_method=sudo # sudo方式

# become_user=root # sudo後變為root使用者

# become_ask_pass=false # sudo後是否驗證密碼

(3)[paramiko_connection]

定義paramiko_connection配置,該部分功能不常用,了解即可。

[paramiko_connection] # 該配置不常用到

# record_host_keys=false # 不記錄新主機的key以提升效率

# pty=false # 禁用sudo功能

(4)[ssh_connection]

ansible預設使用ssh協定連接配接對端主機,該部署是主要是ssh連接配接的一些配置,但配置項較少,多數預設即可。

[ssh_connection]

# pipelining = false # 管道加速功能,需配合requiretty使用方可生效

(5)[accelerate]

ansible連接配接加速相關配置。因為有部分使用者不滿意ansible的執行速度,是以ansible在連接配接和執行速度方面也在不斷地進行優化,該配置項在提升ansibile連接配接速度時會涉及,多數保持預設即可。

# accelerate_port = 5099 # 加速連接配接端口

# accelerate_timeout = 30 # 指令執行逾時時間,機關秒

# accelerate_connect_timeout = 5.0 # 連接配接逾時時間,機關秒

# accelerate_daemon_timeout = 30 # 上一個活動連接配接的時間,機關分鐘

# accelerate_multi_key = yes

(6)[selinux]

關于selinux的相關配置幾乎不會涉及,保持預設配置即可。

[selinux]

# libvirt_lxc_noseclabel = yes

(7)[colors]

ansible對于輸出結果的顔色也進行了詳盡的定義且可配置,該選項對日常功能應用影響不大,幾乎不用修改,保持預設即可。

[colors]

# highlight = white

# verbose = blue

# warn = bright purple

# error = red

# debug = dark gray

# deprecate = purple

# skip = cyan

# unreachable = red

# ok = green

# changed = yellow

# diff_add = green

# diff_remove = red

# diff_lines = cyan

上面盡可能全地介紹了運維工作中可能需要修改的配置選項,除了在關閉首次連接配接提示(host_key_checking = false)或提速調整([accelerate]區域塊配置調整)時可能會稍做調整,其中絕大多數選項預設即可,ansible安裝好後無需任何改動即可使用。

2.3 ansible指令用法詳解

ansible指令行執行方式有ad-hoc、ansible-playbook兩種方式,web化執行方式其官方提供了付費産品tower(10台以内免費),個人的話可以基于其提供的api開發類似的web化産品。關于指令行執行的兩種方式ad-hoc和ansible-playbooks、什麼是ad-hoc及ad-hoc與ansible-playbook的差別我們在第3章有詳細介紹,這裡不再贅述。需簡要說明的是兩者沒有本質上的差別,ad-hoc主要用于臨時指令的執行,ansibel-playbook可以了解為ad-hoc的集合,通過一定的規則編排在一起。兩者的操作也極其簡便,且提供了如with_items、failed_when、changed_when、until、ignore_errors等豐富的邏輯條件和dry-run的check mode。但在chceck mode下并不真正執行指令,即将執行的操作不會對端伺服器産生任何影響,隻模拟指令的執行過程是否能正常執行。

通過第1章的學習我們知道,ansible的通信預設基于ssh,是以我們需要對主機先進行認證。ansible認證方式有密碼認證和公私鑰認證兩種方式,其實完全等同于ssh的認證,是以這裡關于這兩種認證方式不做過多介紹。ansible預設使用(筆者也建議各位使用)公私鑰認證方式,究其原因無非是出于安全的考慮,密碼不用明文存放。以本機為例,執行如下指令即可添加本機認證資訊。

// 随機生成公私鑰對,ssh-keygen是linux下認證密鑰生成、管理和轉換工具,詳細用法可參考其man文檔

ssh-keygen  -n "" -b 4096 -t rsa -c "[email protected]" -f /root/.ssh/stanley.rsa

// 為本機添加密鑰認證

ssh-copy-id –i /root/.ssh/stanley.rsa root@localhost

輸入的時候會有如下提示:

are you sure you want to continue connecting (yes/no)?

輸入全小寫的英文字母yes即可。

而後會有類似如下提示輸入對應root使用者的密碼資訊:

root@localhost's password:

輸入正确的密碼資訊後結果認證,随後在目前指令行輸入如下指令嘗試免密碼登入:

ssh -i /root/.ssh/stanley.rsa root@localhost

如不提示輸入密碼即可直接登入則表示密鑰驗證成功。當然,這裡隻是為大家簡要示範密鑰認證的過程,實際應用中為友善起見,一般會使用非root使用者生成預設檔案名為id_rsa、id_rsa.pub的密鑰對,在使用時通過sudo的方式擷取權限。

ansible的指令使用格式如下:

ansible <host-pattern> [options]

<host-pattern>是inventory中定義的主機或主機組,可以為ip、hostname、inventory中的group組名、具有“.”或“*”或“:”等特殊字元的比對型字元串,<>表示該選項是必須項,不可忽略。

[options]是ansible的參數選項,[]表示該選項中的參數任選其一。

ansible指令可用選項非常多,這裡列舉如下會用到的選項,詳細選項可參考man或第3章。

-m name, --module-name=name:指定執行使用的子產品。

-u username, --user=username:指定遠端主機以username運作指令。

-s, --sudo:相當于linux系統下的sudo指令。

-u sudo_username, --sudo-user=sudo_username:使用sudo,相當于linux下的sudo指令。

具體示例如下:

// 以bruce使用者執行ping存活檢測

ansible all -m ping -u bruce

// 以bruce sudo至root執行ping存活檢測

ansible all -m ping -u bruce --sudo

// 以bruce sudo至batman使用者執行ping存活檢測

ansible all -m ping -u bruce --sudo --sudo-user batman

但在新版本中ansible的sudo指令廢棄,改為--become或-b,如上指令需改為如下:

ansible all -m ping -u bruce -b

ansible all -m ping -u bruce -b --become-user batman

ansible-playbook的指令用法和ansible略有不同,雖然參數選項與ansible有很多相同的地方,但也新增了針對ansible-playbook特有的參數。

ansible-playbook的指令使用格式如下:

ansible-playbook playbook.yml

ansible-playbook指令後跟事先編輯好的playbook.yml檔案即可。本節隻簡單介紹其用法,在第4、5、6章有大量内容介紹其寫法、進階用法及優化方向。ansible-playbook新增的功能參數如下:

--ask-vault-pass:加密playbook檔案時提示輸入密碼。

-d, --diff:當更新的檔案數及内容較少時,該選項可顯示這些檔案不同的地方,該選項結合-c用會有較好的效果。

-e extra_vars, --extra-vars=extra_vars:在playbook中引入外部變量。

--f?lush-cache:将fact清除到的遠端主機緩存。

--force-handlers:強制運作handlers的任務,即使在任務失敗的情況下。

-i inventory:指定要讀取的inventory檔案。

--list-tags:列出所有可用的tags。

--list-tasks:列出所有即将被執行的任務。

--skip-tags=skip_tags:跳過指定的tags任務。

--start-at-task=start_at_task:從第幾條任務開始執行。

--step:逐漸執行playbook定義的任務,并經人工确認後繼續執行下一步任務。

--syntax-check:檢查playbook中的文法書寫。

-t tags, --tags=tags:指定執行該tags的任務。

在日常工作中,大家經常會遇到批量添加認證的問題,而逐條添加認證方式,如機械地對每台主機都一條條添加認證,那是一件非常麻煩的事,也違反了我們期望的自動化方式。具體的批量添加認證方式請參考第9章。如前面所介紹,ansible不僅有ansible、ansible-playbook指令,還有ansible-galaxy、ansible-pull、ansible-doc、ansible-vault、ansible-console(2.0版本新增)指令,掌握ansible的基礎用法後,我們将更深一步學習ansible系列指令。

2.4 ansible系列指令用法詳解與使用場景介紹

如何擷取ansible的系列指令呢?在終端鍵入ansible後連續按兩次tab鍵,會補全所有以ansible字母開頭的指令,這些指令均是ansible系列指令。本節我們來逐一介紹ansible的系列指令使用。

ansible

ansible-galaxy

ansible-pull

ansible-doc

ansible-playbook

ansible-vault

ansible-console

2.4.1 ansible

指令ansible是日常工作中使用率非常高的指令之一,man中是如此定義其功能的:run a command somewhere else,可見其靈活性。ansible指令主要在如下場景使用:

非固化需求

臨時一次性操作

二次開發接口調用

那麼什麼是非固化需求和臨時一次性操作呢?簡單來講,比如工作中我臨時想檢視web1伺服器組是否存活,或我想臨時複制本地的/etc/fstab到web伺服器組的/tmp目錄下做測試,類如這些沒有規律的、臨時需要做的任務,我們稱之為非固化需求、臨時一次性操作。具體的指令使用如下:

// 檢查伺服器存活

ansible web1 –m ping

// 複制本地檔案到遠端

ansible web1 –m copy –a "src=/etc/fstab dest=/tmp/fstab owner=root group=root mode=644 backup=yes"

ansible的傳回結果都非常友好,一般會用3種顔色來表示執行結果:紅色、綠色、橘黃色。其中紅色表示執行過程有異常,一般會中止剩餘所有的任務,如圖2-2所示的ansible執行結果錯誤的結果傳回;綠色和橘黃色表示執行過程沒有異常,所有任務均正常執行,但橘黃色表示指令執行結束後目标有狀态的變化。如圖2-3所示,ansible執行結果正确的結果傳回中的圓圈1為橘黃色顯示;而綠色表示指令執行結束後目标沒有狀态變化,如圖2-3中的圓圈2顯示。

圖2-2 ansible執行結果錯誤的結果傳回

圖2-3 ansible執行結果正确的結果傳回

不僅ansible指令的執行結果如此設定,ansible系列指令均如此設定,是以判斷ansible系列指令的執行結果是否正常是一件非常容易的事情,隻要看顔色即可。

2.4.2 ansible-galaxy

這裡的galaxy和三星手機沒有任何關系。ansible-galaxy的功能可以簡單地了解為github或pip的功能,通過ansible-galaxy指令,我們可以根據下載下傳量和關注量等資訊,查找和安裝優秀的roles。roles是ansible非常重要的一項功能,關于roles的詳細功能會在第6章介紹。在ansible-galaxy上,我們可以上傳和下載下傳roles,這裡也是優秀roles的聚集地,下載下傳位址為https://galaxy.ansible.com。

ansible-galaxy指令使用格式如下:

ansible-galaxy [init|info|install|list|remove] [--help] [options] ...

ansible-galaxy指令分三大部分:

(1)[init|info|install|list|remove]

init:初始化本地的roles配置,以備上傳roles至galaxy。

info:清單指定role的詳細資訊。

install:下載下傳并安裝galaxy指定的roles到本地。

list:列出本地已下載下傳的roles。

remove:删除本地已下載下傳的roles。

ansible 2.0版本中,針對ansible-galaxy增加了login、import、delete、setup等功能,但這些功能需基于login在galaxy認證成功後方可執行,主要為了友善對galaxy上已有的roles的配置工作。

(2)help用法顯示[--help]

針對第一部分的init、info等功能,其後跟--help可單獨顯示該項用法。例如:

ansible-galaxy init ––help

執行後會傳回ansible-galaxy init選項的用法說明。

usage: ansible-galaxy init [options] role_name

options:

    -f, --force           force overwriting an existing role

    -h, --help            show this help message and exit

    -c, --ignore-certs    ignore ssl certificate validation errors.

    -p init_path, --init-path=init_path

                          the path in which the skeleton role will be created.

                          the default is the current working directory.

    --offline             don't query the galaxy api when creating roles

    -s api_server, --server=api_server

                          the api server destination

    -v, --verbose         verbose mode (-vvv for more, -vvvv to enable

                          connection debugging)

    --version             show program's version number and exit

其他選項與help用法一樣。

(3)參數項[options]

該部分結合第一部分的參數完成ansible-galaxy完整的功能用法,如:

ansible-galaxy init [options] role_name即ansible-galaxy init後跟[-f|-h|-c|-p|--off?line|-s server|-v|--version]參數,後跟role-name成為一條完整的指令。

具體可參考如下:

// 下載下傳使用者hectcastro的nginx這個role到本地并忽略錯誤(預設存放在/etc/ansible/roles/)

ansible-galaxy --ignore-errors install azavea.git

因為ansible-galaxy是對https://galaxy.ansible.com網站的上傳、下載下傳、配置類工作,如有類似如下報錯,請確定該網站可正常通路。

the api server (galaxy.ansible.com) is not responding, please try again later.

2.4.3 ansible-pull

該指令的使用涉及ansible的另一種工作模式:pull模式(ansible預設使用push模式)。這和通常使用的push模式工作機理剛好相反,其适用于以下場景:①你有數量巨大的機器需要配置,即使使用高并發線程依舊要花費很多時間;②你要在剛啟動的、沒有網絡連接配接的主機上運作anisble。

ansible-pull指令使用格式如下:

ansible-pull [options] [playbook.yml]

通過ansible-pull結合git和crontab一并實作,其原理如下:通過crontab定期拉取指定的git版本到本地,并以指定模式自動運作預先制訂好的指令。

具體示例參考如下:

*/20 * * * * root /usr/local/bin/ansible-pull -o -c 2.1.0 -d /srv/www/king-gw/ -i /etc/ansible/hosts -u git:// git.kingifa.com/king-gw-ansiblepull >> /var/log/ansible-pull.log 2>&1

ansible-pull通常在配置大批量機器的場景下會使用,靈活性稍有欠缺,但效率幾乎可以無限提升,對運維人員的技術水準和前瞻性規劃有較高要求。

2.4.4 ansible-doc

ansible-doc是ansible子產品文檔說明,針對每個子產品都有詳細的用法說明及應用案例介紹,功能和linux系統man指令類似。該指令使用方式如下:

ansible-doc [options] [module...]

ansible-doc指令後跟[options]參數或[子產品名],顯示子產品用法說明,具體示例如下:

// 列出支援的子產品

ansible-doc –l

// 子產品功能說明

ansible-doc ping

2.4.5 ansible-playbook

ansible-playbook是日常應用中使用頻率最高的指令,其工作機制是:通過讀取預先編寫好的playbook檔案實作批量管理。要實作的功能與指令ansible一樣,可以了解為按一定條件組成的ansible任務集。

ansible-playbook指令後跟yml格式的playbook檔案,執行事先編排好的任務集,指令使用方式如下:

// 執行gw.yml這個playbook中定義的所有任務集

ansible-playbook gw.yml

playbook具有編寫簡單、可定制性高、靈活友善,以及可固化日常所有操作的特點,運維人員應熟練掌握。

2.4.6 ansible-vault

ansible-vault主要用于配置檔案加密,如編寫的playbook配置檔案中包含敏感資訊,不希望其他人随意檢視,ansible-vault可加密/解密這個配置檔案,具體使用方式如下:

usage: ansible-vault [create|decrypt|edit|encrypt|rekey|view] [--help] [options] file_name

具體示例如下。

設定如下密碼,加密a.yml檔案。

ansible-vault   encrypt a.yml

會有以下輸入加密密碼提示:

vault password:

confirm vault password:

encryption successful

這時,再打開a.yml檔案後會發現該檔案亂碼,隻有通過如下指令解密後方可正常檢視。

ansible-vault decrypt a.yml

輸入預設的密碼後方可解密。

decryption successful

此時a.yml檔案可正常檢視。

到此,我們對ansible的用法及系列指令已經有了概念性的了解和掌握,接下來我們進一步了解ansible inventory檔案的配置管理。

2.4.7 ansible-console

ansible-console是ansible為使用者提供的一款互動式工具,使用者可以在ansible-console虛拟出來的終端上像shell一樣使用ansible内置的各種指令,這為習慣于使用shell互動方式的使用者提供了良好的使用體驗。ansible-console主要是針對1.x版本中ansible-shell工具而研發的,目前官網還沒有對ansible-console進行詳細的用法說明,最新版本的ansible軟體包也沒有對應的man文檔說明。經筆者實測,ansible-console指令的使用格式如下。

在終端鍵入ansible-console指令後,會進入如圖2-4所示的類似shell一樣的互動式終端環境。

圖2-4 ansible-console指令用法1

圖2-4中的“root@all (4)[f:5]$”是提示符,該提示符表示“目前的使用使用者@目前所在的inventory中定義的組,預設是all分組(inventory中all組所有主機的數量)[forks:線程數]$”。

使用cd指令可切換至指定hosts或分組,同時提示符的相應資訊也會随之變動,如圖2-5所示。

圖2-5 ansible-console指令用法2

如圖2-5中的ansible-console指令用法2所示,cd至webs分組後,原來的root@all (4)[f:5]$也相應地變更為root@webs (3)[f:5],表示目前分組為webs分組,該分組所擁有的主機總數為3台。執行forks 2後,提示符再次變更為root@webs (3)[f:2]$,表示設定并發的線程數為2。

所有的操作與shell類似,而且支援tab鍵補全,如啟動httpd服務時,鍵入service後連續按兩次tab鍵後會自動補全剩餘的指令選項。ansible-console指令用法3如圖2-6所示。

圖2-6 ansible-console指令用法3

如需啟動httpd服務,使用指令service name=httpd state=started,指令用法與ad-hoc一緻,隻是格式上的使用習慣不同而已。如想擷取service子產品更詳細的用法,輸入help service指令即可。ansible-console指令用法4如圖2-7所示。

圖2-7 ansible-console指令用法4

使用完畢如希望退出,按快捷鍵ctrl+d或ctrl+c即可退出目前的虛拟終端。

ansible-console指令在實際工作中用于ad-hoc和ansible-playbooks之間的場景,常用于集中一批臨時操作或指令,使用ad-hoc要鍵入很多次但整體操作的複雜度又不至于使用playbooks時,這時ansible-console是最佳選擇。

2.5 ansible inventory配置及詳解

inventory是ansible管理主機資訊的配置檔案,相當于系統hosts檔案的功能,預設存放在/etc/ansible/hosts。為友善批量管理主機,便捷使用其中的主機分組,ansible通過inventory來定義其主機群組,在使用時通過–i或--inventory-file指定讀取,與ansible指令結合使用時組合如下:

ansible –i /etc/ansible/hosts webs –m ping

如果隻有一個inventory時可不用指定路徑,預設讀取/etc/ansible/hosts。inventory可以同時存在多個,而且支援動态生成,如aws ec2、cobbler等均支援,本節我們來學習inventory的使用規則。

2.5.1 定義主機群組

inventory配置檔案遵循ini檔案風格,中括号中的字元為組名。其支援将同一個主機同時歸并到多個不同的組中,分組的功能為it人員維護主機清單提供了非常大的便利。此外,若目标主機使用了非預設的ssh端口,還可以在主機名稱之後使用冒号加端口号來标明,以行為機關分隔配置,詳細資訊可參考以下代碼中的注釋。

# “# ”開頭的行表示該行為注釋行,即當時行的配置不生效

# inventory可以直接為ip位址

192.168.37.149

# inventory同樣支援hostname的方式,後跟冒号加數字表示端口号,預設22号端口

ntp.magedu.com:2222

nfs.magedu.com

# 中括号内的内容表示一個分組的開始,緊随其後的主機均屬于該組成員,空行後的主機亦屬于該組,即web2.magedu.com這台主機也屬于[websevers]組

[websevers]

web1.magedu.com

web[10:20].magedu.com # [10:20]表示10~20之間的所有數字(包括10和20),即表示web10.magedu.com、web11.magedu.com……web20.magedu.com的所有主機

web2.magedu.com[dbservers]

db-a.magedu.com

db-[b:f].magedu.com # [b:f]表示b到f之間的所有數字(包括b和f),即表示db-b.magedu.com、db-e.magedu.com……db-f.magedu.com的所有主機

2.5.2 定義主機變量

在日常工作中,通常會遇到非标準化的需求配置,如考慮到安全性問題,業務人員通常将企業内部的web服務80端口修改為其他端口号,而該功能可以直接通過修改inventory配置來實作,在定義主機時為其添加主機變量,以便在playbook中使用針對某一主機的個性化要求。

[webservers]

web1.magedu.com http_port=808 maxrequestsperchild=801 # 自定義http_port的端口号為808,配置maxrequestsperchild為801

ansible其實支援多種方式修改或自定義變量,inventory是其中的一種修改方式,在第6章中我們會詳細介紹。不管哪種修改方式,大家一定要有自己的修改規範,以便于差別管理已有配置。

2.5.3 定義組變量

ansible支援定義組變量,主要針對大量機器的變量定義需求,賦予指定組内所有主機在playbook中可用的變量,等同于逐一給該組下的所有主機賦予同一變量。定義組變量的參考案例如下:

[groupservers]

web2.magedu.com

[groupservers:vars]

ntp_server=ntp.magedu.com  # 定義groupservers組中所有主機ntp_server值為ntp.magedu.com

nfs_server=nfs.magedu.com # 定義groupservers組中所有主機nfs_server值為nfs.magedu.com

2.5.4 定義組嵌套及組變量

inventory中,組還可以包含其他的組(嵌套),并且也可以向組中的主機指定變量。不過,這些變量隻能在ansible-playbook中使用,而ansible不支援。組與組之間可以互相調用,并且可以向組中的主機指定變量。

參考示例如下:

[apache]

httpd1.magedu.com

httpd2.magedu.com

[nginx]

ngx1.magedu.com

ngx2.magedu.com

[webservers:children]

apache

nginx

[webservers:vars]

ntp_server=ntp.magedu.com

ansible以簡單為其核心理念,上述實作在業務日常使用中并不常見,大家了解其用法即可。

2.5.5 多重變量定義

變量除了可以在inventory中一并定義,也可以獨立于inventory檔案之外單獨存儲到yaml格式的配置檔案中,這些檔案通常以.yml、.yaml、.json為字尾或者無字尾。變量通常從如下4個位置檢索:

inventory配置檔案(預設/etc/ansible/hosts)

playbook中vars定義的區域

roles中vars目錄下的檔案

roles同級目錄group_vars和hosts_vars目錄下的檔案

假如foosball主機同屬于raleigh和webservers組,那麼其變量在如下檔案中設定均有效:

/etc/ansible/group_vars/raleigh # can optionally end in '.yml', '.yaml', or '.json'

/etc/ansible/group_vars/webservers

/etc/ansible/host_vars/foosball

對于變量的讀取,ansible遵循如上優先級順序,是以大家設定變量時盡量沿用同一種方式,以友善維護人員管理。

2.5.6 其他inventory參數清單

除了支援如上的功能外,ansible基于ssh連接配接inventory中指定的遠端主機時,還内置了很多其他參數,用于指定其互動方式,如下列舉了部分重要參數:

ansible_ssh_host:指定連接配接主機ansible_ssh_port,指定ssh連接配接端口,預設22

ansible_ssh_user:指定ssh連接配接使用者ansible_ssh_pass,指定ssh連接配接密碼ansible_sudo_pass:指定ssh連接配接時sudo密碼

ansible_ssh_private_key_file:指定特有私鑰檔案

其他内置參數還有數十個,這些參數均可以直接寫在指令行或playbook檔案中,以覆寫配置檔案中的定義。更多參數請參考官網。

2.6 ansible與正則

正規表達式(patterns)是各類進階語言的必定支援的方法之一,ansible也不例外。其patterns功能等同于正規表達式,文法使用也和正則類同,這大大便利了運維的使用。其對于ansible的靈活性有着極大貢獻,該功能同樣支援ansible-playbook。其用法也非常簡單。

ansible <pattern_goes_here> -m <module_name> -a <arguments>

該功能主要針對inventory的主機清單使用,我們通過一些案例可以更好地了解其功能及用法。在如下示例中主要針對webservers進行正則比對:

// 重新開機webservers組所有主機的httpd服務

ansible webservers -m service -a "name=httpd state=restarted"

(1)all(全量)比對

比對所有主機,all或*号功能相同。如檢測所有主機存活情況。

// all和*功能相同,但*号需引起來

ansible all –m ping

ansible "*" -m ping

檢查192.168.1.0/24網段所有主機存活狀況。

ansible 192.168.1.* -m ping

(2)邏輯或(or)比對

如我們希望同時對多台主機或多個組同時執行,互相之間用“:”(冒号)分隔即可。

web1:web2

使用方式如下:

ansible "web1:web2" -m ping

(3)邏輯非(!)比對

邏輯非用感歎号(!)表示,主要針對多重條件的比對規則,使用方式如下:

// 所有在webservers組但不在phoenix組的主機

webservers:!phoenix

(4)邏輯與(&)比對

和邏輯非一樣,邏輯與也主要針對多重條件的比對規則,隻是邏輯上的判斷不同。邏輯與使用&表示,請看如下示例:

// webservers組和staging組中同時存在的主機

webservers:&staging

(5)多條件組合

ansible同樣支援多條件的複雜組合,該情況企業應用不多,這裡做簡單舉例說明。

// webservers和dbservers兩個組中的所有主機在staging組中存在且在 phoenix組中不存在的主機

webservers:dbservers:&staging:!phoenix

(6)模糊比對

*通配符在ansible表示0個或多個任意字元,主要應用于一些模糊規則比對,在平時的使用中應用頻率非常高,請參考如下示例:

// 所有以.magedu.com結尾的主機均符合

*.magedu.com

// one開頭.com結尾的所有主機和dbservers組中的所有主機

one*.com:dbservers

(7)域切割

ansible底層基于python,是以也支援域切割。python字元串域切割的示例如下:

str = '12345678'

print str[0:1]

通過[0:1]即可擷取數值1。該功能在ansible中也支援,以如下inventory内容為例:

cobweb

webbing

weber

通過截取數組下标可以獲得對應變量值。

webservers[0] # == cobweb

webservers[-1] # == weber

webservers[0:1] # == webservers[0],webservers[1]

# == cobweb,webbing

webservers[1:] # == webbing,weber

(8)正則比對

ansible同樣完整支援正則比對功能,“~”開始表示正則比對。

~(web|db).*\.example\.com

檢測beta.example.com、web.example.com、green.example.com、beta.example.org、web.example.org、green.example.org的存活,使用如下比對模式:

ansible "~(beta|web|green)\.example\.(com|org)" -m ping

檢測inventory中所有以192.168開頭的伺服器存活資訊:

ansible ~192\.168\.[0-9]\{\2}.[0-9]\{2,} -m ping

關于ansible的正則功能到此結束,相信大家在浏覽的過程中對其靈活程度也會有所感觸,在對ansible的實際應用過程中也會不斷地加深對其了解。

2.7 本章小結

本章着重為大家介紹了ansible目錄結構功能及ansible指令使用方式。在對ansible的使用有概念性的了解後,又介紹ansible系列指令的功能作用,通過簡單的案例加深對各指令功能的了解。inventory是ansible的核心功能點之一,本章用了約一半内容講解了inventory的入門、書寫規範、使用技巧及其與正則的結合使用。正則作為運維必備技能與ansible的結合也使得ansible愈顯靈活,功能也愈顯強大,請務必熟練掌握。下章我們将為大家介紹ansible ad-hoc指令集的進階使用。

第3章

ansible ad-hoc指令集

第2章介紹了ansible的各項元素、系列指令、inventory基礎,以及ansible與正則的結合使用,這些内容是掌握ansible的基礎,請務必熟練掌握。在前兩章的基礎上,本章為大家介紹ansible ad-hoc指令集,通過模拟真實的企業案例和應用場景更深入地了解ansible。作為ansible最常用的指令,本節内容顯得尤為重要。

3.1 ad-hoc使用場景

所謂ad-hoc,簡而言之是“臨時指令”,英文中作為形容詞有“特别的,臨時”的含義。ad-hoc隻是官方對ansible指令的一種稱謂,大家按各自習慣稱呼即可。筆者平時一般稱之為“臨時操作”或ansible指令。

從功能上講,ad-hoc是相對ansible-playbook而言的,ansible提供兩種完成任務方式:一種是ad-hoc指令集,即指令ansible,另外一種就是ansible-playbook了,即指令ansible-playbook。前者更注重于解決一些簡單或者平時工作中臨時遇到的任務,相當于linux系統指令行下的shell指令,後者更适合于解決複雜或需固化下來的任務,相當于linux系統的shell scripts。通常,深入ansible是從接觸ansible-playbook開始的,靈活運用ansible-playbook才能更好地體會到ansible的強大所在。

具體來講,什麼樣的場景下我們需要用到ad-hoc,什麼樣的情況下需要使用ansible-playbook呢?

(1)需要使用ad-hoc的場景

情景1:

節假日将至,我們需要關閉所有不必要的伺服器,并對所有伺服器進行節前健康檢查。

情景2:

臨時更新apache &nginx的配置檔案,且需同時将其分發至所有需更新該配置的web伺服器。

(2)需要使用ansible-playbook的場景

新購置的伺服器安裝完系統後需做一系列固化的初始化工作,諸如:定制防火牆政策、添加ntp時間同步配置、添加epel源等。

業務側每周定期對生産環境釋出更新程式代碼。

其實兩者之間關系用急行軍(ad-hoc)和遠征軍(ansible-playbook)來形容可能更容易了解。急行軍需輕裝上陣,注重靈活機動;遠征軍需穩紮穩打,注重長遠規劃。正如我們上面所講,ad-hoc更注重于解決一些簡單或者平時工作中臨時遇到的任務,ansible-playbook更适合于解決複雜的或需固化下來的任務。後面的章節中我們會介紹大量企業實戰場景,相信大家會有更深刻的體會。

3.2 ad-hoc指令集介紹

本節介紹通過ad-hoc指令集檢視系統設定,通過ad-hoc研究ansible的并發特性,通過ad-hoc研究ansible的子產品使用。俗話說,磨刀不誤砍柴工。開始之前做一些簡單的初始化檢查,如系統時間正确與否、磁盤容量是否充足等,是很有必要的。

在實際工作中,很多“詭異”問題迫使我們花費大量時間排查,最終卻發現是非常簡單的基礎環境問題導緻的。這其實還是挺常見的,不論對新手還是老鳥均如此,謹記!

我們前面做的系統時間正确與否、磁盤容量是否充足等工作,其實linux下是有開源工具可以幫助我們自動監控的。這裡也為大家推薦幾款linux下耳熟能詳的監控工具,如zabbix、nagios、cacti、falcon、cat等。

3.2.1 ad-hoc指令集用法簡介

本節我們介紹ad-hoc指令集用法。ad-hoc指令集由/usr/bin/ansible實作,其指令用法如下:

可用選項如下。

-v, --verbose:輸出更詳細的執行過程資訊,-vvv可得到執行過程所有資訊。

-i path, --inventory=path:指定inventory資訊,預設/etc/ansible/hosts。

-f num, --forks=num:并發線程數,預設5個線程。

--private-key=private_key_file:指定密鑰檔案。

-m directory, --module-path=directory:指定子產品存放路徑,預設/usr/share/ansible,也可以通過ansible_library設定預設路徑。

-a 'arguments', --args='arguments':子產品參數。

-k, --ask-pass ssh:認證密碼。

-k, --ask-sudo-pass sudo:使用者的密碼(--sudo時使用)。

-o, --one-line:标準輸出至一行。

-t directory, --tree=directory:輸出資訊至directory目錄下,結果檔案以遠端主機名命名。

-t seconds, --timeout=seconds:指定連接配接遠端主機的最大逾時,機關是秒。

-b num, --background=num:背景執行指令,超num秒後中止正在執行的任務。

-p num, --poll=num:定期傳回背景任務進度。

-c connection, --connection=connection:指定連接配接方式,可用選項paramiko (ssh)、ssh、local,local方式常用于crontab和kickstarts。

-l subset, --limit=subset:指定運作主機。

-l ~regex, --limit=~regex:指定運作主機(正則)。

--list-hosts:列出符合條件的主機清單,不執行任何指令。

下面的示例有助于加深對上述内容的了解。

情景1:檢查proxy組所有主機是否存活。

執行指令:

ansible proxy  –f 5 –m ping

傳回結果如圖3-1所示。

圖3-1 ansibleping指令傳回結果

執行結果诠釋:

192.168.37.159 | success >> {

    "changed": false,

    "ping": "pong"

}

其中192.168.37.159是指指令執行的主機,success表示指令執行成功,“>> {}”表示詳細傳回結果如下。“"changed": false”表示沒有對主機做變更,“"ping": "pong"”表示執行了ping指令傳回結果為pong。

情景2:傳回proxy組所有主機的hostname,并列印最詳細的執行過程到标準輸出。

ansible proxy -s -m command -a 'hostname' -vvv

傳回結果如圖3-2所示。

圖3-2 ansiblehostname指令傳回結果

<192.168.37.159> establish connection for user: root on port 22 to 192.168.37.159  # 遠端主機192.168.37.159監聽root使用者的22号端口

<192.168.37.159> remote_module command hostname # 遠端執行指令hostname

<192.168.37.159> exec /bin/sh -c 'mkdir -p $home/.ansible/tmp/ansible-tmp-1455684626.83-94958346638443 && echo $home/.ansible/tmp/ansible-tmp-1455684626.83-94958346638443' # 生成臨時目錄用于存放ansible遠端執行腳本

<192.168.37.159> put /tmp/tmp5sawsq to /root/.ansible/tmp/ansible-tmp-1455684626.83-94958346638443/command # 改名臨時腳本并存放至臨時目錄

<192.168.37.159> exec /bin/sh -c 'sudo -k && sudo -h -s -p "[sudo via ansible, key=urvzacjxvaagwvlrywymxpxfhjkirkqb] password: " -u root /bin/sh -c '"'"'echo become-success-urvzacjxvaagwvlrywymxpxfhjkirkqb; lang=c lc_ctype=c /usr/bin/python /root/.ansible/tmp/ansible-tmp-1455684626.83-94958346638443/command; rm -rf /root/.ansible/tmp/ansible-tmp-1455684626.83-94958346638443/ >/dev/null 2>&1'"'"'' # 使用sudo方式并以python腳本方式執行指令

192.168.37.159 | success | rc=0 >> # 傳回結果為success,coderesult為0

linuxlst # 傳回的指令傳回結果如下

使用-vvv參數可以清楚地了解ansible指令執行流程,如圖3-3所示。

圖3-3 ansible指令執行流程圖

情景3:列出web組所有主機清單。

ansible web --list

傳回結果如下:

10.3.33.21

10.3.33.23

--list選項列出web組所有主機清單資訊,web組中包括 10.3.33.21 和 10.3.33.23兩台主機

接下來我們模拟較為複雜的場景。

情景4:對10.21.40.61伺服器以root執行sleep 20,設定最大連接配接逾時時長為2s,且設定為背景運作模式,執行過程每2s輸出一次進度,如5s還未執行完則終止該任務。

// time指令可省,為友善觀察結果,這裡使用time指令檢視執行時長

time ansible 10.21.40.61 -b 5 -p 2 -t 2 -m command -a 'sleep 20'  -u root

傳回結果如圖3-4所示。

圖3-4 傳回結果

第1行:[warning]不用理會,需更新gmp,該提醒不影響指令傳回結果

第2行:background launch...表示使用-b使該指令背景運作

下面每隔2s輸出一次執行進度

<job 182625384959.32339> polling on 10.21.40.61, 3s remaining表示執行時長剩餘3s

<job 182625384959.32339> polling on 10.21.40.61, 1s remaining表示執行時長剩餘1s

real    0m10.268s程式執行總時長

user    0m1.898s系統使用者層執行時長

sys     0m0.163s系統核心層執行時長

 細心的朋友會發現,我們sleep 20表示暫停 20s,即該指令最少執行時長為20s,但為什麼real程式實際運作時長隻有10s呢?這就是-b選項的意義了,如果超過其指定時間則終止正在執行的任務(但real為什麼是10.268s而不是5.268s,經筆者實測,-b功能生效但時間不精确,正式使用前請多測試)。

以上為ad-hoc指令集的用法說明,後面的章節我們會通過更複雜的執行個體深入了解其功能。

3.2.2 通過ad-hoc檢視系統設定

3.2.1節為大家介紹了ad-hoc的指令集用法,本節我們通過df、free指令檢視系統設定,但是是通過ad-hoc實作的,在此過程中幫助大家了解ansible。我們模拟如下兩個場景。

情景1:批量檢視apps組所有主機的磁盤容量(使用command子產品)。

ansible apps -a "df -lh"

192.168.37.130 | success | rc=0 >>

filesystem            size  used avail use% mounted on

/dev/mapper/vg_linuxlst-lv_root

                       19g  3.6g   14g  21% /

tmpfs                 123m     0  123m   0% /dev/shm

/dev/sda1             485m   29m  431m   7% /boot

192.168.37.155 | success | rc=0 >>

filesystem                       size  used avail use% mounted on

/dev/mapper/vg_linuxlst-lv_root   18g  4.9g   12g  30% /

tmpfs                            144m     0  144m   0% /dev/shm

/dev/sda1                        485m   33m  427m   8% /boot

192.168.37.142 | success | rc=0 >>

/dev/mapper/vg_linuxlst-lv_root   18g  5.4g   12g  33% /

192.168.37.156 | success | rc=0 >>

/dev/mapper/vg_linuxlst-lv_root  8.4g  6.4g  1.6g  81% /

tmpfs                            140m     0  140m   0% /dev/shm

/dev/sda1                        485m   35m  426m   8% /boot

/dev/sdb5                         20g  3.0g   16g  16% /data2

以192.168.37.130的傳回為例,success表示指令執行成功,rc=0表示resultcode=0,即指令傳回結果,傳回碼為0,表示指令執行成功,>>後面跟的内容相當于在主機本地執行df –lh後的結果傳回。

情景2:批量檢視遠端主機記憶體使用情況(shell子產品)。

ansible apps -m shell -a  "free -m"

             total       used       free     shared    buffers     cached

mem:           286        282          4          0         34        119

-/+ buffers/cache:        128        158

swap:         2015        668       1347

mem:           244        188         56          0         30        101

-/+ buffers/cache:         56        187

swap:         1023          0       1023

mem:           286        217         69          0         84         63

-/+ buffers/cache:         68        218

swap:         2015          0       2015

mem:           279        251         28          0         29         33

-/+ buffers/cache:        188         91

swap:         1023         22       1001

以192.168.37.142的傳回為例,success表示指令執行成功,rc=0表示resultcode=0,即指令傳回結果,傳回碼為0,表示指令執行成功,>>後面跟的内容相當于在主機本地執行free-m後的結果傳回。

通過上面兩個場景的示例相信大家對ad-hoc的用法有一定的了解,接下來的章節我們進一步學習ansible的并發特性。

3.2.3 通過ad-hoc研究ansible的并發特性

如3.2.1節所講,ansible和ansible-playbook預設會fork 5個線程并發執行指令,但在實際工作中,如果主機數量衆多,ansible并發5個線程是遠不能滿足企業所需的,是以本節介紹ansible的并發特性。我們通過如下測試來更深入地了解ansible的并發工作模式。

場景如下:我們定義[apps]組,多次執行同樣的ad-hoc指令來檢視其傳回的結果。

以下是執行步驟。

步驟1:定義[apps]組,編輯/etc/ansible/hosts的配置。

執行指令vi /etc/ansible/hosts,鍵入i進入vi編輯模式,跳轉到檔案最末尾,添加如下配置:

[apps]

192.168.37.130

192.168.37.155

192.168.37.142

192.168.37.156

步驟2:多次執行ansible指令,執行指令如下:

ansible apps -m ping -f 3

步驟3:對比傳回結果,如表3-1所示。

表3-1 傳回結果對比

第1次傳回結果 第2次傳回結果

192.168.37.130 | success >> {

    "changed": false,

192.168.37.142 | success >> {

192.168.37.155 | success >> {

192.168.37.156 | success >> {

} 192.168.37.130 | success >> {

傳回結果分析如下:

1)同樣的指令多次執行,但每次的輸出結果都不一定一樣。

2)輸出結果不是按照/etc/ansible/hosts中[apps]定義的主機順序輸出。

3)結果輸出基本上遵循每次輸出3條記錄(線程池始終保持3個線程,是以這裡如果每次輸出小于等于3都是正常的)。

通過上面的實驗我們對ansible的并發性有了概念性的了解。回到前面的問題,企業實際應用中,如主機數量很多,我們需調大線程數,該如何操作呢?這裡ansible為我們提供了便捷的選項,-f指定線程數,如-f 1表示并發啟動一個線程,-f 10則表示同時啟動10個線程并發執行指令。其實檢視源碼可知,ansible使用multiprocessing管理多線程。

 單台主機的性能始終有限,大家根據自己機器實際的硬體配置做調整,建議并發數配置的cpu核數偶數倍就好。如4cores 8gb的伺服器,建議最多并發20個線程。關于ansible的性能,後面章節會為大家介紹ansible的加速模式。

3.2.4 通過ad-hoc研究ansible的子產品使用

前面的章節為大家詳細介紹了ad-hoc的指令集使用方法及其并發特性等,那麼,ansible究竟有多少現成功能可供大家使用呢?本節來為大家介紹ad-hoc的子產品使用。

截至本篇編寫時(2016-2-11),官方呈現的所有可用子產品為468個(2016-8-19所有可用子產品為622個,短短6個月增加了154個,可見ansible的發展速度),所有子產品官方也做了詳盡的功能分類。明細可參考官方連結。另外,ansible也提供了類似于man功能的help說明工具ansible-doc,直接按Enter鍵或輸入-h顯示功能用法。它和linux系統下的man指令一樣重要,正式學習ansible子產品使用前,有必要先了解ansible-doc用法。

指令用法:

--version:顯示工具版本号。

-h, --help:顯示該help說明。

-m module_path, --module-path=module_path:指定ansible子產品的預設加載目錄。

-l, --list:列出所有可用子產品。

-s, --snippet:隻顯示playbook說明的代碼段。

-v:等同于—version,顯示工具版本号。

下面我們看些簡單的示例。

情景1:顯示所有可用子產品。

a10_server                    manage a10 networks ax/softax/thunder/vthunder devices

a10_service_group             manage a10 networks ax/softax/thunder/vthunder devices

a10_virtual_server            manage a10 networks ax/softax/thunder/vthunder devices

acl                           sets and retrieves file acl information.

add_host                      add a host (and alternatively a group) to the ansible-playboo...

airbrake_deployment           notify airbrake about app deployments

alternatives                  manages alternative programs for common commands

apache2_module                enables/disables a module of the apache2 webserver

apt                           manages apt-packages

apt_key                       add or remove an apt key

apt_repository                add and remove apt repositories

apt_rpmapt_rpm package manager

arista_interface              manage physical ethernet interfaces

arista_l2interface            manage layer 2 interfaces

arista_lag                    manage port channel (lag) interfaces

arista_vlan                   manage vlan resources

assemble                      assembles a configuration file from fragments

情景2:以yum子產品為例,我們希望擷取yum子產品的help說明。

ansible-doc yum

> yum

    installs, upgrade, removes, and lists packages and groups with the

    `yum' package manager.

options (= is mandatory):

- conf_file

        the remote yum configuration file to use for the transaction.

        [default: none]

其他子產品help說明以此類推即可。下面通過ansible内置子產品來完成一些具體工作。

【示例1】安裝redhat-lsb并檢視伺服器系統版本号。

步驟1:安裝redhat-lsb。

ansible apps -m yum -a 'name=redhat-lsb state=present'

    "msg": "",

    "rc": 0,

    "results": [

        "redhat-lsb-4.0-7.el6.centos.i686 providing redhat-lsb is already installed"

    ]

其中:

"changed":主機是否有變更,true為有;false為沒有(第1次運作或事先沒有安裝,傳回值一般是true,否則為false)。

"msg":安裝過程資訊。

"rc": 0, resultcode:結果傳回碼,非0傳回碼往往是紅色并且錯誤的傳回,非常明顯。

步驟2:檢視系統版本号。

ansible apps -m command -a 'lsb_release -a'

version:    :base-4.0-ia32:base-4.0-noarch:core-4.0-ia32:core-4.0-noarch:graph

lsb

ics-4.0-ia32:graphics-4.0-noarch:printing-4.0-ia32:printing-4.0-noarch

distributor id: centos

description:    centos release 6.5 (final)

release:        6.5

codename:       final

部分執行結果诠釋:

192.168.37.155:表示指令執行的對象。

success:表示指令執行的傳回狀态為成功狀态。

rc=0:表示指令執行的狀态碼為0。

>>:該符号後傳回的所有内容為執行lsb_release –a指令傳回的資訊。

lsb version:表示該系統的核心版本資訊。

distributor id:表示發行廠商。

description:表示版本簡要資訊。

release:表示該系統的發行版本号。

codename:表示發行版本代号。

【示例2】為所有伺服器安裝ntp服務,并設定為開機啟動。

步驟1:安裝ntp服務。

ansible apps -s -m yum -a "name=ntp state=present"

步驟2:啟動ntp服務,并設定為開機啟動。

ansible apps -m service -a "name=ntpd state=started enabled=yes"

傳回的結果不再一一為大家列舉出來,相信上面那麼多的示例,大家對如何判斷結果是否正确能夠了解了。

如linux所有指令的用法一樣,我們隻能記住日常工作中最常用到的那些,另外那些不常用的指令用法我們隻需要知道如何快速擷取它們的用法即可。linux系統為我們提供了man工具來快速擷取所需。ansible-doc則等同于 man 的功能和作用,這樣解釋相信大家會更容易了解其重要性。

3.3 ad-hoc組管理和特定主機變更

3.2節為大家介紹了ansible子產品清單及help說明擷取方式。日常運維工作中,我們往往會将負責相同場景應用的主機劃分為一個組,以友善統一管理。ansible也提供了簡潔但強大的組管理功能。同時,我們也可能遇到隻針對這組主機中一台或某些主機做變更的場景,針對這些複雜多變的企業場景,本節我們将深入了解ad-hoc組管理和特定主機變更,進一步了解ansible如何應對複雜多變的企業環境。

3.3.1 ad-hoc組定義

ad-hoc的組功能定義在inventory檔案中,預設路徑是/etc/ansible/hosts,書寫格式遵循ini風格,中括号中的字元為組名。可以将同一個主機同時歸并到多個不同的組中;此外,若目标主機使用了非預設的ssh端口,還可以在主機名稱之後使用冒号加端口号來标明。下面通過實際案例來了解inventory檔案的書寫規則。

如下為inventory檔案示例,包括了組定義及冒号加端口号功能的使用。

ntp.magedu.com

www1.magedu.com:2222

www2.magedu.com

[dbservers]

db1.magedu.com

db2.magedu.com

db3.magedu.com

如果遠端主機名稱遵循相似的命名模式,還可以使用清單的方式辨別各主機,如下案例為大家展示該寫法。

www[01:50].magedu.com

[databases]

db-[a:f].magedu.com

本次架構規劃了前端proxy、web servers和後面db一套完整應用,以友善大家實際參考,拓撲規劃請參考圖3-5。圖中共定義了proxy、app、nosql和db這4個組。組配置請編輯/etc/ansible/hosts添加如下配置:

圖3-5 架構拓撲規劃

[proxy]

192.168.37.159

[app]

192.168.37.160

[nosql]

[db]

應用分布如下。

[proxy]組:nginx;

[app]組:nginx+php+django;

[nosql]組:redis;

[db]組:mariadb。

如圖3-5所示的架構拓撲是簡化後的網際網路web服務架構,使用者請求通過proxy轉發至後端webservers響應,通過nosql服務緩沖後,最終将請求傳送到db。我們本章的實戰内容就是通過ansible來搭建這樣一套web服務架構。

3.3.2 ad-hoc配置管理:配置proxy與web servers實踐

本節通過配置proxy &web servers學習ad-hoc的組管理方式,前端proxy隻用到nginx七層代理功能,将請求轉發至後端web servers,web servers同時部署nginx、php和django應用,我們按proxy、webservers依次順序部署應用。

(1)ad-hoc配置管理proxy(即nginx)

安裝nginx,執行指令:

ansible proxy -m yum -a "name=nginx state=present"

利用ansible安裝nginx,如圖3-6所示。

圖3-6 ansible安裝nginx

"changed": true, // 表示本次指令對執行的目标有變更,如再執行一次則為false,表示執行的目标沒

// 有變更,這裡的false和true不代表該指令執行成功或失敗,隻是表示執行目

// 标是否被變更

"rc": 0, // resultcode的簡寫,表示指令的執行結果狀态傳回,非0均為異常,指令執行失敗

"results": [ // 執行結果資訊傳回

如果我們要檢查nginx正常安裝,可以執行指令:ansible proxy -m command -a "nginx -v",如果正常則傳回如下内容:

192.168.37.159 | success | rc=0 >>

nginx version: nginx/1.0.15

ansible的yum子產品同樣支援指定某版本安裝,其name參數指定具體版本位址(網絡或本地均可)。yum子產品也支援從網絡安裝或從本地安裝。

如果從網絡安裝,執行指令:

ansible proxy -m yum -a "name=http://nginx.org/packages/centos/6/noarch/rpms/nginx-release-centos-6-0.el6.ngx.noarch.rpm state=present"

如果從本地安裝,執行指令:

ansible proxy -m yum -a "name=/usr/local/src/nginx-release-centos-6-0.el6.ngx.noarch.rpm state=present"

如指定網絡安裝,安裝期間請保障網絡暢通,并可以通路internet,具體安裝時長視網絡寬帶品質而定,如100m帶寬,該項安裝進行了約2min。如圖3-6為nginx安裝的部分結果回報,ansible在對執行結果傳回提示做得确實不盡人意,雖為json格式輸出,但換行和顔色辨別功能仍有待改善。

(2)ad-hoc配置管理web servers

web servers需同時部署nginx、php和django,其中nginx、php依然通過yum子產品實作,django推薦使用pip或easy_install方式。

1)nginx、php安裝指令如下:

ansible app -m yum -a "name=nginx state=present"

ansible app -m yum -a "name=php state=present"

2)django安裝指令如下:

步驟1:安裝mysql-python和python-setuptools依賴包。

ansible app -m yum -a "name=mysql-python state=present"

ansible app -m yum -a "name=python-setuptools state=present"

步驟2:安裝django。

ansible app -m pip -a "name=django state=present"

步驟3:檢查django安裝是否正常,執行指令如下:

ansible app -m command -a "python -c 'import django; print django.get_version()'"

其中django依賴python 2.7+版本,如執行報錯如下,請檢查python版本。

traceback (most recent call last):

    file "<string>", line 1, in <module>

    file "/usr/lib/python2.6/site-packages/django/__init__.py", line 1, in <module>

fromdjango.utils.version import get_version

    file "/usr/lib/python2.6/site-packages/django/utils/version.py", line 7, in <module>

fromdjango.utils.lru_cache import lru_cache

    file "/usr/lib/python2.6/site-packages/django/utils/lru_cache.py", line 28

fasttypes = {int, str, frozenset, type(none)},

                ^

syntaxerror: invalid syntax

pip和easy_install子產品支援virtualenv虛拟多環境配置,該功能極為強大,是python應用者的必備利器。如上我們使用pip子產品安裝django,衆所周知easy_install也是python安裝軟體包常用的工具之一,ansible同樣支援easy_install,指令類同# ansible app -m easy_install -a "name=django"即可。兩者相比較而言,pip的功能較easy_install更為強大,且支援解除安裝、指定版本号等。經過筆者親測,建議使用pip子產品安裝python系列軟體包,除功能強大外,我們發現pip子產品的穩定性和速度也遠勝easy_install子產品(centos 6.5 final)。

截至目前,proxy & web servers部署完畢,通過數條語句即可完成。本示例中的伺服器隻有4台,如果是40、400、4000台,其帶來的便利和節省的時間成本是不可估量的,更為重要的是,這在很大程度上,可以保障操作的正确性。

其實上面的這些變更通過ansible-playbook進行是更好的選擇,在後面playbook章節的講解與應用過程中大家會逐漸有所體會。當然通過shell單獨登入到對應的伺服器也能實作我們想要完成的工作,但ansible為我們節省了海量的時間成本,這也是我們學習ansible的意義所在。

3.3.3 ad-hoc配置後端:配置nosql與database servers實踐

3.3.2節我們使用ansible配置了proxy和web servers,接下來我們使用類似的方法配置nosql和db服務。我們使用redis配置nosql,我們使用mariadb配置db,之是以沒有使用mysql是因為自從mysql被甲骨文公司收購後,雖埃裡森宣稱mysql依然免費,但随着時間的推移,mysql原班核心人馬相繼離開甲骨文,并創立mariadb及mysql社群,開發者對現有oracle舉動感到不滿,行業内不少企業已在考慮使用mariadb,或計劃替換現有mysql。

具體操作步驟如下。

redis安裝指令:ansibledb -m yum -a "name=redis state=present"。

redis安裝檢查:ansibledb -m command -a "redis-cli --version"。

mariadb安裝步驟如下。

步驟1:添加yum源,vim編輯/etc/yum.repos.d/mariadb.repo添加内容如下。

# mariadb 10.1 centos repository list - created 2016-02-13 04:31 utc

# http://mariadb.org/mariadb/repositories/

[mariadb]

name = mariadb

baseurl = http://yum.mariadb.org/10.1/centos6-x86

gpgkey=https:// yum.mariadb.org/rpm-gpg-key-mariadb

gpgcheck=1

步驟2:安裝mariadb-server,

ansibledb -m yum -a "name=mariadb-server state=present"

步驟3:安裝mariadb-client,

ansibledb -m yum -a "name=mariadb-client state=present"

步驟4:開啟防火牆3306通路權限。

ansible db -m command -a "iptables -a input -s 192.168.37.0/24 -p tcp -m tcp --dport 3306 -j accept"

截至目前,如圖3-5所示的應用成功部署完畢。其實我們搭建一套主流web應用架構,期間無需登入遠端主機,通過ansible的結果傳回即可判斷所有操作是否正确。

3.3.4 ad-hoc特定主機變更

前兩節我們通過搭建了一套主流web應用架構熟悉了ansible的組管理,接下來為大家介紹如何針對特定伺服器做變更,該情景在日常運維工作中很常見。

ansible有多種方式實作針對特定主機做變更。

1)--limit:通過--limit參數限定主機做變更。

情景:在app組中啟動192.168.37.15的ntp服務。

ansible app -m command -a "service ntpd status" --limit "192.168.37.158"

2)指定ip:通過指定具體ip限定主機做變更。

情景:啟動192.168.37.158的ntp服務。

ansible 192.168.37.158 -m command -a "service ntpd status"

3)用“:”作分隔符,指定多台機器做變更。

情景:啟動192.168.37.158和192.168.37.161的ntp服務。

ansible "192.168.37.158:192.168.37.161" -m command -a "service ntpd status"

4)通過“*”泛比對,更靈活地針對多台主機做變更。

情景:啟動192.168.37.*所有主機的ntp服務。

ansible 192.168.37.* -m command -a "service ntpd status"

--limit在日常工作中經常用到,ansible-playbook也支援該參數。“:”分隔指定多主機也是不錯的辦法,但記得要用引号将所有位址引起來。

到目前為止ad-hoc組管理及特定主機變更我們已經掌握,這對靈活管理海量伺服器有很大幫助,關于組及指定主機管理介紹到此結束。接下來為大家介紹的是ad-hoc基于使用者的管理。

3.4 ad-hoc使用者與組管理

使用者權限管理是運維日常最重要的管理工作之一,如生産環境禁用開發和測試人員登入變更,但測試環境的使用者權限仍需耗費精力維護,這項工作大公司也存在(将測試環境交給測試或開發管理并不是每個公司都能做到的,但未來是趨勢)。是以掌握ad-hoc使用者與組管理很有用,如筆者現在的公司每次大版本更新後都會大量修改所有伺服器密碼。每次需要修改數十台伺服器環境密碼,若手動單台登入修改可是一項不小的工作,并且手動方式難免會出錯誤。本節為大家介紹ad-hoc使用者與組管理。

ansible系統使用者子產品有如下兩個:

linux系統使用者管理:user。

windows系統使用者管理:win_user。

3.4.1 linux使用者管理

user子產品功能諸多,各功能作用幾乎完全覆寫平時工作正常及非正常場景。子產品所有屬性如表3-2所示。

表3-2 user子產品屬性

參 數 必填項 預設值 選 項 注 釋

append no no yes

no yes:增量添加group

no:全量變更group,隻設定groups指定的group組

comment no 可選設定使用者賬戶的描述(又名gecos)

createhome no yes yes

no 預設yes,當建立使用者期時或家目錄不存在時為使用者建立home目錄

expires(1.9版本增加) no 無 1.9版本的新增功能,使用者過期時間,不支援的平台該參數将被忽略,現在支援linux和freebsd

force no no yes

no 強制,當和state=absent結合使用時,效果等同于userdel --force

generate_ssh_key no no yes

no 是否生成ssh key,不會覆寫已有的ssh key

group no (可選)設定使用者屬組

groups no 設定使用者附加群組,使用逗号分隔多個群組,如果參數為空(即'groups='),則删除使用者所有附加組(屬組不受影響)

home no (可選)設定使用者家目錄

login_class no (可選)設定freebsd、openbsd、netbsd系統的使用者登入class

move_home no no yes

no 如設定為yes,結合使用home=,臨時遷移使用者家目錄到特定目錄

name yes 使用者名

non_unique no no yes

no (可選)和-u結合使用,允許改變使用者id為非唯一值

password no (可選)設定使用者密碼為該項指定的密碼(加密後的密碼),詳細請參考http://docs.ansible.com/ansible/faq.html# how-do-i-generate-crypted-passwords-for-the-user-module

需要注意的是,在darwin系統,該選項必須是明文,請注意安全問題

remove no no yes

no 結合state=absent使用相當于userdel --remove

seuser no (可選)設定seuser類型啟用selinux

(2.1版本增加)

shell no (可選)設定使用者shell

skeleton no (可選)設定使用者的skel目錄,需和createhome參數結合使用

ssh_key_bits no 2048 (可選)指定生成的ssh key加密位數

ssh_key_comment no ansible-generated on $hostname (可選)定義ssh key注釋

ssh_key_f?ile no .ssh/id_rsa (可選)指定ssh key檔案名,如果該檔案名是相對路徑,則預設路徑為使用者家目錄

ssh_key_passphrase no 設定ssh key密碼,如果沒有提供密碼,則預設沒有加密

ssh_key_type no rsa (可選)指定ssh key類型,具體可用的ssh key類型取決于目标主機

state no present present

absent present:建立(使存在)使用者

absent:删除使用者

system no no yes

no 當建立新賬戶時,該選項為yes,為使用者設定系統賬戶,該設定對已經存在的使用者無效

uid no (可選)設定使用者uid

update_password(1.3版本增加) no always always

on_create always:隻有當密碼不相同時才會更新密碼

on_create:隻為新使用者設定密碼

日常工作所需功能幾乎均囊括在内,接下來為大家介紹使用者相關的五大場景應用,以供參考。

場景1:新增使用者。

需求描述:新增使用者dba,使用bash shell,附加組為admins, dbagroup,家目錄為/home/dba/。

該場景中我們可以掌握如下技能點。

1)groups設定:groups=使用者組1,使用者組2……

2)增量添加屬組:append=yes

3)表明屬組狀态為建立:state=present

ansibledb -m user -a "name=dba shell=/bin/bash groups=admins,dbagroup append=yes home=/home/dba/ state=present"

    "changed": true,

    "comment": "",

    "createhome": true,

    "group": 503,

    "groups": "admins,dbagroup",

    "home": "/home/dba/",

    "name": "dba",

    "shell": "/bin/bash",

    "state": "present",

    "system": false,

    "uid": 501

傳回結果資訊非常簡潔明了,這裡不再一一做解釋

場景2:修改使用者屬組。

需求描述:修改dba附件組為dbagroups(即删除admins組權限)。

全量變更屬組資訊:append=no

ansibledb -m user -a "name=dba groups=dbagroup append=no"

    "append": false,

    "groups": "dbagroup",

    "move_home": false,

删除admins組權限的指令中 append值為no。 另外,細心的朋友會發現,新增使用者時,ansible預設為使用者添加使用者組(primary group)。

場景3:修改使用者屬性。

需求描述:設定dba使用者的過期時間為2016/6/1 18:00:00 (unixtime: 1464775200)。

1)設定使用者登入過期時間:expire=1464775200

2)unix時間轉換:2016/6/1 18:00:00需轉換為unixtime格式(不做介紹,請自行百度)

ansibledb -m user -a "name=dba  expires=1464775200"

這樣,我們已經完成了dba使用者的過期時間設定。

場景4:删除使用者。

需求描述:删除使用者dba,并删除其家目錄和郵件清單。

該場景中我們可以掌握如下技能點:

1)表明屬組狀态為删除:state=absent

2)設定remove=yes:remove=yes

ansibledb -m user -a "name=dba state=absent remove=yes"

結果檢查:到對應主機使用root使用者檢視/etc/passwd是否存在dba使用者,或執行指令id dba确認是否有結果傳回。

場景5:變更使用者密碼。

需求描述:設定系統使用者tom的密碼為redhat123。

ansibledb -m user -a "name=tom shell=/bin/bash password=to46pw3goukva update_password=always"

請注意,password後的字元串to46pw3goukva并非真正的密碼,而是經過加密後的密碼。ansible變更使用者密碼方式與直接通過系統指令passwd修改密碼有較大差别。ansible變更密碼時所使用的密碼是将明文密碼加密後的密碼(有些拗口)。官網上介紹了兩種密碼加密方式,筆者建議使用方式2 passlib,因為mkpasswd方式因系統而異,功能差異較大。

方式1:使用指令mkpasswd生成密碼。

步驟1:查找安裝包名稱。

執行指令:yum whatprovides */mkpasswd,結果如下。

epel/filelists_db                                         | 8.0 mb

expect-5.44.1.15-5.el6_4.x86_64 : a program-script interaction and testing utility

repo        : base

matched from:

filename    : /usr/bin/mkpasswd

步驟2:安裝軟體包。

centos 6.5執行指令:yum install expect

debian6 ubuntu 12.04執行指令:sudo apt-get install whois

步驟3:使用mkpasswd生成密碼。

執行指令:mkpasswd --method=sha-512

筆者也對安裝的軟體包(centos安裝expect, debian&ubuntu安裝whois)感覺詫異,一番google查詢也沒有結果。因為這與本書内容關系不大是以沒有深究,感興趣的朋友自行研究後可告知筆者,以便後續補充給使用者。

方式2:使用python的passlib、getpass庫生成密碼。

步驟1:安裝passlib(python版本建議2.7以上)。

pip install passlib

步驟2:生成密碼。

python 3.x系列版本請使用如下指令(sha512加密算法)。

python -c "from passlib.hash import sha512_crypt; import getpass; print (sha512_crypt.encrypt(getpass.getpass()))"

python 3.x系列版本請使用如下指令(普通加密算法)。

python -c 'import crypt; print (crypt.crypt("redhat123", "dba"))'

python 2.x系列版本請使用如下指令(sha512加密算法)。

python -c "from passlib.hash import sha512_crypt; import getpass; print sha512_crypt.encrypt(getpass.getpass())"

python 2.x系列版本請使用如下指令(普通加密算法)。

生成的密碼如圖3-7所示。

圖3-7 生成的密碼

1)同樣密碼多次加密結果不一樣屬正常情況,想深入了解的朋友可自行研究加密算法及原理。

2)ad-hoc方式建議使用普通算法加密,sha512加密後的密碼包括諸多特殊元字元,傳輸至遠端伺服器會有密碼被轉義截斷的問題。sha512加密算法建議在playbook中使用。

linux系統下的使用者與組管理涉及的各類場景本節均有介紹,作為運維日常最重要的工作之一,希望本節内容對相關人員會有幫助。

3.4.2 windows使用者管理

如第1章所介紹,作為關注度最高的集中化管理工具,ansible同樣支援windows系統。但考慮windows不開源的特殊性及伺服器市場的占有率,使得ansible與windows的結合使用時總是會出問題,但其實類似問題其他工具也同樣存在,這是windows特性使然。本章我們隻做簡單示範,第10章我們還介紹windows相關内容。

場景:新增使用者stanley,密碼為magedu@123,屬組為administrators。

ansible windows -m win_user -a "name=stanley passwd=magedu@123 group=administrators"

傳回結果:

192.168.37.146 | success >> {

    "account_disabled": false,

    "account_locked": false,

    "description": "",

    "fullname": "stanley",

    "groups": [

        {

            "name": "administrators",

            "path": "winnt:// workgroup/linuxlst/administrators"

        }

    ],

    "name": "stanley",

    "password_expired": true,

    "password_never_expires": false,

    "path": "winnt:// workgroup/linuxlst/stanley",

    "sid": "s-1-5-21-3965499365-1200628009-3594530176-1004",

    "user_cannot_change_password": false

部分傳回結果诠釋:

account_disabled——禁用使用者登入;

account_locked——解鎖使用者;

groups——使用者所屬組;

name——使用者名;

password_expired——下次登入修改密碼;

user_cannot_change_password——使用者是否可修改密碼。

僅從操作上即可看出,ansible對windows的使用者管理也是基于linux管理方式的沿用,旨在簡單易用。

3.4.3 應用層使用者管理

前面兩小節為大家介紹了ansible基于linux和windows的系統管理。事實上,除開源系統類unix系統和大家耳熟能詳的windows系統以外,ansible也支援商業系統或産品類應用,系統如aws的iam,mac的osx;軟體如apache cloudstack、jabberd、openstack、mongodb、mysql、postgresql、rabbitmq、vertica。本節我們以mysql使用者管理為例介紹。

情景:新增mysql使用者stanley,設定登入密碼為magedu@bj,對zabbix.*表有all權限。

ansible db -m mysql_user -a 'login_host=localhost login_password=magedu login_user=root name=stanley password=magedu@bj priv=zabbix.*:all state=present'

    "user": "stanley"

登入驗證步驟如下。

1)在db伺服器上測試登入。

mysql -ustanley -pmagedu@bj

2)執行指令:show grants for 'stanley'@'localhost';驗證權限是否正确。

其實如上指令存在很大的安全隐患,因為mysql的登入資訊完全暴露在指令台。ansible建議的使用方式如下。

1)在遠端主機的~/.my.cnf檔案中配置root的登入資訊,配置資訊如下:

    [client]

user=root

password=magedu

2)指令行執行指令如下:

ansible db -m mysql_user -a 'name=stanley password=magedu@bj priv=zabbix.*:all state=present'

此方式密碼将不再暴露在控制台,在一定程度上提高了服務安全性。

3.5 本章小結

ansible ad-hoc在運維日常工作中的作用舉足輕重,日常工作中的臨時并發性操作均通過ad-hoc協助完成,是以我們花了很多篇幅為大家介紹其使用及企業實踐。同樣重要的還有ansible的playbook功能,ansible-playbook可幫助我們完成更多、更複雜、更重要的功能。我們将在第4章、第5章、第6章深入學習ansible-playbook的強大功能。