魏巍-Ansible系列課程-基礎(chǔ)入門-Playbook入門篇

Paste_Image.png
難度指數(shù): 4星(滿星5星)
技術(shù)指數(shù): 5星(滿星5星)
理論指數(shù): 4星(滿星5星)
面向人群: 自動(dòng)化運(yùn)維&運(yùn)維開發(fā)

1. Playbook簡介

像很多其它配置文件管理方法一樣,Ansible使用一種比較直白的方法來描述自己的任務(wù)配置文件。
Ansible 的任務(wù)配置文件被稱之為“playbook”,我們可以稱之為“劇本”。每一出劇本(playbook)中都包含一系列的任務(wù),這每個(gè)任務(wù)在ansible中又被稱為一出“戲劇”(play)。一個(gè)劇本(playbook)中包含多出戲?。╬lay),這很容易理解。

為了便于理解,再給大家舉個(gè)栗子~
NAB球隊(duì)教練手里都有一個(gè)叫戰(zhàn)術(shù)板的東西,每次暫停,主教練都會(huì)在戰(zhàn)術(shù)板上布置一系列戰(zhàn)術(shù)(playbook),球員在場上做出一系列的跑動(dòng)和相互掩護(hù)來完成這個(gè)戰(zhàn)術(shù),這其中每一個(gè)跑位和掩護(hù)就可以被稱之為“play”。

Paste_Image.png

在Ansible中,我們就充當(dāng)編劇的角色,親自編寫劇本(一系列的服務(wù)器操作),讓一出出精彩的戲?。╬lay)巧妙配合,完成對(duì)服務(wù)器的一系列精確控制。

1.1 Playbook語法簡介

Playbook采用一種可讀性很高的且容易被人類閱讀的語法的YAML語法編寫,YAML: "YAML Ain't a Markup Language"(YAML不是一種置標(biāo)語言)。該語言在被開發(fā)時(shí),YAML 的意思其實(shí)是:"Yet Another Markup Language"(仍是一種置標(biāo)語言),格式如下所示:

house:
  family:
    name: Doe
    parents:
      - John
      - Jane
    children:
      - Paul
      - Mark
      - Simone
  address:
    number: 34
    street: Main Street
    city: Nowheretown
  zipcode: 12345

1.2 YAML簡介

1.2.1 YAML特性

  • 1 YAML的可讀性好
  • 2 YAML和腳本語言的交互性好
  • 3 YAML使用實(shí)現(xiàn)語言的數(shù)據(jù)類型
  • 4 YAML有一個(gè)一致的信息模型
  • 5 YAML易于實(shí)現(xiàn)

1.2.2 YAML語法

  • 1 YAML使用可打印的Unicode字符,可使用UTF-8或UTF-16。
  • 2 使用空白字符未文件縮排來表示結(jié)構(gòu);不過不能使用跳格字符。
  • 3 注解由井字號(hào)( # )開始,可以出現(xiàn)在一行中的任何位置,而且范圍只有一行(也就是一般所謂的單行注解)
  • 4 每個(gè)清單成員以單行表示,并用短杠+空白( - )起始?;蚴褂梅嚼ㄌ?hào)( [ ] ),并用逗號(hào)+空白( , )分開成員。
  • 5 每個(gè)雜湊表的成員用冒號(hào)+空白( : )分開鍵值和內(nèi)容?;蚴褂么罄ㄌ?hào)( { } ),并用逗號(hào)+空白( , )分開。 雜湊表的鍵值可以用問號(hào) ( ? )起始,用來明確的表示多個(gè)詞匯組成的鍵值。
  • 6 字串平常并不使用引號(hào),但必要的時(shí)候可以用雙引號(hào) ( " )或單引號(hào) ( ' )框住。使用雙引號(hào)表示字串時(shí),可用倒斜線( \ )開始的跳脫字符(這跟C語言類似)表示特殊字符。
  • 7 區(qū)塊的字串用縮排和修飾詞(非必要)來和其他資料分隔,有新行保留(preserve)(使用符號(hào) | )或新行折疊(flod)(使用符號(hào) > )兩種方式。
  • 8 在單一檔案中,可用連續(xù)三個(gè)連字號(hào)(——)區(qū)分多個(gè)檔案。另外,還有選擇性的連續(xù)三個(gè)點(diǎn)號(hào)( ... )用來表示檔案結(jié)尾。
  • 9 重復(fù)的內(nèi)容可使從參考標(biāo)記星號(hào) ( * )復(fù)制到錨點(diǎn)標(biāo)記( & )。
  • 10 指定格式可以使用兩個(gè)驚嘆號(hào) ( !! ),后面接上名稱。
  • 11 檔案中的單一文件可以使用指導(dǎo)指令,使用方法是百分比符號(hào)( % )。有兩個(gè)指導(dǎo)指令

2. Playbook實(shí)戰(zhàn)

之前我們分享的Ansbile基礎(chǔ)模塊使用時(shí),那種Ad-hoc點(diǎn)對(duì)點(diǎn)的,一次執(zhí)行一個(gè)模塊的操作方式已經(jīng)使得Andsible一中非常強(qiáng)大的管理工具;但playbook將會(huì)使Ansible成為超一流的管理工具。

2.1 Shell腳本與Playbook的轉(zhuǎn)換

現(xiàn)在越來越多的DevOPS也開始將目光移向了Ansible,因?yàn)锳nsible可以輕松的將shell腳本或簡單的shell命令轉(zhuǎn)換為Ansible plays.

