005.Ansible的palybook簡單使用


一 Ansible Playbook簡介

ansbile-playbook是一系列ansible命令的集合,利用yaml 語言編寫。playbook命令根據自上而下的順序依次執行。同時,playbook開創了很多特性,它可以允許你傳輸某個命令的狀態到后面的指令,如你可以從一台機器的文件中抓取內容並附為變量,然后在另一台機器中使用,這使得你可以實現一些復雜的部署機制,這是ansible命令無法實現的。

playbook通過ansible-playbook命令使用,它的參數和ansible命令類似,如參數-k(–ask-pass) 和 -K (–ask-sudo) 來詢問ssh密碼和sudo密碼,-u指定用戶,這些指令也可以通過規定的單元寫在playbook 。
ansible-playbook的簡單使用方法: ansible-playbook example-play.yml 。

二 Playbook基本語法

下面是一個簡單的ansible-playbook示例,可以了解其構成:

# cat user.yml
- name: create user
  hosts: all
  remote_user: root
  gather_facts: false
  vars:
    user:"test"
  tasks:
    - name: create  user
      user: name="{{ user }}"

配置項說明:

  • name:對該playbook實現的功能做一個概述,后面執行過程中,會打印 name變量的值
  • hosts:指定對哪些被管理機進行操作;
  • remote_user:指定在遠程被管理機上執行操作時使用什么用戶,如不指定,則使用ansible.cfg中配置的remote_user
  • gather_facts:指定在執行任務之前,是否先執行setup模塊獲取主機相關信息,如未用到,可不指定
  • vars:定義后續任務中會使用到的變量,如未用到,可不指定
  • tasks:定義具體需要執行的任務name:對任務的描述,在執行過程中會打印出來。
  • user:指定調用user模塊;
  • name:user模塊里的一個參數,用於指定創建的用戶名稱

同樣,如果想實現把這個新增的用戶刪除,只需將該playbook文件的最后一行替換為如下行再執行相應的playbook即可:

user: name="{{ user }}" state=absent remove=yes

三 playbook組成

3.1 palybook簡單演示

- name: configure nginx
  hosts: 192.168.132.133
  tasks:
    - name: install epel-release
      package: 
        name: epel-release 
        state: present
    - name: install nginx
      package: 
        name: nginx 
        state: present
    - name: create directory
      file: 
        path: ./file 
        state: directory 
        owner: nginx 
        group: nginx
    - name: copy file from remote serevr
      fetch: 
        src: /usr/share/nginx/html/index.html 
        dest: file/
    - name: delete file of remote server
      file: 
        path: /usr/share/nginx/html/index.html 
        state: absent
    - name: create a remote server file
      file: 
        path: /usr/share/nginx/html/index.html  
        state: touch  
        owner: nginx 
        group: nginx
    - name: content
      copy: 
        content: "<h3>welcome ansible</h3>"  
        dest: /usr/share/nginx/html/index.html
    - name: start service
      systemd: 
        name: nginx 
        state: started 
        enabled: yes 
        daemon_reload: yes

[root@node1 ansible]# ansible-playbook nginx_config.yml

PLAY [configure nginx] ************************************************************************************************************************
TASK [Gathering Facts] ************************************************************************************************************************
ok: [192.168.132.133]
TASK [install epel-release] *******************************************************************************************************************
changed: [192.168.132.133]
TASK [install nginx] **************************************************************************************************************************
changed: [192.168.132.133]
TASK [create directory] ***********************************************************************************************************************
ok: [192.168.132.133]
TASK [copy file from remote serevr] ***********************************************************************************************************
changed: [192.168.132.133]
TASK [delete file of remote server] ***********************************************************************************************************
changed: [192.168.132.133]
TASK [create a remote server file] ************************************************************************************************************
changed: [192.168.132.133]
TASK [content] ********************************************************************************************************************************
changed: [192.168.132.133]
TASK [start service] **************************************************************************************************************************
changed: [192.168.132.133]
PLAY RECAP ************************************************************************************************************************************
192.168.132.133            : ok=9    changed=7    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

