1. 程式人生 > 其它 >學會ansible之playbook一篇就夠了

學會ansible之playbook一篇就夠了

技術標籤:自動化運維工具運維雲端計算linux經驗分享

文章目錄

一、ansible-playbook 詳解

playbooks是 一個不同於使用Ansible命令列執行方式的模式,其功能更強大靈活。簡單來說,playbook是一個非常簡單的配置管理和多主機部署系統,不同於任何已經存在的模式,可作為一個適合部署複雜應用程式的基礎。Playbook可以定製配置,可以按照指定的操作步驟有序執行,支援同步和非同步方式。值得注意的是playbook是通過YAML格式來進行描述定義的

1.1:playbook格式

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

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

1.2:inventory主機清單

ansible預設的主機清單是/etc/ansible/hosts檔案,主機清單可以手動設定,也可以通過Dynamic Inventory動態生成,一般主機名使用FQDN

vim /etc/ansible/hosts
[webserver]                          #方括號設定組名
www1.example.org                     #定義被監控主機,這邊可以是主機名也可以是IP地址,主機名需要修改/etc/hosts檔案
www2.example.org:4444                #冒號後定義遠端連線埠,預設是ssh的22

如果是名稱類似的主機,可以使用列表的方式表示各個主機

[webserver]
www[01:50].example.org ansible_ssh_user=root ansible_ssh_pass=123456

[dbbservers]
db-[a:f].example.org

1.3:inventory變數

主機變數
[webserver]
www1.magedu.com http_port=80 maxRequestsChild=808
www2.magedu.com http_port=8080 maxRequestsChild=909

組變數
[servers:vars]
ntp_server=ntp.example.org
nfs_server=nfs.example.org

組巢狀
[apache]
http1.example.org
http2.example.org

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

[webservers:children]
apache
nginx

inventory變數引數

引數說明
ansible_ssh_host將要連線的遠端主機名.與你想要設定的主機的別名不同的話,可通過此變數設定
ansible_ssh_portssh埠號.如果不是預設的埠號,通過此變數設定
ansible_ssh_user預設的 ssh 使用者名稱
ansible_ssh_passssh 密碼(這種方式並不安全,我們強烈建議使用 --ask-pass 或 SSH 金鑰)
ansible_ssh_private_key_filessh 使用的私鑰檔案.適用於有多個金鑰,而你不想使用 SSH 代理的情況
ansible_ssh_common_args此設定附加到sftp,scp和ssh的預設命令列
ansible_sftp_extra_args此設定附加到預設sftp命令列
ansible_scp_extra_args此設定附加到預設scp命令列
ansible_ssh_extra_args此設定附加到預設ssh命令列
ansible_ssh_pipelining確定是否使用SSH管道. 這可以覆蓋ansible.cfg中得設定
ansible_shell_type目標系統的shell型別.預設情況下,命令的執行使用 ‘sh’ 語法,可設定為 ‘csh’ 或 ‘fish’
ansible_python_interpreter目標主機的 python 路徑.適用於的情況: 系統中有多個 Python, 或者命令路徑不是"/usr/bin/python",比如 *BSD, 或者 /usr/bin/python
ansible_*_interpreter這裡的"*"可以是ruby 或perl 或其他語言的直譯器,作用和ansible_python_interpreter 類似
ansible_shell_executable這將設定ansible控制器將在目標機器上使用的shell,覆蓋ansible.cfg中的配置,預設為/bin/sh

1.4、核心元件

tasks:任務
variables:變數
templates:模板
handlers:處理器
roles:角色

hosts 定義單個主機或組,vars定義變數,remote_user定義執行命令的遠端使用者,tasks定義執行哪些命令,handlers定義呼叫哪些處理器

vars(變數):

變數命名: 字母數字下劃線組成,只能以字母開頭

變數種類:

facts(內建變數)

由遠端主機發回的主機屬性資訊,這些資訊被儲存在ansible變數當中

