天天看點

Ansible 之 playbook使用

1  概述

Playbook組織格式是YAML格式,編排的是任務(task),用來記錄重複執行的指令  

YAML:YAML(/ˈjæməl/,尾音類似camel駱駝)是一個可讀性高,用來表達資料序列的格式。YAML參考了其他多種語言,包括:C語言、Python、Perl,并從XML、電子郵件的資料格式(RFC 2822)中獲得靈感。Clark Evans在2001年首次發表了這種語言,另外Ingy döt Net與Oren Ben-Kiki也是這語言的共同設計者。目前已經有數種程式設計語言或腳本語言支援(或者說解析)這種語言。

YAML是"YAML Ain't a Markup Language"(YAML不是一種标記語言)的遞歸縮寫。在開發的這種語言時,YAML 的意思其實是:"Yet Another Markup Language"(仍是一種标記語言),但為了強調這種語言以資料做為中心,而不是以标記語言為重點,而用反向縮略語重命名。  

YAML的文法和其他進階語言類似,并且可以簡單表達清單、散清單,标量等資料形态。它使用空白符号縮進和大量依賴外觀的特色,特别适合用來表達或編輯資料結構、各種配置檔案、傾印除錯内容、檔案大綱(例如:許多電子郵件标題格式和YAML非常接近)。

基本資料結構:

    标量、數組、關聯數組

表量:直接值

數組:用花括号組成的鍵值對

2  playbook的基礎元件

1)Hosts:運作指定任務的目标主機;

2)remoute_user: 在遠端主機上執行任務的使用者;

    sudo_user:

3)tasks:任務清單

    子產品,子產品參數;

    格式:

        (1) action: module arguments

        (2) module: arguments

        注意:shell和command子產品後面直接跟指令,而非key=value類的參數清單;

        (1) 某任務的狀态在運作後為changed時,可通過“notify”通知給相應的handlers;

         (2) 任務可以通過"tags“打标簽,而後可在ansible-playbook指令上使用-t指定進行調用;

4)handlers:

     任務,在特定條件下觸發;

     接收到其它任務的通知時被觸發;

         notify: HANDLER TASK NAME

5)variables:

    (1) facts:可直接調用;

        注意:可使用setup子產品直接擷取目标主機的facters;

例子

收集172.18.50.72内置變量,通過setup子產品實作收集主機的變量

ansible 172.18.50.72 -m setup

    (2) 使用者自定義變量:

     兩種設定的方式

         (a) ansible-playbook指令的指令行中的,-e可以重複使用

-e VARS, --extra-vars=VARS

         (b) 在playbook中定義變量的方法:

             vars:

             - var1: value1

             - var2: value2

變量引用:{{ variable }},變量兩側有空格

(3) 通過roles傳遞變量;

    (4) Host Inventory

         (a) 使用者自定義變量

(i) 向不同的主機傳遞不同的變量;

IP/HOSTNAME  varaiable=value var2=value2

(ii) 向組中的主機傳遞相同的變量;

[groupname:vars]

variable=value

(b) invertory參數

用于定義ansible遠端連接配接目标主機時使用的參數,而非傳遞給playbook的變量;

ansible_ssh_host

ansible_ssh_port

ansible_ssh_user

ansible_ssh_pass

3  運作playbook的方式

(1) 測試

ansible-playbook  --check

隻檢測可能會發生的改變,但不真正執行操作;

ansible-playbook  --list-hosts

ansible-playbook --list-hosts installpkg.yml 

列出運作任務的主機;

ansible-playbook  --syntax-check

檢查文法,沒有輸出表示沒有文法錯誤

ansible-playbook  --syntax-check installpkg.yml

(2) 運作

ansible-playbook  腳本

例子:

ansible-playbook  installpkg.yml      

4  例子

例一:編寫一個yaml文檔,用來安裝redis和ngnix服務,并啟動相關服務

注意,文法裡有橫線用來引導,區分不同的功能的語句,如下面語句有多個hosts,是以在hosts前加橫杆,tasks有多個,用橫杆區分每個tasks,而且縮進是有要求的,同一層級,一般縮進一樣。注意橫杆和冒号後有空格。

vim installpkg.yaml
- hosts: websrvs
  remote_user: root
  tasks:
  - name: install nginx package
    yum: name=nginx state=latest
  - name: start nginx service
    service: name=nginx enabled=true state=started
- hosts: dbsrvs
  remote_user: root
  tasks:
  - name: install redis package
    yum: name=redis state=latest
  - name: install conf file
    copy: src=/root/redis.conf dest=/etc/redis.conf owner=redis group=root mode=644
  - name: start redis service
    service: name=redis state=started      

準備redis的配置模闆

更改redis配置模闆監聽端口為0.0.0.0 和 端口為6380

vim  redis.conf
vim /root/redis.conf
bind 0.0.0.0
port 6380      

檢視playbook裡的主機

ansible-playbook --list-hosts installpkg.yml      

檢視playbook裡的tasks

ansible-playbook --list-tasks installpkg.yml      

測試執行腳本,添加選項-C,并沒有實際執行