下面有一個(gè)安裝apache的shell腳本,大家來感受一下:

#!/bin/bash
# 安裝Apache
yum install --quiet -y httpd httpd-devel
# 復(fù)制配置文件
cp /path/to/config/httpd.conf /etc/httpd/conf/httpd.conf
cp /path/to/httpd-vhosts.conf /etc/httpd/conf/httpd-vhosts.conf
# 啟動(dòng)Apache,并設(shè)置開機(jī)啟動(dòng)
service httpd start
chkconfig httpd on

將其轉(zhuǎn)換為一個(gè)完整的playbook后:

---
- hosts: all

  tasks:
   - name: "安裝Apache"
     command: yum install --quiet -y httpd httpd-devel
   - name: "復(fù)制配置文件"
     command: cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
     command: cp /tmp/httpd-vhosts.conf /etc/httpd/conf/httpd-vhosts.conf
   - name: "啟動(dòng)Apache,并設(shè)置開機(jī)啟動(dòng)"
     command: service httpd start
     command: chkconfig httpd on
Paste_Image.png

將以上內(nèi)容放在一個(gè)名為playbook.yml的文件中,直接調(diào)用ansible-playbook命令,即可運(yùn)行,運(yùn)行結(jié)果和腳本運(yùn)行結(jié)果一致:

# ansible-playbook ./playbook.yml

也就是說,只要你有編寫shell腳本的基本能力,你就可以快速的學(xué)會(huì)利用playbook來發(fā)揮Ansible的強(qiáng)大威力。

在上述playbook中,我們使用了“command”模塊來運(yùn)行了標(biāo)準(zhǔn)的shell命令。我們還給了每一出play一個(gè)“name”,因此當(dāng)我們運(yùn)行playbook時(shí),每一個(gè)play都會(huì)有非常易讀的的信息輸出:

Paste_Image.png

上面的playbook已經(jīng)可以很好的運(yùn)行shell腳本了,但是Ansible還有很多其他內(nèi)置模塊,可以大幅提升處理復(fù)雜配置的能力。

---
- hosts: all
  sudo: yes

  tasks:
   - name: 安裝Apache
     yum: name={{ item }} state=present
     with_items:
     - httpd
     - httpd-devel
   - name: 復(fù)制配置文件
     copy:
       src: "{{ item.src }}"
       dest: "{{ item.dest }}"
       owner: root
       group: root
       mode: 0644
     with_items:
     - {
       src: "/tmp/httpd.conf",
         dest: "/etc/httpd/conf/httpd.conf" }
     - {
       src: "/tmp/httpd-vhosts.conf",
       dest: "/etc/httpd/conf/httpd-vhosts.conf"
       }
   - name: 檢查Apache運(yùn)行狀態(tài),并設(shè)置開機(jī)啟動(dòng)
     service: name=httpd state=started enabled=yes

運(yùn)行結(jié)果如下:

2.2 Playbook案例逐行剖析