例如:ansible 192.168.238.170 -m setup 來獲取遠端主機上的屬性資訊,這些屬性資訊儲存在facts中

通過命令列傳遞

通過命令列傳遞:ansible-playbook test.yml –extra-vars “host=www user=tom“(如果劇本中已有此處定義的變數則會被覆蓋)

通過roles傳遞

主機變數

在/etc/ansible/hosts中定義

[web1]
192.168.1.1 name=haha

組變數

[group_name:vars]
foo=bar

hosts :

/etc/abible/hosts 中指定的遠端主機,並用指定的屬性進行連線

ansible_ssh_port 連線遠端主機使用的埠

ansible_ssh_user 連線遠端主機使用的使用者

ansible_ssh_pass 連線遠端主機使用的密碼

cat /etc/ansible/hosts

[web1]
web1.hostname ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=123
web2.hostname

示例

[root@master ~]# cat apache.yaml 

 - hosts: node                  #定義的主機組,即應用的主機
  vars:                             #定義變數
    http_port: 80
    max_clients: 200
  user: root
  tasks:                               #執行的任務
 - name: ensure apache is at the latest version
    yum: pkg=httpd state=latest
 - name: ensure apache is running
    service: name=httpd state=started
 - name: html
    shell : echo 'cc' > /var/www/html/index.html
  handlers:                         #處理器
    - name: restart apache
      service: name=httpd state=restarted
  • 執行一個playbook的格式
ansible-playbook [yaml檔名]
#執行劇本
ansible-playbook apache.yaml

-k(–ask-pass)           用來互動輸入ssh密碼
-K(-ask-become-pass)    用來互動輸入sudo密碼
-u                      指定使用者

補充命令:

#檢查yaml檔案的語法是否正確
ansible-playbook nginx.yaml --syntax-check

#檢查tasks任務
ansible-playbook nginx.yaml --list-task

#檢查生效的主機
ansible-playbook nginx.yaml --list-hosts

#指定從某個task開始執行
ansible-playbook nginx.yaml --start-at-task='Copy Nginx.conf'

1.5、hosts和users介紹

[root@master opt]# cat a.yml 
- hosts: node
  remote_user: root 

#執行劇本
ansible-playbook a.yaml 

#檢查語法
ansible-playbook a.yml --syntax-check
  • 在原有基礎為每個任務定義遠端執行使用者
[root@master opt]# cat a.yml 
- hosts: node
  remote_user: root 
  tasks:
   - name: test connection
     ping:
     remote_user: root

ansible-playbook a.yml 

1.6、tasks列表和action

  • Play的主體部分是task列表,task列表中的各任務按次序逐個在hosts中指定的主機上執行,即在所有主機上完成第一個任務後再開始第二個任務。
    在執行playbook時(從上到下執行),如果一個host執行task失敗,整個tasks都會回滾,請修正playbook中的錯誤,然後重新執行即可。
    Task的目的是使用指定的引數執行模組,而在模組引數中可以使用變數,模組執行時冪等的,這意味著多次執行是安全的,因為其結果一致。
  • 2.每一個task必須有一個名稱name,這樣在執行playbook時,從其輸出的任務執行資訊中可以很好的辨別出是屬於哪一個task的。如果沒有定義name,‘action’的值將會用作輸出資訊中標記特定的task。
  • 3.定義一個task,常見的格式:”module: options” 例如:yum: name=httpd
  • 4.ansible的自帶模組中,command模組和shell模組無需使用key=value格式
[root@master opt]# cat a.yml 
- hosts: node
  remote_user: root 
  tasks:
   - name: selinux
     command: '/sbin/setenforce 0'
     remote_user: root
   - name: install httpd
     yum: name=httpd
   - name: start httpd
     service: name=httpd state=started

#執行yml檔案
ansible-playbook a.yml

假如task中有錯誤操作 ,會回滾操作,新增以下欄位
ignore_errors: true