ansible-playbook -C installpkg.yml      

以上腳本,測試正常的話,就去掉-C選項,實際執行

ansible-playbook  installpkg.yml      

例二:handler的使用

條件式觸發:handler,滿足條件的時候觸發條件

handlers:處理器,配置檔案被修改的時候才執行,條件定義在notify

以下指令,表示當配置檔案被更改的時候,notify就會觸發handler,實作重新開機的操作.注意格式的書寫。

vim  /root/ansible/handler.yml
- hosts: websrvs
  remote_user: root
  tasks:
  - name: install nginx package
    yum: name=nginx state=latest
  - name: start nginx service
    service: name=nginx enabled=true state=started
- hosts: dbsrvs
  remote_user: root
  tasks:
  - name: install redis package
    yum: name=redis state=latest
  - name: install conf file
    copy: src=/root/redis.conf dest=/etc/redis.conf owner=redis group=root mode=644
    tags: instconf
    notify: restart redis service
  - name: start redis service
    service: name=redis state=started
  handlers: 
  - name: restart redis service
    service: name=redis state=restarted      

例三:tag的使用

更改websrvs的配置内容,設定tag為instnginx

vim  /root/ansible/installpkg.yml
- hosts: websrvs
  remote_user: root
  tasks:
  - name: install nginx package
    yum: name=nginx state=latest
    tags: instnginx
  - name: start nginx service
    service: name=nginx enabled=true state=started
- hosts: dbsrvs
  remote_user: root
  tasks:
  - name: install redis package
    yum: name=redis state=latest
  - name: install conf file
    copy: src=/root/redis.conf dest=/etc/redis.conf owner=redis group=root mode=644
    tags: instconf
    notify: restart redis service
  - name: start redis service
    service: name=redis state=started
  handlers: 
  - name: restart redis service
    service: name=redis state=restarted      

檢視任務,會顯示對應的标簽

ansible-playbook --list-tasks installpkg.yml      

指定标簽,可以重新跑指定的标簽指令,如他部分的指令不執行,如這裡指定tag為instnginx,則隻安裝nginx包,但是不啟動服務,其他部分的指令不會執行

ansible-playbook -t instnginx installpkg.yml      

同時跑多個标簽,多個任務可以指定同一标簽,比較靈活 。如以下配置中,把安裝不同的服務包的tag都設定為instpkg,同時設定了 複制dbsrvs組的配置檔案,裝置複制檔案的tag為instconf,同時執行多個tag間用逗号隔開

vim  /root/ansible/installpkg.yml
- hosts: websrvs
  remote_user: root
  tasks:
  - name: install nginx package
    yum: name=nginx state=latest
    tags: instpkg
  - name: start nginx service
    service: name=nginx enabled=true state=started
- hosts: dbsrvs
  remote_user: root
  tasks:
  - name: install redis package
    yum: name=redis state=latest
    tags: instpkg
  - name: install conf file
    copy: src=/root/redis.conf dest=/etc/redis.conf owner=redis group=root mode=644
    tags: instconf
    notify: restart redis service
  - name: start redis service
    service: name=redis state=started
  handlers: 
  - name: restart redis service
    service: name=redis state=restarted      

執行如下

ansible-playbook -t instpkg,instconf installpkg.yaml      

結果是websrvs組隻安裝nginx,但是沒有啟動nginx服務,同時dbsrvs安裝了redis包而且複制了配置檔案到對應的主機,而且在install conf file任務中配置了notify任務,是以dbsrvs組的redis服務會被啟動

例四:變量的使用

通過變量pkgname安裝相關的包

vim installvar.yml 
- hosts: websrvs
  remote_user: root
  vars:
  - pkgname: tree
  tasks:
  - name: install package
    yum: name={{ pkgname }} state=latest      

運作腳本,不指定變量預設是安裝tree

ansible-playbook  installvar.yml      

指定變量,playbook指令行裡定義的變量優先級比腳本裡高,  這裡會安裝memcached,而不是腳本裡的tree

ansible-playbook -e "pkgname=memcached"  installvar.yaml      

直接在host裡定義變量,但是這個變量級别很低,比腳本裡的變量還低

vim /etc/ansible/hosts 
[websrvs]
172.18.50.72 pkgname=redis
172.18.50.75 pkgname=memcached      
vim /root/ansible/installvar.yml 
- hosts: websrvs
  remote_user: root
  vars:
  - pkgname: tree
  tasks:
  - name: install package
    yum: name={{ pkgname }} state=latest      

執行指令

ansible-playbook  installvar.yaml      

則websrvs安裝的服務包是tree,而不是/etc/ansible/hosts裡指派的變量

去掉腳本裡的變量

vim /root/ansible/installvar.yaml 
- hosts: websrvs
  remote_user: root
  tasks:
  - name: install package
    yum: name={{ pkgname }} state=latest      

重新執行

ansible-playbook  installvar.yml      
vim /etc/ansible/hosts
[websrvs]
172.18.50.72 pkgname=redis ansible_ssh_user=root ansible_ssh_pass=Pass123456
172.18.50.75 pkgname=memcached      

繼續閱讀