現(xiàn)在我們已經(jīng)對(duì)playbook有了一個(gè)大概的了解,接一下,讓我們詳細(xì)解剖一下上面的playbook都做了是什么以及怎么工作的。

  • 1 第一行,“---”,這個(gè)是YAML語法中注釋的用法,就像shell腳本中的“#”號(hào)一樣
  • 2 第二行,“- hosts: all”,告訴ansible具體要在哪些主機(jī)上運(yùn)行我的劇本(playbook),在本例中是all,即所有主機(jī)
  • 3 第三行,“sudo: yes”,告訴ansible通過sudo來運(yùn)行相應(yīng)命令,這樣所有命令將會(huì)以root身份執(zhí)行
  • 4 第四行,“tasks:”,指定一系列將要運(yùn)行的任務(wù)
  • 每一個(gè)任務(wù)(play)以“- name: 安裝Apache”開頭。“- name:”字段并不是一個(gè)模塊,不會(huì)執(zhí)行任務(wù)實(shí)質(zhì)性的操作,它只是給“task” 一個(gè)易于識(shí)別和名稱。即便把name字段對(duì)應(yīng)的行完全刪除,也不會(huì)有任何問題。
  • 本例中我們使用yum模塊來安裝Apache,替代了“yum -y install httpd httpd-devel”
  • 在每一個(gè)play當(dāng)中,都可以例用 with_items 來定義變量,并通過“{{ 變量名 }}”的形式來直接使用使用yum模塊的state=present選項(xiàng)來確保軟件被安裝,或者使用state=absent來確保軟件被刪除
  • 第二個(gè)任務(wù)(play)同樣是“- name”字符開頭
  • 我們使用copy模塊來將“src”定義的源文件(必須是ansible所在服務(wù)器上的本地文件 )復(fù)制到“dest”定義的目的地址(此地址為遠(yuǎn)程主機(jī)的上地址)去,在傳遞文件的同時(shí),還定義了文件的屬主,屬組和權(quán)限
  • 這個(gè)play中,我們用數(shù)組的形式給變量賦值,使用{var1: value, var2: value} 的格式來賦值,變量的個(gè)數(shù)可以任意多,不同變量間以逗號(hào)分隔,使用{{item.var1 }}的形式來調(diào)用變量,本例中為:{{ item.src }}
    1. 第三個(gè)任務(wù)(play)使用了同樣的結(jié)構(gòu),調(diào)用了service模塊,以保證服務(wù)的正常開啟

2.3 Playbook與Shell腳本差異對(duì)比

當(dāng)我們把shell腳本轉(zhuǎn)換為playbook運(yùn)行的時(shí)候,ansible會(huì)留下清晰的執(zhí)行痕跡,明確告訴我們在每一臺(tái)主機(jī)上的每一步都做了什么。

更厲害的是,當(dāng)我們重復(fù)執(zhí)行一個(gè)playbook時(shí),當(dāng)ansible發(fā)現(xiàn)系統(tǒng)的現(xiàn)有狀態(tài)符合playbook所定義的狀態(tài)時(shí),anbile將自動(dòng)跳過該操作。

比如下圖,我們再次執(zhí)行playbook: temp.yml,當(dāng)ansible發(fā)現(xiàn)playbook中的play都已被完成,它將直接返回ok狀態(tài)碼,速度非常之快。
如果是shell腳本,肯定會(huì)硬著頭皮,把所用操作再做一遍。

Paste_Image.png

在正式運(yùn)行playbook之前,可以使用--check 或 -C 選項(xiàng)來檢測playbook都會(huì)改變哪些內(nèi)容,顯示的結(jié)果跟真正執(zhí)行時(shí)一模一樣,但不會(huì)真的對(duì)被管理的服務(wù)器產(chǎn)生影響

3. Ansible-playbook命令詳解

3.1 限定執(zhí)行范圍

--limit   

如果我們運(yùn)行上面的例子,會(huì)發(fā)現(xiàn)所有被ansible管理的主機(jī)都會(huì)被操作。
我們可以通過修改“- hosts:”字段來指定哪些主機(jī)將會(huì)應(yīng)用playbook的操作,

指定一臺(tái)主機(jī):www.magedu.com
指定多臺(tái)主機(jī):www.magedu.com,www.osstep.com
指定一組主機(jī):dbserver

