YAML:能夠將你打算對多機器的批量操做放到一個文件中,順序執行,能夠根據機器作到根據機器信息判斷執行,其餘命令執行結果判斷執行。linux
YAML有着嚴格的層級要求,稍微有個縮進問題就會沒法運行,因此學習過程當中,須要細心觀察。nginx
命令 指定hosts文件位置 劇本文件 參數shell
-C 調試模式,調試劇本是否能夠正常運行(這個模式中,任何更改的操做都不會執行)centos
ansible-playbook -i hosts yaml.file ansible-playbook -i hosts yaml.file -C
劇本開始語法bash
--- #一個標識符,相似#!/bin/bash - hosts: all #此劇本做用域 remote_user: root #使用什麼用戶運行此劇本 gather_facts: True #在遠程主機運行setup模塊,並將收集的信息記錄起來(等於命令ansible all -m setup#查看系統信息),能夠經過系統信息來判斷是否執行 vars: #定義變量 variable: values tasks: #任務開始標籤 - name: task_name model_name: values
每個任務,能夠指定必定的操做,定義一個任務基礎參數以下服務器
#一個用name模塊被'命名'任務下只容許有一個同級的模塊存在(不包括輔助功能,後面會講)學習
- name: task_name
model_name: values
yaml語法中結構:測試
[ { 'name': 'task_name', 'model_name': 'values' } ]
如下這種狀況,命名任務與模塊是同級的狀況下,能夠正常執行,只是不在命名任務模塊下的模塊執行起來顯示的是是模塊名稱,而不是任務名稱(例子1-1),任務多了沒法判斷url
- model_name: values
- name: task_name
model_name: values
- model_name: values
yaml語法中結構:centos7
[ {'model_name': 'values'}, { 'name': 'task_name', 'model_name': 'values' }, {'model_name': 'values'} ]
例子1-1
[root@host1 [10:02:30]/yaml/test]#cat test.yaml --- - hosts: all remote_user: root gather_facts: True tasks: - name: "ping test" ping: - ping: [root@host1 [10:02:32]/yaml/test]#ansible-playbook -i hosts test.yaml PLAY [all] *********************************************************************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************************************************************** ok: [192.168.100.3] TASK [ping test] ***************************************************************************************************************************************************** ok: [192.168.100.3] TASK [ping] ********************************************************************************************************************************************************** ok: [192.168.100.3] PLAY RECAP *********************************************************************************************************************************************************** 192.168.100.3 : ok=3 changed=0 unreachable=0 failed=0 [root@host1 [10:02:41]/yaml/test]#
實際狀況演練
新建下方文件:
[root@host1 [18:32:56]/yaml/test]#cat test.yaml --- - hosts: all remote_user: root gather_facts: True tasks: - name: "ping test" ping:
上方意思是新建ping test的任務,並執行ping模塊,測試連通性,看下方結果,能夠看到任務標籤,而且狀態也是成功的。(Gathering Facts 表明或許系統信息,也是成功的)
#如下以"狀況"的形式,向你們講解如何使用經常使用方法
狀況1:你的環境中有多臺機器,分別有CentOS6系統和CentOS7系列系統,兩類系統在某些方面多是不同的,你如今兩臺機器上執行不一樣的操做,讓咱們來看看怎麼實現。
hosts文件內容
100.3爲centos6 祕鑰對認證,能夠免密鏈接
100.7爲centos7 沒作過密鑰對認證,經過密碼認證
192.168.100.3 192.168.100.7 ansible_user=root ansible_password=nihao123!
執行下方命令
ansible all -m setup
返回的是主機的信息,如系統類型,ip地址等,ansible能夠根據這些作過濾
在此狀況下,咱們能夠經過 ansible_distribution和ansible_distribution_major_version進行匹配(如下是兩臺主機的信息組合,由於我使用的grep過濾的我須要的字段)
[root@host1 [14:30:55]/yaml/test]#ansible -i hosts all -m setup |grep "ansible_distribution" "ansible_distribution": "CentOS", "ansible_distribution_file_parsed": true, "ansible_distribution_file_path": "/etc/redhat-release", "ansible_distribution_file_variety": "RedHat", "ansible_distribution_major_version": "7", "ansible_distribution_release": "Core", "ansible_distribution_version": "7.2.1511", "ansible_distribution": "CentOS", "ansible_distribution_file_parsed": true, "ansible_distribution_file_path": "/etc/redhat-release", "ansible_distribution_file_variety": "RedHat", "ansible_distribution_major_version": "6", "ansible_distribution_release": "Final", "ansible_distribution_version": "6.5",
編寫下方劇本。
根據when執行判斷條件,當系統版本爲6時執行對應的任務,爲7時執行對應的任務。
[root@host1 [15:37:42]/yaml/test]#cat test2.yaml --- - hosts: all remote_user: root gather_facts: True tasks: - name: "ping test" ping: - name: "only on Centos6" shell: "echo 'ON THE Centos6'" when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '6' - name: "only on Centos7" shell: "echo 'ON THE Centos7'" when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '7'
執行測試,能夠看到,任務執行時,都執行了對應的匹配條件,只有條件經過才執行對應的shell模塊指定的命令,不經過時跳過執行。
when匹配方式有多種,除了咱們使用的a=a and b=b以外,大體經常使用的以下
when: (ansible_distribution == 'CentOS' and ansible_distribution_major_version == '6') or (ansible_distribution == 'CentOS' and ansible_distribution_major_version == '5') #等同於and,匹配多個條件 when: -ansible_distribution== "CentOS" -ansible_distribution_major_version== "6" #對數字作大於小於的判斷 when:ansible_distribution_major_version|int >= 6 #定義變量,並根據變量來判斷對應任務是不是否執行 vars: epic: true when: epic when not epic #經過上個模塊執行結果來判斷此模塊是否執行(result|failed 能夠替換爲result is failed ),此方法使用方法詳見例子1-2 tasks: - command: /bin/false register: result ignore_errors: True - command: /bin/something when: result|failed - command: /bin/something_else when: result|success - command: /bin/still/something_else when: result|skipped
例子1-2
新建下方劇本,
劇本含義:當cat /etc/fapweifjapewijfapwejfpawjf成立時,判斷"when: result is success"才成立
(須要配合
register: result #將執行結果記錄到result變量上,給when提供判斷條件
ignore_errors: True #跳過錯誤,錯誤時繼續執行,給when提供判斷機會
使用)
--- - hosts: all remote_user: root gather_facts: True tasks: - shell: "cat /etc/fapweifjapewijfapwejfpawjf" register: result ignore_errors: True - shell: "head -10 /etc/fapweifjapewijfapwejfpawjf" when: result is success
執行結果
狀況2:須要給多臺機器添加yum源配置
像這種問題,就是須要使用echo "" >> ..repo 到文件中去,可是,yum倉庫的配置可不是隻是一項,有什麼能寫的更簡潔的方法呢。
with_items 一個迭代器,你能夠在裏面定義不少的東西,而後在某處引用時,裏面的東西會循環的輸出,直到定義的值輸出完。
相似下方例子
items=[1,2,3,4,5,6,7,8] for i in items: print(i)
新建下方劇本
gather_facts: no 在不須要獲取機器信息時,根據信息作判斷時,將其關閉,避免影響執行速度。
定義名稱:with_items,調用名稱:item都是固定的,不能更改.
{{variable}} 調用變量的方法,也是調用迭代器的方法。
--- - hosts: all remote_user: root gather_facts: no tasks: - name: "setting yum" shell: "echo {{ item }} >> /etc/yum.repos.d/base.repo" with_items: - "[base]" - "name=base" - "baseurl=ftp://10.124.164.114/pub/Server" - "enabled=1" - "gpgcheck=0"
在客戶端上查看結果,已經正常寫入。
狀況3:你須要一次操做多個服務,如啓動,重啓等。
你可使用狀況2中的,定義with_items方法,可是你須要去with_items字段中定義,代碼量多了不免有點麻煩,咱們能夠結合變量使用(在文首就直接定義了),定義一個列表,而後將列表傳給with_items,交由它來作一個迭代器,當引用item時引用多個值。
問:爲何不直接在{{}}中引用變量,而要引用迭代器
由於變量沒法在引用時被循環,就算列表裏面有多個值,它引用時也只會識別一個列表,就是[nginx,ntpd]。
--- - hosts: all remote_user: root gather_facts: no vars: service_list: [nginx,ntpd] service_state: restarted tasks: - service: name="{{item}}" state="{{service_state}}" with_items: '{{ service_list }}'
狀況4:你的劇本文件中,定義了不少功能,可是此次,你只想運行某個功能,該如何實現呢。
debug模塊,只是一個功能,在此狀況中,能夠用任何模塊替換,此模塊是將msg定義的消息回顯到終端,供咱們調試。
tags標籤,定義在模塊下,標籤名稱建議有意義,無難輸入的特殊字符,無空格
--- - hosts: all remote_user: root gather_facts: no tasks: - debug: msg="task 1" tags: task1 - debug: msg="task two" tags: task2
執行測試
此狀況重點來了,單獨運行某個標籤。使用以下命令
只運行task1標籤的任務
[root@host1 [18:17:53]/yaml/test]#ansible-playbook -i hosts --tags=task1 test5.yaml
學習了上面的使用狀況,你已經能夠寫一個屬於你的yaml劇本,使用什麼模塊實現什麼功能,這個你能夠邊學邊用,你能夠試着完成下方我根據我工做環境自制的精簡版ansible yaml劇本練習做業,鞏固你的學習。
如下要求須要在你寫時,寫在同一劇本中
1.新建用戶 admin,deployer,並定義密碼
2.設置用戶永不過時
3.備份/home/admin/ 的全部文件(包括隱藏文件) ,(假設你有一個叫/dev/vdb的磁盤),判斷/dev/vdb是否掛載,若是掛載了,就不用管,若是沒有掛載,將其掛載到/home/admin/ ,恢復你備份的文件至/home/admin/
4.同步服務器的時間,將時間同步服務設置爲自啓動
5.先零時,後永久的增長ulimit ("max user processes", "open files", "pending signals")這三個值的大小,具體大小自定義,達到更改效果便可。
6.先零時關閉防火牆,selinux,後設置永久關閉。
7.將hostname 和本機ip的對應關係增長至/etc/hosts文件中
8.設置yum倉庫,讓其能正常下載軟件,
9,支持運行此劇本時,指定值運行[同步時間]任務,而不設置時間同步服務自啓動