ansible自動運維工具之ansible-playbook詳解

一、Playbook簡介

playbook配置文件使用YAML語法,具有簡潔明瞭、結構清晰等特點。playbook配置文件類似於shell腳本,是一個YAML格式的文件,用於保存針對特定需求的任務列表。上面介紹的ansible命令雖然可以完成各種任務,但是當配置一些複雜任務時,逐條輸入就顯得效率非常低下了。更有效的方案是在playbook配置文件中放置所有的任務代碼,利用ansible-playbook命令執行該文件,可以實現自動化運維。YAML文件的擴展名通常爲.yaml或.yml。

二、playbook的核心元素

playbook的核心元素包含:

  • hosts:任務的目標主機,多個主機用冒號分隔,一般調用/etc/ansible/hosts中的分組信息。
  • remote_user:遠程主機上,運行此任務的默認身份爲root。
  • tasks:任務,即定義的具體任務,由模塊定義的操作列表。
  • handlers:觸發器,類似tasks,只是在特定的條件下才會觸發的任務。某任務的狀態在運行後爲changed時,可通過“notify”通知給相應的handlers進行觸發執行。
  • roles:角色,將hosts剝離出去,由tasks、handlers等所組成的一種特定的結構集合。

三、playbook格式

playbook需要注意的事項:

  • playbook由YMAL語言編寫。YAML參考了其他多種語言,包括:XML、C語言、Python、Perl等。MAL格式是類似於JSON的文件格式,便於人理解和閱讀,同時便於書寫。
  • 通過“-”來代表項,通過冒號 “ :”來分隔鍵和值,整個文件以“---”開始並以“...”結束。
  • 所有的“-”和“ : ”後面均由空格,而且要嚴格注意縮進和對齊,否則語法可能能會報錯。
  • 每次在執行playbook文件之前,一定要使用“-C”選項來進行預測試。該選項會執行一遍playbook文件,但不會對目標主機進行任何更改,若語法有錯或目標主機缺少某個文件,都將報錯提示。

1、執行簡單的playbook文件:

[root@ansible ~]# grep -v ^# /etc/ansible/hosts | grep -v ^$              #查看hosts中的分組信息
[web1]
192.168.1.2
[web2]
192.168.1.3
[root@ansible ~]# vim /etc/ansible/a.yml        #創建a.yml文件,寫入以下內容
---
- hosts: web1                   #針對web1組中的操作
  remote_user: root                    #遠端執行用戶身份爲root
  tasks:                #任務列表
        - name: adduser                                          #任務名稱
          user: name=user1 state=present          #執行user模塊,創建用戶
          tags:                 #創建tag標籤
          - aaa                   #tag標籤爲aaa
        - name: addgroup             #任務名稱
          group: name=root system=yes           #執行group模塊,創建組
          tags:                  #創建tag標籤
          - bbb                   #tag標籤爲bbb
- hosts: web2                  #針對web2組中的操作
  remote_user: root              #遠端執行用戶身份爲root
  tasks:                      #任務列表
        - name: copy file to web                #任務名稱
          copy: src=/etc/passwd dest=/home            #執行copy模塊,複製文件
          tags:                        #創建tag標籤
          - ccc                      #tag標籤爲ccc
...

我這裏編寫的playbook文件如下:
ansible自動運維工具之ansible-playbook詳解
playbook文件定義的任務需要通過ansible-playbook命令進行調用並執行,ansible-playbook命令用法如下:

[root@ansible ~]# ansible-playbook  [ option ]/etc/ansible/a.yml
其中option中的功能包括:
* --syntax-check:檢測yaml文件的語法。
* -C:預測試,不會改變目標主機的任何設置。
* --list-tasks:列出yaml文件的任務列表。
* --list-hosts:列出yaml文件影響的主機列表。
* --list-tags:列出yaml文件中的標籤。
* -t TAGS:表示只執行指定標籤的任務。
* --skip-tags=SKIP_TAGS:表示出了指定標籤的任務,執行其他任務。
* --start-at-task=START_AT:從指定任務開始往下運行。

執行a.yml文件的示例如下:

[root@ansible ~]# ansible-playbook --syntax-check /etc/ansible/a.yml    #語法檢測