當(dāng)然,也可以直接通過ansible-playbook命令來指定主機(jī):

# ansible-playbook playbook.yml --limit webservers

這樣以來(假設(shè)你的inventory文件中包含webserver組),即便playbook中設(shè)定“hosts: all”,但也僅對(duì)webserver組生效。

--list-hosts

如果想知道在執(zhí)行playbook時(shí),哪些主機(jī)將會(huì)受影響,則使用--list-hosts選項(xiàng):

# ansible-playbook playbook.yml --list-hosts

運(yùn)行結(jié)果:

Paste_Image.png

(由于用測試的被管理主機(jī)只有一臺(tái),所以count結(jié)果為1)

4. Ansible-playbook: 用戶與權(quán)限設(shè)置

--remote-user

Playbook中,如果在與hosts同組的字段中沒有定義user,那么Ansible將會(huì)使用你在inventory文件中定義的用戶,如里inventory文件中也沒定義用戶,Ansible將默認(rèn)使用當(dāng)前系統(tǒng)用戶身份來通過SSH連接遠(yuǎn)程主機(jī),在運(yùn)程程主機(jī)中運(yùn)行play內(nèi)容。

我們也可以直接在ansible-playbook中使用 --remote-user選項(xiàng)來指定用戶:

# ansible-playbook playbook.yml --remote-user=tom
--ask-sudo-pass

在某些情況下,我們需要傳遞sudo密碼到遠(yuǎn)程主機(jī),來保證sudo命令的正常運(yùn)行。這時(shí),可以使用--ask-sudo-pass (-K)選項(xiàng)來交互式的輸入密碼。

--sudo
使用--sudo選項(xiàng),可以強(qiáng)制所有play都使用sudo用戶,同時(shí)使用--sudo-user選項(xiàng)指定切換到具體哪個(gè)用戶,如果不指定,則默認(rèn)以root身份運(yùn)行。

比如,當(dāng)前用戶Tom想以Jerry的身份運(yùn)行playbook,命令如下:
$ ansible-playbook playbook.yml --sudo --sudo-user=jerry --ask-sudo-pass
執(zhí)行過程中,會(huì)要求用戶輸入Jerry的密碼。

  1. Ansible-playbook: 其它選項(xiàng)
    Ansible-playbook命令還有一些其他選項(xiàng):

--inventory=PATH (-i PATH):指定inventory文件,默認(rèn)文件是/etc/ansible/hosts
--verbose(-v):顯示詳細(xì)輸出,也可以使用-vvvv顯示精確到每分鐘的輸出
--extra-vars=VARS(-e VARS):定義在playbook使用的變量,格式為:"key=value,key=value"
--forks=NUM ( -f NUM):指定并發(fā)執(zhí)行的任務(wù)數(shù),默認(rèn)為5,根據(jù)服務(wù)器性能,調(diào)大這個(gè)值可提高ansible執(zhí)行效率
--connection=TYPE ( -c TYPE):指定連接遠(yuǎn)程主機(jī)的方式,默認(rèn)為ssh,設(shè)為local時(shí),剛只在本地執(zhí)行playbook,建議不做修改
--check:檢測模式,playbook中定義的所有任務(wù)將在每臺(tái)遠(yuǎn)程主機(jī)上進(jìn)行檢測,但并不直正執(zhí)行

以上這些參數(shù)即可滿足大部分的工作需求。

問題1:ansible-playbook 如何收集多臺(tái)服務(wù)器的信息,做統(tǒng)一的匯總report?

回問題1: ansible有一個(gè)模塊叫setup, 直接在命令行運(yùn)行:ansible all -m setup即可獲取所有主機(jī)的各種信息,當(dāng)然該模塊也可在playbook中使用

問題2: setup模塊收集到的各個(gè)機(jī)器的信息,是如何匯總到中控機(jī)的呢?

回問題2:這個(gè)問題涉及ansible工作原理,我還不曾讀過ansible源碼,但ansible默認(rèn)使用ssh方式來管理遠(yuǎn)程主機(jī),那么我想setup模塊收集到的各主機(jī)的信息,包括其他模塊也一樣,都就應(yīng)該是通過ssh的方式來進(jìn)行傳遞,但這只是我的一個(gè)推斷

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容