- hosts: node
  remote_user: root
  tasks:
   - name: selinux
     command: '/sbin/setenforce 0'
   - name: firewalld
     yum: 'name=firewall state=stoped'
     ignore_errors: true
   - name: start httpd
     service: name=httpd state=started
······
PLAY RECAP ******************************************************************************
192.168.158.30             : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=1   
192.168.158.40             : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=1   

1.7:Handlers介紹

Handlers也是一些task的列表,和一般的task並沒有什麼區別。
是由通知者進行的notify,如果沒有被notify,則Handlers不會執行,假如被notify了,則Handlers被執行
不管有多少個通知者進行了notify,等到play中的所有task執行完成之後,handlers也只會被執行一次

[root@master opt]# cat c.yml 
- hosts: node
  remote_user: root
  vars:
  - package: httpd
  - service: httpd
  tasks:
   - name: install httpd package
     yum: name={{package}} state=latest
     notify:
      -restart httpd
   - name: start httpd service
     service: enabled=true name={{service}} state=started
  handlers:
   - name: restart httpd
     service: name={{service}} state=restarted

1.8:playbook使用變數的方法

1、通過ansible命令傳遞

vim lisi.yml 

- hosts: mysql
  remote_user: root
  vars:
   - username: lisi
  tasks:
   - name: create user
     user: name={{username}}
      
'執行劇本'
ansible-playbook lisi.yml

'或者-e後面加變數直接引用'
- hosts: node
  remote_user: root
  vars:
  tasks:
   - name: create user
     user: name={{username}}

然後執行命令:ansible-playbook lisi.yml -e "user=lisi"    都是可行的

1、定義在hosts檔案中的變數,是主角常用變數
2、yml直接定義的變數,任務中常用的變數
3、命令傳遞進去的變數,測試中常用的變數

1.9、條件測試

如果需要根據變數、facts(setup)或此前任務的執行結果來作為某task執行與否的前提時要用到條件測試,在Playbook中條件測試使用when子句。
在task後新增when子句即可使用條件測試:when子句支援正則表示式或語法。

vim lisi.yml

- hosts: node
  remote_user: root
  tasks:
    - name: "shutdown CentOS"
      command: /sbin/shutdown -h now            '-h:關機 -r:重啟'
      when: ansible_distribution == "CentOS"    '滿足Centos就關機'
'執行'
ansible-playbook lisi.yml    '發現node主機已經被關機'

1.10、多條件判斷

vim lisi.yml

- hosts: mysql
  remote_user: root
  tasks:
    - name: "shut down CentOS 7 systems"
      command: /sbin/shutdown -r now
      when:
        - ansible_distribution == "CentOS"
        - ansible_distribution_major_version == "7"

1.11、組條件判斷

vim lisi.yml

- hosts: mysql
  remote_user: root
  tasks:
    - name: "shut down CentOS 6 and Debian 7 systems"
      command: /sbin/shutdown -t now
      when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6") or
            (ansible_distribution == "Debian" and ansible_distribution_major_version == "7")
            
'執行副本'
ansible-playbook lisi.yml 

1.12、迭代

當有需要重複性執行的任務時,可以使用迭代機制。其使用格式為將需要迭代的內容定義為item變數引用,並通過with_items語句指明迭代的元素列表即可。

# 利用item變數傳遞,with_items中存放需要遍歷的元素。
- hosts: 192.168.158.30
  remote_user: root
  tasks:
   - name: "Install Packages"
     yum: name={{ item }} state=latest
     with_items:
       - httpd
       - mysql
       - php


- hosts: 192.168.158.30
  remote_user: root
  tasks:
   - name: Add users
     user: name={{ item.name }} groups={{ item.groups }}
     with_items:
        - { name: 'test1', groups: 'wheel'}
        - { name: 'test2', groups: 'root'}
依次建立使用者 test1 test2,對應組為wheel'、,root