playbook: /etc/ansible/a.yml       #表示沒有報錯
[root@ansible ~]# ansible-playbook -C /etc/ansible/a.yml         #對a.yml進行預測試
                                  .................#省略部分內容
192.168.1.2       : ok=3    changed=1    unreachable=0    failed=0   
192.168.1.3       : ok=2    changed=1    unreachable=0    failed=0   
#返回結果表示沒有錯誤,全部可以執行成功。
[root@ansible ~]# ansible-playbook --list-hosts /etc/ansible/a.yml    #列出a.yml文件中的主機
[root@ansible ~]# ansible-playbook --list-tasks /etc/ansible/a.yml       #列出任務
[root@ansible ~]# ansible-playbook --list-tags /etc/ansible/a.yml            #列出標籤
[root@ansible ~]# ansible-playbook /etc/ansible/a.yml                #執行任務
[root@ansible ~]# ssh 192.168.1.2 tail -1 /etc/passwd              #確認執行結果
user1:x:1001:1001::/home/user1:/bin/bash
[root@ansible ~]# ssh 192.168.1.3 ls -ld /home/passwd
-rw-r--r--. 1 root root 2342 7月  23 16:06 /home/passwd
#一般情況先執行“-C”命令進行預測試,沒有問題後再執行.yml文件。

有一個在線的ansible-playbook語法檢測工具,可以更直觀的檢查出語法中的錯誤,感興趣可以看一下:http://www.yamllint.com/
2、觸發器

需要觸發才能執行的任務,當之前在tasks中的任務執行成功後,若希望在此基礎上觸發其他任務,這就需要定義handlers。例如,當通過ansible的模塊對目標主機的配置文件進行修改之後,如果任務執行成功,可以觸發一個觸發器,在觸發器中定義目標主機的服務重啓操作,以便配置文件生效。handlers觸發器具有如下特點:

  • handlers是ansible提供的條件機制之一。handlers和task很類似,但是它只在被task通知的時候纔會觸發執行。
  • handlers只會在所有任務執行完成後執行。而且即使被通知了很多次,它也只會執行一次。

handlers觸發器的使用示例如下:

[root@ansible ~]# ssh 192.168.1.2 netstat -anpt | grep 80                  #查詢1.2主機監聽的端口
tcp6       0      0 :::80         :::*          LISTEN      94858/httpd 
#可以看到是監聽80端口,現在通過腳本改爲8080端口,並使其生效。
[root@ansible ~]# vim /etc/ansible/httpd.yml          #編輯httpd.yml文件,寫入以下內容

---
- hosts: web1
  remote_user: root
  tasks:
        - name: change port
          command: sed -i 's/Listen\ 80/Listen\ 8080/g' /etc/httpd/conf/httpd.conf
          notify:                                        #配置觸發條件
                - restart httpd server     #完成該任務後調用名爲“restart httpd server”的觸發器
  handlers:                                          #配置觸發器
        - name: restart httpd server  #指定觸發器名字,要和上面“notify”指定的觸發器名字一樣
          service: name=httpd state=restarted           #觸發任務爲重啓httpd服務。
...
#編寫完成後,保存退出即可。
[root@ansible ~]# ansible-playbook -C /etc/ansible/httpd.yml           #進行預測試。
[root@ansible ~]# ansible-playbook  /etc/ansible/httpd.yml               #執行腳本。
[root@ansible ~]# ssh 192.168.1.2 netstat -anpt | grep 8080        #遠端主機已經運行8080端口
tcp6       0      0 :::8080        :::*         LISTEN      103594/httpd

3、角色

將多種不同的tasks的文件集中存儲在某個目錄下,則該目錄就是角色。角色一般存放在/etc/ansible/roles/目錄下,可通過ansible的配置文件來調整默認的角色目錄,/etc/ansible/roles/目錄下有很多子目錄,其中每一個子目錄對應一個角色,每個角色也有自己的目錄結構,結構如下:
ansible自動運維工具之ansible-playbook詳解