查看192.168.132.133

[root@node3 ~]# rpm -qa |grep epel-release
epel-release-7-11.noarch
[root@node3 ~]# rpm -qa |grep  nginx
nginx-mod-http-xslt-filter-1.16.1-1.el7.x86_64
nginx-all-modules-1.16.1-1.el7.noarch
nginx-mod-mail-1.16.1-1.el7.x86_64
nginx-mod-http-image-filter-1.16.1-1.el7.x86_64
nginx-mod-stream-1.16.1-1.el7.x86_64
nginx-filesystem-1.16.1-1.el7.noarch
nginx-mod-http-perl-1.16.1-1.el7.x86_64
nginx-1.16.1-1.el7.x86_64
[root@node3 ~]# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2020-04-29 14:06:10 CST; 2min 25s ago
[root@node3 ~]# systemctl is-enabled nginx
enabled

訪問

 

3.2 yml規則

yml文件它的基本語法規則如下。

  • 大小寫敏感
  • 使用縮進表示層級關系
  • 縮進時不允許使用Tab鍵,只允許使用空格。
  • 縮進的空格數目不重要,只要相同層級的元素左側對齊即可

# 表示注釋,從這個字符一直到行尾,都會被解析器忽略。

YAML 支持的數據結構有三種。

  • 對象:鍵值對的集合,又稱為映射(mapping)/ 哈希(hashes) / 字典(dictionary)
  • 數組:一組按次序排列的值,又稱為序列(sequence) / 列表(list)
  • 純量(scalars):單個的、不可再分的值

ansible-playbook常用選項

3.3 ansible其他用法

1 打印詳細信息

  • -v:打印任務運行結果
  • -vv:打印任務運行結果以及任務的配置信息
  • -vvv:包含了遠程連接的一些信息
  • -vvvv:Adds extra verbosity options to the connection plug-ins,including the users being used in the managed hosts to execute scripts, and what scripts have been executed

 [root@node1 ansible]# ansible-playbook nginx_config.yml -v

2. 校驗playbook語法

[root@node1 ansible]# ansible-playbook nginx_config.yml --syntax-check

playbook: nginx_config.yml

3. 測試運行playbook

通過-C選項可以測試playbook的執行情況,但不會真的執行:

 [root@node1 ansible]# ansible-playbook -C nginx_config.yml

4 Multiple Plays

# This is a simple playbook with two plays

- name: first play
  hosts: web.example.com
  tasks:
    - name: first task
      yum:
        name: httpd
        status: present
    - name: second task
      service:
        name: httpd
        state: started
    
- name: second play
  hosts: db.example.com
  tasks:
    - name: first task
      yum:
        name: mariadb-server
        status: present
    - name: second task
      service:
        name: mariadb
        state: started

四 playbook的結構說明

playbook是由一個或多個"play"組成的列表。play的主要功能就是對一組主機應用play中定義好的task。從根本上來講一個task就是對ansible一個module的調用。而將多個play按照一定的順序組織到一個playbook中,我們稱之為編排。

playbook主要有以下四部分構成:

  • Target section: 用於定義將要執行playbook的遠程主機組及遠程主機組上的用戶,還包括定義通過什么樣的方式連接遠程主機(默認ssh)
  • Variable section: 定義playbook運行時需要使用的變量
  • Task section: 定義將要在遠程主機上執行的任務列表
  • Handler section: 定義task執行完成以后需要調用的任務

4.1 Target section

playbook中的每一個play的目的都是為了讓某個或某些主機以某個指定的用戶身份執行任務。

Playbook中的遠程用戶

playbook中的遠程用戶和ad-hoc中的使用沒有區別,默認不定義,則直接使用ansible.cfg配置中的用戶相關的配置。也可在playbook中定義如下:

- name: /etc/hosts is up to date
  hosts: datacenter
  remote_user: automation
  become: yes
  become_mothod: sudo
  become_user: root
  
  tasks:
    - name: server.example.com in /etc/hosts
      lineinfile:
        path: /etc/hosts
        line: '192.168.0.200 server.exmaple.com server'
        state: present

Playbook中的hosts

playbook中的hosts即inentory中的定義主機與主機組,在《Ansible Inventory》中我們講到了如何選擇主機與主機組,在這里也完全適用。

4.2 Variable section

定義playbook運行時需要使用的變量

- name : test vars
  hosts: node2
  remote_user: ansible
  become_user: root
  become_method: sudo

  vars:
    user:
      name: "user1"
      address: "IPaddr"
  tasks:
    - name: "print"
      debug:
        msg: "{{ user }}"

執行

PLAY [test vars] ******************************************************************************************************************************
TASK [Gathering Facts] ************************************************************************************************************************
ok: [node2]
TASK [print] **********************************************************************************************************************************
ok: [node2] => {
    "msg": {
        "address": "IPaddr", 
        "name": "user1"
    }
}
PLAY RECAP ************************************************************************************************************************************
node2                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

4.3 Task section

play的主體部分是任務列表。

任務列表中的各任務按次序逐個在hosts中指定的所有主機上執行,在所有主機上完成第一個任務后再開始第二個。在自上而下運行某playbook時,如果中途發生錯誤,則整個playbook會停止執行,由於playbook的冪等性,playbook可以被反復執行,所以即使發生了錯誤,在修復錯誤后,再執行一次即可。

定義task可以使用action: module optionsmodule: options的格式,推薦使用后者以實現向后兼容。

tasks:
  - name: make sure apache is running
    service: 
      name: httpd
      state: started
      
  - name: disable selinux
    command: /sbin/setenforce 0

如果命令或腳本的退出碼不為零可以使用如下方式替代:

tasks:
  - name: run this command and ignore the result
    shell: /usr/bin/somecommand || /bin/true

可以使用ignore_errors來忽略錯誤信息:

tasks:
  - name: run this command and ignore the result
    shell: /usr/bin/somecommand
    ignore_errors: True

4.4 Handler section

  • 在Ansible Playbook中,handler事實上也是個task,只不過這個task默認並不執行,只有在被觸發時才執行。

  • handler通過notify來監視某個或者某幾個task,一旦task執行結果發生變化,則觸發handler,執行相應操作。

  • handler會在所有的play都執行完畢之后才會執行,這樣可以避免當handler監視的多個task執行結果都發生了變化之后而導致handler的重復執行(handler只需要在最后執行一次即可)。

在notify中定義內容一定要和tasks中定義的 - name 內容一樣,這樣才能達到觸發的效果,否則會不生效。

- name: configure nginx
  hosts: 192.168.132.133
  tasks:
    - name: install epel-release
      package:
        name: epel-release
        state: present
    - name: install nginx
      package:
        name: nginx
        state: present
      notify: restart nginx - name: create directory
      file:
        path: ./file
        state: directory
        owner: nginx
        group: nginx
    - name: copy file from remote serevr
      fetch:
        src: /usr/share/nginx/html/index.html
        dest: file/
    - name: delete file of remote server
      file:
        path: /usr/share/nginx/html/index.html
        state: absent
    - name: create a remote server file
      file:
        path: /usr/share/nginx/html/index.html
        state: touch
        owner: nginx
        group: nginx
    - name: content
      copy:
        content: "<h3>welcome ansible</h3>"
        dest: /usr/share/nginx/html/index.html
    - name: start service
      systemd:
        name: nginx
        state: started
        enabled: yes
        daemon_reload: yes
  handlers:
    - name: restart nginx
      systemd:
        name: nginx
        daemon_reload: yes
        state: restarted

執行

