1. 程式人生 > >[自動化] Ansible之使用Playbooks詳解

[自動化] Ansible之使用Playbooks詳解

關系 cache 用戶 調用 註意事項 change 結構 man 安裝步驟

一、Playbook簡介

Playbook 是由一個或多個play組成的列表,主要功能是將task定義好的角色歸並為一組進行統一管理,也就是通過Ansible的模板將多個play組織在一個Playbook中運行。

二、playbook格式

playbook由YMAL語言編寫。YAML參考了其他多種語言,包括:XML、C語言、Python、Perl等。MAL格式是類似於JSON的文件格式,便於人理解和閱讀,同時便於書寫。以下為playbook常用到的YMAL格式。

  • YMAL中的列表元素以”-”開頭然後緊跟著一個空格,後面為元素內容。就像這樣- host。
  • 同一個列表中的元素應該保持相同的縮進。否則會被當做錯誤處理。
  • playbook中hosts,variables,roles,tasks等對象的表示方法都是鍵值中間以”:”分隔,”:”後面還要增加一個空格。
  • 劇本以.yml後綴

三、Playbook的核心元素

Playbook本身由以下各部分組成:
(1)Hosts:運行指定任務的目標主機;
(2)Tasks:任務,即調用模塊完成的操作;
(3)Variables:變量;
(4)Templates:模板;
(5)Handles:處理器,當某條件滿足時,觸發執行的操作;
(6)Roles:角色

四、任務列表的元素介紹

Play的主體是任務列表。任務列表中的任務依照次序逐個在hosts中指定的所有主機上執行,如果發生錯誤會將所有已執行任務回滾。

1.模塊、模塊參數格式

task的任務是按照指定的參數去執行模塊。

(1)action:moudle options

(2)moudle:options,其中後者可以實現向後兼容。

註意:在Ansible自帶模塊中,command模塊和shell模塊只需要一個列表定義即可,無需使用key=value格式。

2.Handles和tags的使用

Handlers用於當關註的資源發生變化時所采取的操作。使用tags讓用戶選擇跳過沒有變化的代碼,只運行Playbook中發生變化的部分代碼。

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

(2) 任務可以通過“tags“打標簽,通過 ansible-playbook命令 使用 --tags選項能實現僅運行指定的tasks。

示例:

vim /etc/ansible/nginx.yml

- hosts: nginx
  remote_user: root
  tasks:
    - name:yum install epel-release -y    #安裝epel源
      yum: name=epel-release state=latest
    - name: yum install nginx -y  #安裝nginx
      yum: name=nginx state=latest
    - name: copy nginx.conf   #拷貝配置文件
      copy: src=/opt/nginx.conf dest=/etc/nginx/nginx.conf backup=yes
      notify:
        - reload     #會觸發handlers中名字為reload的任務
      tags: 
        - reloadnginx
    - name: start nginx   #啟動nginx服務
      service: name=nginx state=started
      tags: 
        - startnginx
  handlers:
    - name: reload  #重載配置
      service: name=nginx state=reloaded

執行:ansible-playbook nginx.yml 

技術分享圖片
技術分享圖片

修改配置文件內容之後執行時調用標簽ansible-playbook nginx.yml --tags= "reloadnginx",就會跳過安裝步驟直接重載配置文件並啟動服務。
技術分享圖片
技術分享圖片

3.variables:變量

(1) facts:可直接調用

註意:可使用setup模塊直接獲取目標主機的facters

ansible xxx -m setup

技術分享圖片
(2) 用戶自定義變量:

  • 通過命令行傳遞變量

    ansible-playbook xxx.yml -extra-vars "host-www user-mageedu"
  • 在playbook中定義變量的方法
    vars:
    - var1: value1
    - var2: value2

(3)通過roles傳遞變量

(4)Host Inventory(主機清單)

- 主機變量

示例

[webservers] 
www1.accp.com  http_port=80    #添加主機變量http_port
www2.accp.com  http_port=8080

- 組變量

示例

[servers-vars]
ntp_server=ntp.example.org  #指定主機變量
nfs_server=nfs.example.org

- 組嵌套

示例

[apache]
httpd1.example.org
httpd2.example.org

[nginx]
ngx1.example.org
ngx2.example.org

[webservers:children]
apache
nginx

示例:使用變量package來代替軟件包,變量service來代替服務名。

- hosts: nginx
  remote_user: root
  vars:
    - package: vsftpd
    - service: vsftpd
  tasks:
    - name: install httpd package
      yum: name={{package}} state=latest   ##安裝最新版本的httpd
    - name: start httpd server
      service: name={{service}} enabled=true state=started     ##開啟服務

技術分享圖片

4.Templates:模板文件以.j2後綴

Jinja是基於 Python的模板引擎。 Template類是 Jinja的另一個重要組件,可以看
作是一個編譯過的模板文件,用來產生目標文本,傳遞 Python的變量給模板去替換模
板中的標記。

示例

從被管理端復制一份httpd.conf到管理端/opt/template
並做如下修改
mkdir /opt/template
cp /opt/template/httpd.conf  /opt/httpd.conf.j2
vim /opt/httpd.conf.j2      

 Listen {{http_port}}
 ServerName {{server_name}}

vim /etc/ansible/hosts
[httpd]
192.168.100.144 http_port=192.168.100.144:808 server_name=www.yun.com:808
# 在hosts文件為主機配置變量

vim httpd.yml

- hosts: httpd
  remote_user: root
  vars:
    - package: httpd
    - service: httpd
  tasks:
    - name: install httpd package
      yum: name={{package}} state=latest   #安裝最新版本的httpd
    - name: install configure file
      template: src=/opt/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf  #使用模板並根據變量進行配置
      notify:
        - restart httpd   #調用handler
    - name: start httpd server
      service: name={{service}} enabled=true state=started     #開啟服務
  handlers:
    - name: restart httpd
      service: name={{service}} state=restarted