/etc/ansible/roles/爲角色集合,該目錄下有自定義的各個子目錄:

  • mariadb:mysql角色。
  • Apache:httpd角色。
  • Nginx:Nginx角色。
  • 每個角色的定義,以特定的層級目錄結構進行組織。以mariadb(mysql角色)爲例:
  • files:存放由copy或script等模塊調用的文件。
  • templates:存放template模塊查找所需要的模板文件的目錄,如mysql配置文件模板。
  • tasks:任務存放的目錄。
  • handlers:存放相關觸發執行的目錄。
  • vars:變量存放的目錄。
  • meta:用於存放此角色元數據。
  • default:默認變量存放的目錄,文件中定義了此角色使用的默認變量。

上面的目錄中,tasks、handlers、vars、meta、default至少應該包含一個main.yml文件,該目錄下也可以有其他.yml文件,但是需要在main.yml文件中用include指令將其他.yml文件包含進來。
.
有了角色後,可以直接在yaml文件(playbook配置文件)中調用角色,示例如下:

---
- hosts: web1
  remote_user: root
  roles:            
  - mysql        #調用角色名
  - httpd             #調用角色名
...

可以只調用一個角色,也可以調用多個角色,當定義了角色後,用ansible-playbook PALYBOOK文件執行即可。此時ansible會到角色集合的目錄(/etc/ansible/roles)去找mysql和httpd目錄,然後依次運行mysql和httpd目錄下的所有代碼。
.
下面來個安裝及配置mariadb數據庫的實例:

需求分析:

  • 要求被管理主機上自動安裝mariadb,安裝完成後上傳提前準備好的配置文件至遠端主機,重啓服務,然後新建testdb數據庫,並允許test用戶對其擁有所有權限。
  • 被管理主機配置yum倉庫,自行配置,若被管理端可以連接互聯網,那麼直接將yum倉庫指向互聯網即可。

開始在ansible服務器上實施:

[root@ansible /]# mkdir -pv /etc/ansible/roles/mariadb/{files,tasks,handlers}
mkdir: 已創建目錄 "/etc/ansible/roles/mariadb"
mkdir: 已創建目錄 "/etc/ansible/roles/mariadb/files"
mkdir: 已創建目錄 "/etc/ansible/roles/mariadb/tasks"
mkdir: 已創建目錄 "/etc/ansible/roles/mariadb/handlers"
[root@ansible /]# cd /etc/ansible/roles/mariadb/tasks/       #切換至指定目錄
[root@ansible tasks]# ls
[root@ansible tasks]# vim main.yml                     #編寫main.yml文件
---
- name: install mariadb
  yum: name=mariadb-server state=present
- name: move config file
  shell: "[ -e /etc/my.cnf ] && mv /etc/my.cnf /etc/my.cnf.bak"
- name: provide a new config file
  copy: src=my.cnf dest=/etc/my.cnf
- name: reload mariadb
  shell: systemctl restart mariadb
- name: create database testdb
  shell: mysql -u root -e "create database testdb;grant all on testdb.* to 'test'@'192.168.1.%' identified by 'test123';flush privileges;"
  notify:
  - restart mariadb
...
#編寫完畢,保存退出即可。
[root@ansible tasks]# cd ../handlers/            #切換至觸發器目錄
[root@ansible handlers]# vim main.yml              #編寫main.yml文件,寫入以下內容
---
- name: restart mariadb
  service: name=mariadb state=restarted
...
#編寫完畢,保存退出即可。
[root@ansible handlers]# cd ../files     #進入mariadb角色文件夾的files
[root@ansible files]# pwd
/etc/ansible/roles/mariadb/files
[root@ansible files]# ls            #準備好配置好的mysql數據庫配置文件,需要分發到遠程主機的
my.cnf
[root@ansible files]# cd /etc/ansible/
[root@ansible ansible]# vim mariadb.yml         #編寫.yml文件
---
- hosts: web
  remote_user: root
  roles:
  - mariadb
...
##編寫完畢,保存退出即可。
[root@ansible ansible]# ansible-playbook -C mariadb.yml          #進行預檢測
                                  ........................          #省略部分內容
PLAY RECAP ***************************************************************************
192.168.1.2                : ok=3    changed=1    unreachable=0    failed=0 
#返回結果表示沒問題
[root@ansible ansible]# ansible-playbook mariadb.yml           #執行安裝

待安裝完成後,在遠端主機上查看是否已經創建了testdb數據庫,並測試以test用戶登錄,自行測試吧。

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