Linux自動(dòng)化運(yùn)維工具之a(chǎn)nsible(二)
YAML簡(jiǎn)介
YAML是一個(gè)可讀性高的用來表達(dá)資料序列的格式。
YAML參考了其他多種語言,包括:XML、C語言、Python、Perl以及電子郵件格式RFC2822等。
Clark Evans在2001年在***發(fā)表了這種語言,另外Ingy döt Net與Oren Ben-Kiki也是這語言的共同設(shè)計(jì)者。
YAML Ain't Markup Language,即YAML不是XML。不過,在開發(fā)的這種語言時(shí),YAML的意思其實(shí)是:"Yet Another Markup Language"(仍是一種標(biāo)記語言)。
其特性包括:
- YAML的可讀性好
- YAML和腳本語言的交互性好
- YAML使用實(shí)現(xiàn)語言的數(shù)據(jù)類型
- YAML有一個(gè)一致的信息模型
- YAML易于實(shí)現(xiàn)
- YAML可以基于流來處理
- YAML表達(dá)能力強(qiáng),擴(kuò)展性好
YAML語法
YAML的語法和其他高階語言類似,并且可以簡(jiǎn)單表達(dá)清單、散列表、標(biāo)量等數(shù)據(jù)結(jié)構(gòu)。
其結(jié)構(gòu)(Structure)通過空格來展示,序列(Sequence)里的項(xiàng)用"-"來代;Map里的鍵值對(duì)用":"分隔。
YAML文件擴(kuò)展名通常為.yaml或者.yml。
下面是一個(gè)示例。
2 個(gè)重要的結(jié)構(gòu)組成部分:list和directory
list 列表的所有元素均使用“-”打頭,例如:
dictionary字典通過key與valuef進(jìn)行標(biāo)識(shí),例如:
也可以將key:value放置于{}中進(jìn)行表示,例如:
多個(gè)映射關(guān)系組成一個(gè)字典,一個(gè)列表可以包含多個(gè)字典。
YAML中的變量
變量命名
變量名僅能由字母、數(shù)字和下劃線組成,且只能以字母開頭。
facts
facts是由正在通信的遠(yuǎn)程目標(biāo)主機(jī)發(fā)回的信息,這些信息被保存在ansible變量中。
要獲取指定的遠(yuǎn)程主機(jī)所支持的所有facts,可使用如下命令進(jìn)行:
- # ansible hostname -m setup
這個(gè)命令可以獲得被監(jiān)控端主機(jī)的各種信息,將這些信息得到后保存到變量中。
自定義變量在 yaml 中可以使用vars關(guān)鍵字來定義變量:
變量的引用
特殊的變量,迭代
當(dāng)有需要重復(fù)性執(zhí)行的任務(wù)時(shí),可以使用迭代機(jī)制。
其使用格式為將需要迭代的內(nèi)容定義為item變量引用,并通過with_items語句來指明迭代的元素列表即可。
示例:
例如:在被控端添加 2 個(gè)用戶 方式
1:一般做法
方式1:使用變量方式
方式2:使用迭代方式
事實(shí)上,with_items中可以使用元素還可為hashes,例如:
Inentory文件的格式
inventory文件遵循INI文件風(fēng)格,中括號(hào)中的字符為組名。
可以將同一個(gè)主機(jī)同時(shí)歸并到多個(gè)不同的組中;此外,當(dāng)如若目標(biāo)主機(jī)使用了非默認(rèn)的SSH端口,還可以在主機(jī)名稱之后使用冒號(hào)加端口號(hào)來標(biāo)明。
如果主機(jī)名稱遵循相似的命名模式,還可以使用列表的方式標(biāo)識(shí)各主機(jī),例如:
主機(jī)變量
可以在inventory中定義主機(jī)時(shí)為其添加主機(jī)變量以便于在playbook中使用。例如:
組變量組變量是指賦予給指定組內(nèi)所有主機(jī)上的在playbook中可用的變量。例如:
組嵌套 inventory中,組還可以包含其它的組,并且也可以向組中的主機(jī)指定變量。不過,這些變量只能在ansible-playbook中使用,而ansible不支持。例如:
inventory參數(shù) ansible基于ssh連接inventory中指定的遠(yuǎn)程主機(jī)時(shí),還可以通過參數(shù)指定其交互方式;
常用的參數(shù)如下所示:
ansible的循環(huán)機(jī)制還有更多的高級(jí)功能,你可以進(jìn)行一下嘗試。
playbooks
playbook是由一個(gè)或多個(gè)“play”組成的列表。
play的主要功能在于將事先歸并為一組的主機(jī)裝扮成事先通過ansible中的task定義好的角色。
從根本上來講,所謂task無非是調(diào)用ansible的一個(gè)module。
將多個(gè)play組織在一個(gè)playbook中,即可以讓它們聯(lián)同起來按事先編排的機(jī)制同唱一臺(tái)大戲。
playbook基礎(chǔ)組件
1、Hosts和Users
playbook中的每一個(gè)play的目的都是為了讓某個(gè)或某些主機(jī)以某個(gè)指定的用戶身份執(zhí)行任務(wù)。
hosts用于指定要執(zhí)行指定任務(wù)的主機(jī),其可以是一個(gè)或多個(gè)由冒號(hào)分隔主機(jī)組。
remote_user則用于指定遠(yuǎn)程主機(jī)上的執(zhí)行任務(wù)的用戶。 不過,remote_user也可用于各task中。也可以通過指定其通過sudo的方式在遠(yuǎn)程主機(jī)上執(zhí)行任務(wù),其可用于play全局或某任務(wù)。此外,甚至可以在sudo時(shí)使用sudo_user指定sudo時(shí)切換的用戶。
2、任務(wù)列表和action
play的主體部分是task list。
task list中的各任務(wù)按次序逐個(gè)在hosts中指定的所有主機(jī)上執(zhí)行,即在所有主機(jī)上完成***個(gè)任務(wù)后再開始第二個(gè)。
在運(yùn)行自下而下某playbook時(shí),如果中途發(fā)生錯(cuò)誤,所有已執(zhí)行任務(wù)都將回滾,因此,在更正playbook后重新執(zhí)行一次即可。
task的目的是使用指定的參數(shù)執(zhí)行模塊,而在模塊參數(shù)中可以使用變量。
模塊執(zhí)行是冪等的,這意味著多次執(zhí)行是安全的,因?yàn)槠浣Y(jié)果均一致。
每個(gè)task都應(yīng)該有其name,用于playbook的執(zhí)行結(jié)果輸出,建議其內(nèi)容盡可能清晰地描述任務(wù)執(zhí)行步驟。如果未提供name,則action的結(jié)果將用于輸出。
定義task的可以使用“action: module options”或“module: options”的格式,推薦使用后者以實(shí)現(xiàn)向后兼容。如果action一行的內(nèi)容過多,也中使用在行首使用幾個(gè)空白字符進(jìn)行換行。
在眾多模塊中,只有command和shell模塊僅需要給定一個(gè)列表而無需使用“key=value”格式,例如:
如果命令或腳本的退出碼不為零,可以使用如下方式替代:
或者使用ignore_errors來忽略錯(cuò)誤信息:
3、handlers
用于當(dāng)關(guān)注的資源發(fā)生變化時(shí)采取一定的操作。
“notify”這個(gè)action可用于在每個(gè)play的***被觸發(fā),這樣可以避免多次有改變發(fā)生時(shí)每次都執(zhí)行指定的操作,取而代之,僅在所有的變化發(fā)生完成后一次性地執(zhí)行指定操作。
在notify中列出的操作稱為handler,也即notify中調(diào)用handler中定義的操作。
handler是task列表,這些task與前述的task并沒有本質(zhì)上的不同。
tags
tags用于讓用戶選擇運(yùn)行或路過playbook中的部分代碼。ansible具有冪等性,因此會(huì)自動(dòng)跳過沒有變化的部分,即便如此,有些代碼為測(cè)試其確實(shí)沒有發(fā)生變化的時(shí)間依然會(huì)非常地長。
此時(shí),如果確信其沒有變化,就可以通過tags跳過此些代碼片斷。
示例:基于playbooks實(shí)現(xiàn)web服務(wù)的部署
1、提供好Inventory文件
2、編輯 palybooks 劇本
3、準(zhǔn)備好配置文件 將web的配置放到指定目錄 src=/root/httpd.conf4、開始部署
結(jié)果示例:
查看端口:

此時(shí)如果配置文件發(fā)生變化:
至此基本使用配置完成。