技術分享圖片
技術分享圖片

5.循環:叠代,即需要重復執行的任務。

(1) when 語句:只需要在task之後添加when語句即可。

示例:

vim /etc/ansible/when.yml

- hosts: nginx
  remote_user: root
  vars:
    - username: user10
  tasks:
    - name: create {{username}} user
      user: name={{username}}
      when: ansible_fqdn=="promote.cache-dns.local"
執行:ansible-playbook when.yml 就會創建在nginx組的主機上。

技術分享圖片
(2)叠代:直接將需要叠代的內容定義為item變量並進行引用,然後通過with_items語句來指明叠代的元素。

示例:

vim /etc/ansible/items.yml

- hosts: nginx
  remote_user: root
  tasks:
    - name: install packages  #安裝with_items中列出的包
      yum: name={{ item }} state=latest
      with_items:
        - php
        - php-mysql

執行:ansible-playbook items.yml 就會安裝列表中的包

技術分享圖片
示例:

vim adduser.yml

- hosts: httpd
  remote_user: root
  tasks:
    - name: add some groups         #添加一些組
      group: name={{ item }} state=present
      with_items:
         - group1
         - group2
         - group3
    - name: add some user       #創建用戶到對應的組
      user: name={{ item.name }} group={{ item.group }} state=present
      with_items:
        - { name: ‘user1‘, group: ‘group1‘ }
        - { name: ‘user2‘, group: ‘group2‘ }
        - { name: ‘user3‘, group: ‘group3‘ }

 執行:ansible-playbook adduser.yml 就會創建對應的用戶及組

技術分享圖片
技術分享圖片

6.角色列表: Roles

Ansible為了層次化、結構化地組織 Playbook,使用了角色( roles),可以根據層
次結構自動裝載變量文件、 tasks以及 handlers等。只需要在 Playbook中使用 include
指令即可使用 roles。簡單來講, roles就是通過分別將變量、文件、任務、模塊及處理
器設置於單獨的目錄中,便捷地使用他們。

創建roles時的註意事項:

(1)目錄名同角色名的定義

(2)目錄結構有固定的格式:

  • files:用來存放由copy模塊或script模塊調用的文件。
  • templates:用來存放jinjia2模板。
  • tasks:至少有一個main.yml文件,定義各tasks。
  • handlers:有一個main.yml文件,定義各handlers。
  • vars:有一個main.yml文件,定義變量。
  • default:有一個main.yml文件,定義默認變量。
  • meta:有一個main.yml文件,定義此角色的特殊設定及其依賴關系。

註意:在每個角色命令的目錄中分別創建files、handlers、tasks、templates、meta、default和vars目錄,用不到的目錄可以創建為空目錄,但不可以不創建。

示例:定制三個角色:httpd、mysql、php

(1)在roles目錄下生成對應的目錄結構

mkdir -pv /etc/ansible/roles/{httpd,mysql,php}/{files,templates,vars,tasks,handlers,meta,default}

技術分享圖片

(2)在每個角色的handlers、tasks、meta、default、vars目錄下創建main.yml文件,千萬不能自定義。

touch /etc/ansible/roles/{httpd,mysql,php}/{default,vars,tasks,meta,handlers}/main.yml

(3)定義每個角色中tasks/main.yml的配置文件。

------編寫httpd模塊------

vim /etc/ansible/roles/httpd/tasks/main.yml   
- name: ensure apache is at the latest version 
  yum: name={{item}} state=latest
  with_items:
    - httpd
    - httpd-devel
- name: conf
  template: src=/etc/ansible/roles/httpd/templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
  tags: 
    - httpdconf
  notify: 
    - new conf to reload
  tags:
    - reload
- name: start service
  service: name=httpd enabled=true state=started
-------編寫mysql模塊-------

vim /etc/ansible/roles/mysql/tasks/main.yml
- name: ensure mysql is at the latest version 
  yum: name={{item}} state=latest
  with_items:
    - mariadb
    - mariadb-server
    - mariadb-libs
    - mariadb-devel
- name: start service
  service: name=mariadb enabled=true state=started

-------編寫php模塊-----

vim /etc/ansible/roles/php/tasks/main.yml
- name: ensure php is at the latest version
  yum: name={{item}} state=latest
  with_items:
    - php
    - php-mysql
    - php-gd
    - php-ldap
    - php-odbc
    - php-pear
    - php-xml
    - php-xmlrpc
    - php-mbstring
    - php-snmp
    - php-soap
    - curl
    - curl-devel 
    - php-bcmath

(4)修改變量文件vars/main.yml

vim /etc/ansible/roles/httpd/vars/main.yml
    http_port : 80    #添加變量
    server_name : www.yun.com:80

(5)定義handlers文件handlers/main.yml

vim /etc/ansible/roles/httpd/handlers/main.yml

- name: new conf to reload
  service: name=httpd state=reloaded

(6)定義/etc/ansible/lamp.yml的playbook文件

-----編寫roles示例-----
vi /etc/ansible/lamp.yml

- hosts: lamp
  remote_user: root
  roles:
    - httpd
    - mysql
    - php

(7)執行lamp.yml的playbook文件

ansible-playbook lamp.yml

技術分享圖片
(8)前往部署lamp的主機上編寫php測試頁,打開瀏覽器看網頁是否正常。

vim /var/www/html/index.php
    <?php
    phpinfo();
   ?>

打開瀏覽器輸入http://192.168.100.145/index.php
技術分享圖片
綜上步驟,lamp架構部署成功。

[自動化] Ansible之使用Playbooks詳解