PLAY [configure nginx] ************************************************************************************************************************
TASK [Gathering Facts] ************************************************************************************************************************
ok: [192.168.132.133]
TASK [install epel-release] *******************************************************************************************************************
ok: [192.168.132.133]
TASK [install nginx] **************************************************************************************************************************
ok: [192.168.132.133]
TASK [create directory] ***********************************************************************************************************************
ok: [192.168.132.133]
TASK [copy file from remote serevr] ***********************************************************************************************************
ok: [192.168.132.133]
TASK [delete file of remote server] ***********************************************************************************************************
changed: [192.168.132.133]
TASK [create a remote server file] ************************************************************************************************************
changed: [192.168.132.133]
TASK [content] ********************************************************************************************************************************
changed: [192.168.132.133]
TASK [start service] **************************************************************************************************************************
ok: [192.168.132.133]
PLAY RECAP ************************************************************************************************************************************
192.168.132.133            : ok=9    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

沒有觸發,試音並沒有change

- name: configure nginx
  hosts: 192.168.132.133
  tasks:
    - name: install epel-release
      package: 
        name: epel-release 
        state: present
    - name: install nginx
      package: 
        name: nginx 
        state: present
    - name: create directory
      file: 
        path: ./file 
        state: directory 
        owner: nginx 
        group: nginx
    - name: copy file from remote serevr
      fetch: 
        src: /usr/share/nginx/html/index.html 
        dest: file/
    - name: delete file of remote server
      file: 
        path: /usr/share/nginx/html/index.html 
        state: absent
      notify: restart nginx - name: create a remote server file
      file: 
        path: /usr/share/nginx/html/index.html  
        state: touch  
        owner: nginx 
        group: nginx
    - name: content
      copy: 
        content: "<h3>welcome ansible</h3>"  
        dest: /usr/share/nginx/html/index.html
    - name: start service
      systemd: 
        name: nginx 
        state: started 
        enabled: yes 
        daemon_reload: yes
  handlers: 
    - name: restart nginx
      systemd: 
        name: nginx
        daemon_reload: yes
        state: restarted  

執行

[root@node1 ansible]# ansible-playbook  nginx_config.yml 

PLAY [configure nginx] ************************************************************************************************************************
TASK [Gathering Facts] ************************************************************************************************************************
ok: [192.168.132.133]
TASK [install epel-release] *******************************************************************************************************************
ok: [192.168.132.133]
TASK [install nginx] **************************************************************************************************************************
ok: [192.168.132.133]
TASK [create directory] ***********************************************************************************************************************
ok: [192.168.132.133]
TASK [copy file from remote serevr] ***********************************************************************************************************
ok: [192.168.132.133]
TASK [delete file of remote server] *********************************************************************************************************** changed: [192.168.132.133]
TASK [create a remote server file] ************************************************************************************************************
changed: [192.168.132.133]
TASK [content] ********************************************************************************************************************************
changed: [192.168.132.133]
TASK [start service] **************************************************************************************************************************
ok: [192.168.132.133]
RUNNING HANDLER [restart nginx] *************************************************************************************************************** changed: [192.168.132.133]
PLAY RECAP ************************************************************************************************************************************
192.168.132.133            : ok=10   changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

觸發執行

一個任務可以觸發多個handlers

notify: 
  - restart nginx
  - restart redis

默認情況下,在一個play中,只要有task執行失敗,則play終止,即使是與handler關聯的task在失敗的task之前運行成功了,handler也不會被執行。如果希望在這種情況下handler仍然能夠執行,則需要使用如下配置:

- hosts: all
 force_handlers: yes
  tasks:
    - name: a task which always notifies its handler
      command: /bin/true
      notify: restart the database
    - name: a task which fails because the package doesn't exist
      yum:
        name: notapkg
        state: latest
      
  handlers:
    - name: restart the database
      service:
        name: mariadb

如果與handler關聯的task還未執行,在其前的task已經失敗,整個play終止,則handler未被觸發,也不會執行


博主聲明:本文的內容來源主要來自譽天教育晏威老師,由本人實驗完成操作驗證,需要的博友請聯系譽天教育(http://www.yutianedu.com/),獲得官方同意或者晏老師(https://www.cnblogs.com/breezey/)本人同意即可轉載,謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM