目錄
Ansible概述 3
安裝ansible 5
yum安裝ansible 5
源碼包安裝 5
Ansible配置檔案解析 6
Ansible系列指令用法詳解 9
ansible 9
ansible-galaxy 10
absible-pull 11
ansible-doc 11
ansible-playbooks 11
ansible-vault 11
Ansible Inventory配置及詳解 12
定義主機群組 12
定義主機變量 13
定義組變量 13
定義組嵌套及組變量 13
多重變量定義 14
Inventory參數清單 14
Ansible與正則 15
ALL比對 15
邏輯或(or)比對 15
邏輯非(!)比對 15
邏輯與(&)比對 15
多條件組合 16
模糊比對 16
域切割 16
正則比對 17
Ansible的指令集 17
ansible指令參數 17
ansible指令的執行流程圖 18
Ansible-playbook 21
ansible-playbook的工作原理: 21
Playbook文法介紹 21
Playbooks中包含的部分 22
target section 23
variable section 23
tasks section 24
handlers section 24
變量 25
在Inventory中用等号“=”來為變量指派 25
在playbook和包含變量設定的配置檔案中,用冒号“:”來指派 25
在運作playbook時,使用--extra-vars選項指定額外的變量 25
在playbook中定義變量,使用vars子產品 25
可以将變量單獨定義到一個檔案中,在playbook中引用變量檔案 26
利用ansible内置環境變量(setup子產品) 26
在Inventory檔案中定義變量 26
注冊變量 27
主機變量和主機組變量 28
變量的優先級 29
Include包含 29
Roles 31
建構roles 32
跨平台roles 34
when條件判斷 35
任務間流程控制 38
tags 标簽 39
Block塊 40
Ansible常用子產品 43
file子產品 43
copy子產品 43
service子產品 44
yum子產品 46
unarchive子產品 48
lineinfile子產品 49
register子產品 49
get_url子產品 49
regexp子產品 49
with_items子產品 49
Playbook中常用的子產品 49
template子產品 49
set_fact子產品 51
pause子產品 52
wait_for子產品 53
assemble子產品 54
add_host子產品 55
group_by子產品 55
debug子產品 56
常用的自動化運維工具
CFengine
Chef
Puppet
--基于ruby開發,采用C/S架構,擴充性強,基于ssl認證
SaltStack
--基于python開發,采用C/S架構,相對于puppet更輕量級,配置文法采用yaml,配置腳本更為簡單
Ansible
--基于python開發,分布式,無需用戶端,輕量級,語言為yaml
Ansible概述
ansible是新出現的自動化運維工具,基于Python開發,集合了衆多運維工具(puppet、cfengine、chef、func、fabric)的優點,實作了批量系統配置、批量程式部署、批量運作指令等功能。
ansible是基于子產品工作的,本身沒有批量部署的能力。真正具有批量部署的是ansible所運作的子產品,ansible隻是提供一種架構。主要包括:
(1)、連接配接插件connection plugins:負責和被監控端實作通信;
(2)、host inventory:指定操作的主機,是一個配置檔案裡面定義監控的主機;
(3)、各種子產品核心子產品、command子產品、自定義子產品;
(4)、借助于插件完成記錄日志郵件等功能;
(5)、playbook:劇本執行多個任務時,非必需可以讓節點一次性運作多個任務。
Ansible的基本架構
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5iNwM2YzkTOwIjM1UzLcFTMyIDMy8CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
上圖為ansible的基本架構,如圖可知其包括以下部分:
核心:ansible
核心子產品(Core Modules):這些都是ansible自帶的子產品
擴充子產品(Custom Modules):可添加的擴充子產品
插件(Plugins):完成子產品功能的補充
劇本(Playbooks):ansible的任務配置檔案,将多個任務定義在劇本中,由ansible自動執行
連接配接插件(Connectior):ansible基于連接配接插件連接配接到各個主機上,預設使用ssh連接配接,也支援其他連接配接方式,需要安裝插件
主機群(Host):定義ansible管理的主機
安裝ansible
yum安裝ansible
[root@centos-20 man1]#yum -y install epel*
[root@centos-20 man1]# yum list |grep ansible
ansible.noarch 2.2.1.0-1.el6 @epel
ansible-inventory-grapher.noarch 1.0.1-2.el6 epel
ansible-lint.noarch 2.0.1-1.el6 epel
python2-ansible-tower-cli.noarch 3.1.3-2.el6 epel
ansible的目錄結構
配置檔案目錄 /etc/ansible
執行檔案目錄 /usr/bin
lib庫依賴目錄 /usr/lib/pythonX.X/
help 文檔目錄 /usr/share/doc/ansible-X.X.X
man文檔目錄 /usr/share/man/man1
源碼包安裝
解決依賴關系
yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto
下載下傳源碼包
https://releases.ansible.com/ansible/ansible-2.2.2.0.tar.gz
tar xf ansible-2.2.2.0.tar.gz
cd ansible-2.2.2.0
python setup.py build
python setup.py install
mkdir /etc/ansible
cp -r examples/* /etc/ansible
Ansible配置檔案解析
ansible自身的配置檔案隻有一個,即absible.cfg,預設的位置在/etc/ansible目錄下:
[default] 正常的連接配接類配置,大多數保持預設即可
#inventory = /etc/ansible/hosts 定義Inventory,用于定義ansible的主機清單配置
#library = /usr/share/my_modules/ 定義lib庫存放目錄
#remote_tmp = ~/.ansible/tmp 臨時檔案遠端主機存放目錄
#local_tmp = ~/.ansible/tmp 臨時檔案本地存放目錄
#forks = 5 預設開啟的并發數
#poll_interval = 15 預設輪詢時間間隔
#sudo_user = root 預設sudo使用者
#ask_sudo_pass = True 是否需要sudo密碼
#ask_pass = True 是否需要密碼
#transport = smart
#remote_port = 22
#module_lang = C
#module_set_locale = False
#gather_subset = all
# gather_timeout = 10
#roles_path = /etc/ansible/roles 預設下載下傳的roles存放的目錄
#host_key_checking = False 首次連接配接是否需要檢查key認證,建議False
#stdout_callback = skippy
# enable additional callbacks
#callback_whitelist = timer, mail
#task_includes_static = True
#handler_includes_static = True
#error_on_missing_handler = True
#sudo_exe = sudo
#sudo_flags = -H -S -n
#timeout = 10 預設逾時時間
#remote_user = root 如果沒有指定使用者,預設使用的遠端連接配接使用者
#log_path = /var/log/ansible.log 執行日志存放位置
#module_name = command 預設執行的子產品
#executable = /bin/sh
#hash_behaviour = replace
#private_role_vars = yes
#jinja2_extensions = jinja2.ext.do,jinja2.ext.i18n
#private_key_file = /path/to/file
#vault_password_file = /path/to/vault_password_file
#ansible_managed = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host}
#ansible_managed = Ansible managed
#display_skipped_hosts = True
#display_args_to_stdout = False
#error_on_undefined_vars = False
#system_warnings = True
#deprecation_warnings = True
# command_warnings = False
#action_plugins = /usr/share/ansible/plugins/action
action插件的存放目錄
#cache_plugins = /usr/share/ansible/plugins/cache
#callback_plugins = /usr/share/ansible/plugins/callback
callback插件的存放目
#connection_plugins = /usr/share/ansible/plugins/connection
connection插件的存放目錄
#lookup_plugins = /usr/share/ansible/plugins/lookup
lookup插件的存放目錄
#inventory_plugins = /usr/share/ansible/plugins/inventory
inventory插件存放的目錄
#vars_plugins = /usr/share/ansible/plugins/vars
vars插件的存放目錄
#filter_plugins = /usr/share/ansible/plugins/filter
filter插件存放的目錄
#test_plugins = /usr/share/ansible/plugins/test
test插件存放的目錄
#strategy_plugins = /usr/share/ansible/plugins/strategy
strategy插件存放的目錄
#bin_ansible_callbacks = False
#nocows = 1
#cow_selection = default
#cow_selection = random
#nocolor = 1
#fact_caching = memory getfact緩存的主機資訊存放方式
#retry_files_enabled = False
#retry_files_save_path = ~/.ansible-retry 錯誤重新開機檔案目錄
#no_log = False
#no_target_syslog = False
#allow_world_readable_tmpfiles = False
#var_compression_level = 9
#module_compression = 'ZIP_DEFLATED'
#max_diff_size = 1048576
[privilege_escalation] 出于安全考慮,不會直接用root直接部署應用程式,往往會開放普通使用者權限并給予sudo的權限,該部配置設定置主要針對sudo使用者提權的配置
#become=True 是否sudo
#become_method=sudo sudo的方式
#become_user=root sudo後變成root使用者
#become_ask_pass=False sudo後是否驗證密碼
[paramiko_connection] 該配置不常用,了解即可
#record_host_keys=False 不記錄新主機的key以提升效率
#pty=False 禁用sudo功能
[ssh_connection] ansible預設使用的ssh協定連接配接對端主機,該部分是ssh連接配接的一些配置,比較少,預設即可
#pipelining = False 管道加速功能,需要配合requiretty使用方可生效
[accelerate] ansible連接配接加速的配置,該配置項在提升ansible連接配接速度時會涉及,多數預設即可。
#accelerate_port = 5099 加速連接配接端口
#accelerate_timeout = 30 指令執行逾時時間,機關秒
#accelerate_connect_timeout = 5.0 連接配接逾時時間,機關秒
#accelerate_daemon_timeout = 30 上一個活動連接配接的時間,機關分鐘
#accelerate_multi_key = yes
[selinux] 預設即可
#libvirt_lxc_noseclabel = yes
[colors] ansible對于輸出結果的顔色配置,預設即可
#highlight = white
#verbose = blue
#warn = bright purple
#error = red
#debug = dark gray
#deprecate = purple
#skip = cyan
#unreachable = red
#ok = green
#changed = yellow
#diff_add = green
#diff_remove = red
#diff_lines = cyan
Ansible系列指令用法詳解
ansible
指令格式:ansible <host-pattern> [options]
<host-pattern> 是Inventory中定義的主機或主機組,可以為ip、hostname、Inventory中的group組名、具有“.”或“*”或“:”等特殊字元的比對性字元串,<>表示該選項是必須項。
[options] ansible的參數選項,[ ] 表示該選項中的參數人選其一。
應用場景:非固化需求
臨時一次性操作
二次開發接口調用
ansible-galaxy
ansible-galaxy的功能可以簡單的了解為GitHub或PIP的功能,通過ansible-galaxy指令,可以根據下載下傳量和關注量等資訊,查找和安裝優秀的Roles。可以上傳和下載下傳Roles,下載下傳位址https://galaxy.ansible.com
指令格式
ansible-galaxy [delete|import|info|init|install|list|login|remove|search|setup] [--help] [options] ...
ansible-galaxy指令分為三大部分:
1、[delete|import|info|init|install|list|login|remove|search|setup]
- init:初始化本地的Roles配置,以備上傳Roles至galaxy
- info:清單指定Role的詳細資訊
- install:下載下傳并安裝galaxy指定的Roles到本地
- list:列出本地已下載下傳的Roles
- remove:删除本地已下載下傳的Roles
- help 用法顯示[--help]
- ansible-galaxy init [options] role_name3、參數項[options],可以用--help檢視參數
- # 下載下傳這個Roles到本地并忽略錯誤
下載下傳roles
https://galaxy.ansible.com/explore#/ 多元度劃分roles的下載下傳使用情況,指令規範遵循username.rolesname。是以下載下傳的方法:
ansible-galaxy install username.rolesname
如果同時下載下傳多個roles,可以将所需要的roles寫入配置檔案後,使用-r批量下載下傳roles,如:
vim roles.txt
user1.role1,v1.0.0
user2.role2,v0.5
user2.role3
下載下傳:
ansible-galaxy install -r roles.txt
absible-pull
該指令的使用涉及ansible的另一種工作模式:pull模式(ansible預設使用push模式)。這和push模式的工作機理剛好相反,使用的場景:
- 有數量巨大的機器需要配置,即使使用高并發線程依舊要花費很多時間;
- 要在剛啟動的沒有網絡連接配接的主機上運作ansible;
指令格式:ansible-pull -U <repository> [options]
ansible-doc
ansible-doc是ansible子產品文檔說明
指令格式:ansible-doc [options] [module...]
ansible-playbooks
指令的工作機制:通過讀取預先寫好的playbook檔案實作批量管理。要實作的功能與amsible一樣,可以了解為按一定條件組成的ansible任務集。
指令的格式:ansible-playbook playbook.yml
ansible-vault
absible-vault主要用于陪配置檔案加密,如編寫的playbook配置檔案中包含敏感的資訊,不希望其他人随意看到,ansible-vault可加密/解密這個配置檔案。
指令格式:ansible-vault [create|decrypt|edit|encrypt|rekey|view] [--help] [options] vaultfile.yml
加密a.yml檔案
ansible-vault encrypt a.yml
解密a.yml檔案
ansible-vault decrypt a.yml
Ansible配置及詳解
Inventory是ansible管理主機資訊的配置檔案,預設存放在/etc/ansible/hosts。友善批量管理主機,使用時通過-i或--inventory-file指定讀取:
ansible -i /etc/absible/hots webs -m ping
定義主機群組
192.168.189.40 #可以直接寫IP
[node] #中括号中的字元為組名,以中括号進行分組
192.168.189.50
node1.centos.com #支援hostname的方式,後跟冒号加數字表示端口号,預設是22号端口
node2.centos.com:2222 #空行後的主機亦屬于該組
[webserver]
web1.centos.com
web[2:10].centos.com 表示2~10之間的所有數字(包括2和10),即web2到web10.centos.com的所有主機名
[dbserver]
a.centos.com
[b:e].centos.com #[b:e]表示b到e之間的所有字母(包括b和e),即b.centos.com、c.centos.com、d.centos.com、e.centos.com 的所有主機
定義主機變量
[webserver]
web1.centos.com http_port=8080 maxRequestsPerChild=801
#自定義http_port的端口為8080,配置maxRequestsPerChild=801
定義組變量
主要針對大量機器的變量定義需求,賦予組内所有主機同一變量。
[node]
192.168.189.50
node1.centos.com
node2.centos.com
[node:vars]
ntp_server=times.aliyum.com
#定義組中所有主機的ntp_server值為times.aliyum.com
定義組嵌套及組變量
Inventory中,組還可以包含其他的組,并且可以向組中的主機指定變量。不過這些變量隻能在ansible-playbook中使用,而ansible不支援。
[nginx]
nginx1.centos.com
nginx2.centos.com
[mysql]
mysql1.centos.com
mysql2.centos.com
[allserver:children]
nginx
mysql
[allserver:vars]
ntp_server=times.aliyum.com
多重變量定義
變量除了定義在hosts中,也可以定義在其他的配置檔案中,變量通常從如下4個位置檢索:
- Inventory配置檔案(預設/etc/ansible/hosts)
- Playbook中vars定義的區域
- Roles中vars目錄下的檔案
- Roles同級目錄group_vars和hosts_vars目錄下的檔案。
Inventory參數清單
ansible_ssh_host | 将要連接配接的遠端主機名 |
ansible_ssh_port | ssh端口号 |
ansible_ssh_user | 預設的ssh使用者名 |
ansible_ssh_pass | ssh密碼(建議ssh秘鑰) |
ansible_sudo_pass | sudo密碼 (建議使用--ask-sudo-pass) |
ansible_sudo_exe | sudo指令路徑 |
ansible_connection | 于主機連接配接的類型,比如: ssh、local或者paramiko |
ansible_ssh_private_key_file | ssh使用的秘鑰檔案,适用于有多個秘鑰檔案,而且不想使用ssh代理的情況 |
ansible_shell_type | 目标系統的shell類型,預設使用sh,可設定為‘csh’或‘fish’ |
ansible_python_interpreter | 目标主機的python路徑,系統中有多個Python,或路徑不是/usr/bin/python |
ansible_become | 允許更新權限,相當于ansible_sudo或ansible_su |
ansible_become_method | 允許設定特殊權限的方法 |
ansible_become_user | 允許設定特殊權限的使用者,相當于ansible_sudo_user或ansible_su_user |
ansible_become_pass | 允許設定特權使用者的密碼,相當于ansible_sudo_pass |
Ansible與正則
ansible的正規表達式(Patterns)功能等同于正規表達式,文法使用也和正則類同,主要用于Inventory的主機清單使用
ansible <pattern_goes_here> -m <module_name> -a <arguments>
ALL比對
比對所有主機,all或*号的功能相同。如檢測所有主機存活情況
ansible all -m ping
ansible "*" -m ping
檢查192.168.189.0網段所有主機的狀況
ansible 192.168.189.* -m ping
邏輯或(or)比對
如果要同時對多台主機或多個組同時執行時,互相之間用“:”冒号分隔即可。
ansible "node:webserver" -m ping
邏輯非(!)比對
邏輯非用感歎号(!)表示,主要針對多重條件的比對規則
ansible "node :! webserver" -m ping
# 所有在node組但是不在webserver組的主機
邏輯與(&)比對
和邏輯非一樣,邏輯與也主要針對多重條件的比對規則,隻是邏輯上的判斷不同。邏輯與使用&表示
ansible "webserver :& node" -a "ls"
兩個組中同時存在的主機
多條件組合
ansible同樣支援多條件的複雜組合,應用不多,僅了解
webserver : dbserver :& staging :! phone
# webserver和dbserver中所有的主機在staging組中存在且在phone組中不存在的主機
模糊比對
*通配符在ansible表示0個或多個任意字元,主要應用于一些模糊規則比對,使用頻率比較高
ansible *.centos.com -m ping
# 比對以 .centos.com 結尾的所有主機
ansible *.centos.com:node-m ping
# 比對以結尾的所有主機和node組中的所有主機
域切割
ansible底層基于Python,是以也支援域切割
str = ‘12345678’
print str[0:1]
通過[0:1]即可獲得數值1、2
[node]
192.168.189.40
192.168.189.50
node1.centos.com
通過截取數組下表可以獲得對應的變量值
ansible node[0] -m ping # ==192.168.189.40
ansible node[-1] -m ping # ==node1.centos.com
ansible node[0:1] -m ping # ==node[0],node[1]
正則比對
“~”開始表示正則比對
~(web|bd).*\.centos\.com
比對以web、bd開頭的域名
Ansible的指令集
ansible指令參數
Usage: ansible <host-pattern> [options]
options | 解釋 | |
-a | --args | 子產品的參數 |
-B | --background | 背景執行指令,超出x秒後終止正在執行的任務,秒 |
-C | --check | 不做任何改變,相反,預測一些可能發生的變化 |
-D | --diff | 當從模闆改變主機的檔案時,顯示出這些檔案的不同内容,與--check一起用 |
-e | --extra-vars | |
-f | --forks | 并發線程數,預設是5個線程 |
-i | --inventory-file | 指定inventory資訊,預設位置: /etc/ansible/hosts |
-l | --limit | 指定運作的主機 |
-m | --module-name | 指定使用的子產品 |
-M | --module-path | 指定子產品的存放路徑,預設位置: /usr/share/absible |
-o | --one-line | 标準輸出至一行 |
--output | ||
-P | --poll=NUM | 定期傳回背景任務進度,和-B一起使用,預設是15秒 |
--syntax-check | ||
-t | --tree=directory | 輸出資訊号指定目錄,結果檔案以遠端主機名命名 |
-v | --verbose | 輸出詳細的資訊 |
-vvv | 輸出執資訊行過程的所有資訊 | |
--version | 顯示版本 | |
Connection Options: | ||
-k | --ask-pass | ssh的認證密碼 |
--private-key | 指定秘鑰檔案位置 | |
-u | --user | 用哪個使用者連接配接主機 |
-c | --connection | 指定連接配接方式,可用選項:paramiko(SSH)、ssh、local |
-T | --timeout | 連接配接主機的逾時時間,秒 |
Privilege Escalation Options: | ||
-s | --sudo | sudo指令 |
-U | --sudo-user | 使用sudo |
-S | --su | |
-R | --su-user | |
-b | --become | |
--become-method | ||
--become-user | ||
--ask-sudo-pass | ||
--ask-su-pass | ||
-K | --ask-become-pass | sudo使用者的密碼 |
執行個體1
ansible node -f 5 -m ping
執行個體2
ansible node -m command -a ‘hostname’-vvv
執行個體3
列出node組所有的主機清單
[root@centos-20 ansible]# ansible node --list
hosts (3):
192.168.189.40
192.168.189.50
node1.centos.com
執行個體4
對192.168.189.40伺服器以root執行sleep 20,設定最大連接配接時長為2s,且設定為背景運作模式,執行過程每2s輸出一次進度,如5s還未執行完就結束任務
[root@centos-20 ansible]# time ansible 192.168.189.40 -B 5 -P 2 -T 2 -m command -a "sleep 20"
192.168.189.40 | FAILED | rc=0 >>
async task did not complete within the requested time
real 0m10.738s
user 0m2.711s
sys 0m0.878s
實驗:用ansible搭建nginx+php+mysql
配置主機組
[nginx]
192.168.189.30
[php]
192.168.189.40
[mysql]
192.168.189.50
安裝服務
ansible nginx -m yum -a "name=nginx state=present"
ansible php -m yum -a "name=php state=present" -v
ansible mysql -m yum -a "name=/opt/tools/mysql-server-5.6.17-1.e16.x86_64.rpm state=present"
啟動服務
ansible nginx -m service -a "name=nginx state=started enabled=yes"
ansible php -m service -a "name=php state=started enabled=yes"
ansible mysql -m service -a "name=mysqld state=started enabled=yes"
Ansible-playbook
ansible的任務配置檔案被稱為playbook,我們可以稱之為“劇本”。每一個劇本(playbook)都包含一系列任務,每個任務在absible中又被稱為“戲劇”(play)。一個劇本(playbook)中包含多個戲劇(play)。
ansible-playbook的工作原理:
Playbook文法介紹
playbook采用的是yaml(Yet仍是一種标記語言)文法編寫。
- 資料結構可以用類似大綱的縮排方式呈現,結構通過縮進來表示,連續的項目通過減号“-”來表示
- 結構中key/value的值用“:”來分隔,冒号和字元串之間用有個空格分隔,換行寫時,需要加“-”
- 字元串不一定要用雙引号辨別
- 縮進必須統一,在縮進中空白字元的數目并不重要,隻要相同級别的元素左側對其就可以了(注意:不能使用tab字元)
- 可以在檔案中加入選擇性的空行,以增加可讀性
- 選擇性的符号“---”可以用來表示開始,“…”可以用來表示結尾
- 使用#号注釋代碼
如:
---
- hosts: nginx
user: root
vars:
- src_file: /usr/local/nginx/conf/nginx.conf
- dest_file: /etc/nginx/nginx.conf
tasks:
- name: install nginx
yum: name=nginx state=present
- name: copy test.txt
copy: src={{ src_file }} dest={{ dest_file }} backup=yes
notify:
- restart nginx
handlers:
- name: restart nginx
service: name=nginx state=restarted
...
Playbooks中包含的部分
- target section定義将要執行playbook的遠端主機組
- variable section定義playbook執行時需要使用的變量
- task section定義将要在遠端主機上執行的任務清單
- handler section定義task執行完成後需要調用的任務
target section
hosts:定義遠端的主機組
user:執行該任務的組的使用者
remote_user:與user相同
sudo:如果設定為yes,執行該任務組的使用者在執行時,獲得root權限
sudo_user:如果你設定user為tom,sudo為yes,sudo_user為jerry,則tom使用者會獲得jerry用的權限
connection:通過什麼方式連接配接到遠端主機,預設是ssh
gather_facts:如果不需要再遠端主機上執行setup子產品,使用該選項。預設會自動執行
variable section
有三種定義變量的方式
vars:
- port:80
vars_files:
- variablefile #在同級目錄下的variable檔案中定義變量
- vars.yml
- [ "one.yml", "two.yml" ]
vars_prompt: #互動式輸入變量值
- name: serivce #變量名
prompt: please enter something #提示輸入變量值
private: no #在輸入變量值時,是否顯示内容
注:
private 該值為yes,即使用者所有的輸入在指令行中預設是看不見的,将值設定為no時,使用者輸入可見
default:為變量設定預設值,以節省使用者輸入時間
confirm:特别适合輸入密碼的情況,如果設定為yes,則會要求使用者輸入兩次,以增加輸入的正确性。
tasks section
#tasks 定義的三種方法
---
- hosts: nginx
vars:
- server:nginx
tasks:
- name: install nginx
yum: name=nginx state=present 第一種:寫成一行
- name: copy config file
copy: 第二種:寫成清單
src: /usr/local/nginx/conf/nginx.conf
dest: /etc/nginx/nginx.conf
- name: start nginx
action: service name=nginx state=started 第三種:用action調用子產品
handlers section
handlers也是一些tasks的清單,和一般的task沒有什麼差別。
handlers是由通知者進行notify,如果沒有被notify,handler不會被執行。
不管有多少個通知者進行了notify,隻有等到play中所有的task執行完成之後,handlers也隻會執行一次。
- hosts: nginx
user: root
vars:
- src_file: /usr/local/nginx/conf/nginx.conf
- dest_file: /etc/nginx/nginx.conf
tasks:
- name: install nginx
yum: name=nginx state=present
- name: copy test.txt
copy: src={{ src_file }} dest={{ dest_file }} backup=yes
notify: #當執行完copy後,通知rstart nginx
- restart nginx
handlers:
- name: restart nginx
service: name=nginx state=restarted
變量
在ansible中,變量以英文大小寫字母開頭,中間可以包含下劃線和數字。
- 合法的變量格式:foo, foo_bar, foo_bar_5, fooBar
- 建議字母都用小寫
- 盡量讓數字在變量名的末尾
在Inventory中用等号“=”來為變量指派
foo=bar
在playbook和包含變量設定的配置檔案中,用冒号“:”來指派
foo: bar
在運作playbook時,使用--extra-vars選項指定額外的變量
ansible-playbook nginx.yml --extra-vars "foo=bar"
在playbook中定義變量,使用vars子產品
vars
vars_files
vars_prompt #互動時使用的變量,使用較少
- hosts:all
vars:
- foo: bar
vars_files:
- /vars/external_vars.yml
可以将變量單獨定義到一個檔案中,在playbook中引用變量檔案
---
- hosts:nginx
vars_files:
- vars.yml
…
vim vars.yml
foo: bar
利用ansible内置環境變量(setup子產品)
---
- vars_files:
- [ "apache_{{ ansible_os_family }}.yml", "apache_default.yml" ]
在Inventory檔案中定義變量
[nginx]
192.168.189.30 proxy_state=present #為某一台主機定義變量
192.168.189.40
[nginx:vars] #為主機組定義變量
nginx_versinotallow=1.10.1
在執行ansible指令時,ansible預設會在/etc/ansible/host_vars/和/etc/ansible/group_vars/目錄下讀取變量定義,可以在這兩個目錄下建立與hosts檔案中主機名或組名同名的檔案來定義變量,也可以在這兩個目錄下定義all檔案,來一次性的為所有的主機定義變量。
[nginx]
192.168.189.30
192.168.189.40
在同級目錄下建立group_vars/nginx檔案
vim group_vars/nginx
nginx_version: 1.10.1
注冊變量
将操作的結果,包括标準輸出和标注錯誤輸出,儲存到變量中,然後在根據這個變量的内容來決定下一步的操作,利用register子產品
數組變量或清單變量,定義方法如下:
foo_list:
- one
- two
- three
清單定義完成後,要讀取其中第一個變量,有一下兩種方法:
foo[0]
foo|first
字典變量,如ansible内置變量absible_eth0就是這種變量,它用來存儲遠端主機上的eth0接口的資訊。可以收集變量ansible_eth0的内容:
[root@centos-20 ansible]# cat var.yml
---
- hosts: nginx
tasks:
- debug: var=ansible_eth0
...
[root@centos-20 ansible]# ansible-playbook var.yml
PLAY [nginx] *******************************************************************
TASK [setup] *******************************************************************
ok: [192.168.189.30]
TASK [debug] *******************************************************************
ok: [192.168.189.30] => {
"ansible_eth0": {
"active": true,
"device": "eth0",
"ipv4": {
"address": "192.168.189.30",
"broadcast": "192.168.189.255",
"netmask": "255.255.255.0",
"network": "192.168.189.0"
},
"ipv6": [
{
"address": "fe80::20c:29ff:fedf:3ac6",
"prefix": "64",
"scope": "link"
}
],
"macaddress": "00:0c:29:df:3a:c6",
"module": "e1000",
"mtu": 1500,
"pciid": "0000:02:01.0",
"promisc": false,
"speed": 1000,
"type": "ether"
}
}
擷取IPv4的位址,方法有兩種
{{ ansible_eth0.ipv4.address }}
{{ ansible_eth0['ipv4']['address'] }}
主機變量和主機組變量
在運作ansible任務時,可能需要從一台遠端主機上擷取另一台遠端主機的變量資訊,變量hostvars可以實作這一需求。如,我們想擷取host1上的變量admin_user的内容,在任意主機上直接使用下面的代碼即可:
{{ hostvars['host1']['admin_user'] }}
ansible提供了一些非常有用的内置變量:
- groups:包含了所有hosts檔案裡主機組名的清單
- group_names:包含了目前主機所在的所有主機組名的一個清單
- inventory_hostname:通過hosts檔案定義主機的主機名
- inventory_hostname_short:變量inventory_hostname的第1部分,比如inventory_hostname的值是book.ansible.com,那麼inventory_hostname_short就是book
- play_shots:将執行目前任務的所有主機。
變量的優先級
官方給出了如下由高到低的優先級:
- 在指令行中定義的變量(即用-e定義的變量)
- 在Inventory中定義的連接配接變量(比如ansible_ssh_user)
- 大多數的其他變量(指令行轉換、play中的變量、include的變量、role中的變量等)
- 在Inventory中定義的其他變量
- 由系統通過gather_facts方法發現的facts
- Role預設變量
Playbook循環
當在一個playbook中很多tasks都重複引用某個子產品,比如一次同步10個檔案,可以使用absible loops。可以讓playbook減少重複使用某個子產品。
标準loops
如使用yum安裝10個軟體。with_items的值時python list資料類型,可以了解為每個task會循環讀取list裡面的值,然後key的名稱是item
---
- name: install serivce
hosts: all
tasks:
- name: yum install
yum: name={{ item }} state=present
with_items:
- nginx
- httpd
- php
- mysql-server
...
list裡面也支援python字典,如:
---
- name: copy file
hosts: 192.168.189.30
tasks:
- name: copy file
copy: src={{ item.src }} dest={{ item.dest }}
with_items:
- { src: /tmp/a.txt, dest: /tmp/ }
- { src: /tmp/b.txt, dest: /tmp/ }
...
[root@centos-20 ansible]# ansible-playbook copy.yml
檔案比對loops
檔案比對loops是編寫playbook的時候需要針對檔案進行操作中常用的一種循環,比如需要針對一個目錄下指定格式的檔案進行處理,這時可以直接引用with_fileglob循環去比對我們需要處理的檔案即可。如:
[root@centos-20 ansible]# cat copy.yml
---
- name: copy file
hosts: 192.168.189.30
tasks:
- name: copy file
copy: src={{ item }} dest=/tmp/
with_fileglob:
- /etc/ansible/*.yml
...
執行:
[root@centos-20 ansible]# ansible-playbook copy.yml
條件判斷loops
有時候在執行一個task之後,需要檢測task的結果是否達到了預想狀态,如果沒有達到預想的狀态時,就要退出playbook的執行,這時就要對某個task結果一直循環檢測,如:
[root@centos-20 ansible]# cat test7.yml
---
- hosts: 192.168.189.30
tasks:
- name: debug loops
shell: cat /tmp/a.txt
register: file
until: file.stdout.startswith("aaa")
retries: 5
delay: 5
- debug: msg={{ file }}
...
執行:
[root@centos-20 ansible]# ansible-playbook test7.yml
5秒執行一次cat /tmp/a.txt 将結果register給file然後判斷host.stdout.startswith的内容是否是aaa字元串開頭的,如果是,條件成立,此task運作完成,如果條件不成立,5秒後重試,5次不成立,此task運作失敗。
檔案優先比對loops
檔案優先比對loops和檔案比對loops的功能是相似的,但是檔案優先比對會根據傳入的變量或着檔案進行從上往下比對,如果比對到某個檔案,它會用這個檔案當做{{ item }}的值:
---
- hosts: all
gather_facts: True
tasks:
- name: debug loops
debug: msg="files ------> {{ item }}"
with_first_found:
- "{{ ansible_distribution }}.yml"
- "default.yml"
…
with_file_found會在list定義的清單中從上往下比對,優先比對ansible_distribution 檔案,比對不到預設是default.yml
Include包含
在大型複雜的架構中,一個很大的playbooks很維護,這是需要用到include。将plays分解成多個不同的段,然後在其他的plays中包含他們。不同的段根據不同的目的進行分類,全部包含在主play中。總有四種類型的包含:
- 變量包含:允許将變量存在外部的yml檔案
- playbook包含:一個大型的項目可以包含多個plays
- 任務包含:将任務放到普通的檔案中,當需要的時候包含他們
- handlers包含:允許将所有的handlers處理程式當到一個地方
應用的場景
有ABCDEF這6個項目,但都需要使用重新開機php的功能,我們可以将重新開機PHP的功能作為單獨的playbook檔案,使其他的項目可以引用該檔案,不必每個項目都重寫“重新開機php”功能。
執行個體:安裝DNS
## cat named.yml
- name: install DNS
hosts: nginx
vars:
- server: bind
- src_file: /etc/ansible/template/named.j2
- dest_file: /etc/named.conf
tasks:
- include: /etc/ansible/named/tasks.yml
- { include: tasks2.yml, version: '1.1', package: [nginx,httpd] }
- { include: tasks3.yml, when: absible_all_ipv4_addresses == '192.168.1.117' }
handlers:
- include: /etc/ansible/named/service.yml
## cat /etc/ansible/named/tasks.yml
- name: install service
yum: name={{ server }} state=present
- name: copy config file
template: src={{ src_file }} dest={{ dest_file }} backup=yes
notify:
- restart named
## cat /etc/ansible/named/service.yml
- name: restart named
service: name=named state=restarted
動态includes
在滿足一定條件時加載includes
## cat /etc/ansible/include.yml
---
- name: check if extra_tasks.yml is present
hosts: nginx
tasks:
# 判斷/tmp目錄下extra-tasks.yml檔案是否存在
- stat: path=/tmp/extra-tasks.yml
# 擷取狀态傳回值
register: extra_tasks_file
# 結合when條件,隻有當extra_tasks_file檔案存在時,再加載include
- include: /etc/ansible/extra-tasks.yml
when: extra_tasks_file.stat.exists
...
## cat /etc/ansible/extra-tasks.yml
- debug: var={{ extra_tasks_file }}
include允許傳遞清單和字典參數
tasks:
- { include: wordpress.yml, wp_user: timmy }
Roles
字面的意思是角色,可以了解為:有互相關聯功能的集合,相對includes功能,roles更适合于大項目playbook的編排架構。
建構roles
roles主要依賴于目錄的命名和擺放,預設tasks/main.yml是所有任務的接口,是以使用roles的過程可以了解為目錄規範化命名的過程。每一個目錄下均由mail.yml定義該功能的任務集,tasks/main.yml預設執行所有指定的任務。roles的調用檔案xxx.yml
site.yml
webservers.yml
fooservers.yml
roles/
common/
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
webservers/
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
一個playbook
---
- hosts: webservers
roles:
- common
- webservers
- 如果存在, 其中列出的 tasks 将被添加到 play 中
- 如果存在, 其中列出的 handlers 将被添加到 play 中
- 如果存在, 其中列出的 variables 将被添加到 play 中
- 如果存在, 其中列出的 “角色依賴” 将被添加到 roles 清單中 (1.3 and later)
- 所有可以引用 roles/x/files/ 中的檔案,不需要指明檔案的路徑。
- 所有可以引用 roles/x/files/ 中的腳本,不需要指明檔案的路徑。
- 所有可以引用 roles/x/templates/ 中的檔案,不需要指明檔案的路徑。
- 所有可以引用 roles/x/tasks/ 中的檔案,不需要指明檔案的路徑。
執行個體:
[root@centos-20 test]# tree
.
├── roles
│ ├── common
│ │ ├── defaults
│ │ ├── files
│ │ ├── handlers
│ │ ├── meta
│ │ ├── tasks
│ │ │ └── main.yml
│ │ ├── templates
│ │ └── vars
│ └── zabbix
│ ├── defaults
│ ├── files
│ │ ├── conf
│ │ │ ├── userparameter_haproxy.conf
│ │ │ ├── userparameter_ine.conf
│ │ │ ├── userparameter_linux_status.conf
│ │ │ ├── userparameter_memory.conf
│ │ │ ├── userparameter_ping_status.conf
│ │ │ ├── wifiin.ping.sh
│ │ │ ├── zabbix_ine_status.sh
│ │ │ ├── zabbix_linux_plugin.sh
│ │ │ └── zabbix_ping.sh
│ │ └── zabbix_agentd.conf
│ ├── handlers
│ ├── meta
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ └── vars
└── zabbix.yml
## 執行方法
ansible-playbook zabbix.yml
跨平台roles
ansible支援多平台,如,為Debian、RedHat兩種類型的系統安裝apache服務
## 在hosts檔案中定義主機組
[apache]
192.168.189.30
192.168.189.40
## 建立兩個角色
## apache_db角色
mkdir roles/apache_db/tasks
vim roles/apache_db/tasks/main.yml
---
- include: http.yml
...
vim roles/apache_db/tasks/http.yml
---
- name: ubuntu install httpd
remote_user: sremanager
apt: name=mini-httpd state=present
...
## apache_rh角色
mkdir roles/apache_rh/tasks
vim roles/apache_rh/tasks/main.yml
---
- include: http.yml
...
vim roles/apache_rh/tasks/http.yml
---
- name: centos install apache
remote_user: root
yum: name=httpd state=present
...
## 在relos的同級目錄建立一個apache.yml
---
- name: install apache
hosts: apache
roles:
- { role: apache_db, when: ansible_os_family == 'Debian' }
- { role: apache_rh, when: ansible_os_family == 'RedHat' }
...
when條件判斷
很多任務隻有在特定的條件下載下傳能執行,這時就需要when語句
如隻有遠端主機是redhat時才執行yum install httpd
---
- name: yum install apache
hosts: test
tasks:
- name: yum install httpd
yum: name=httpd state=present
when: ansible_os_family == 'RedHat'
…
- when語句和注冊變量結合
如檢查一個nginx的運作狀态,并判斷傳回的狀态值,當狀态為“running”時,停止nginx服務
---
- name: stop nginx
hosts: test
tasks:
- name: check nginx status
shell: /etc/init.d/nginx status #檢查Nginx的狀态
register: nginx_status #将Nginx的狀态指派給nginx_status變量
- name: stop nginx
service: name=nginx state=stopped
when: "'running' in nginx_status.stdout" #當“running”單詞在傳回的狀态中時,關閉nginx
- debug: var=nginx_status #輸出nginx的狀态
...
- changed_when、failed_when條件判斷
對于ansible,其很難判斷一個指令的運作是否符合我們的實際預期,尤其是在使用command和shell子產品時,如果不适用changed_when語句,ansible将永遠傳回changed。
---
- name: yum install nginx
shell: yum install nginx
register: nginx
changed_when: "'nothing to install or update' not in nginx.stdout"
…
在安裝nginx時,隻有運作的結果中不包含“mothing to install or update”字段的時候,ansible才會将傳回值的狀态改為changed,這更符合我們的需要
- filed_when
任務間流程控制
任務委托
預設情況下,ansible的所有任務都是在我們制定的機器上面運作的,當在一個獨立的叢集環境中配置時,這并沒有什麼問題。而在有些情況下,比如給某一台伺服器發送通知或監控伺服器中添加被監控主機,這時候任務就要在特定的主機上運作,而非所有的主機,這就用到ansible的委托任務了。
任務暫停
在有些情況下,一些任務的運作需要等待一些狀态的恢複,比如一台主機或者應用剛剛啟動,我們需要等待它上面的某個端口開啟,此時我們就不得不将正在運作的任務暫停,知道其狀态滿足我們的需求。
- name: wait for webserver to start
local_action:
module: wait_for
host: webserver1
port: 80
delay: 10
timeout: 300
state: started
這個任務将會每10秒檢查一次主機webserver1上的80端口是否開啟,如果超過300s,80端口仍未開啟,将會傳回失敗資訊。
[root@centos-20 ansible]# cat test5.yml
---
- name: check nginx
hosts: test
tasks:
- name: check 80
wait_for: port=80 delay=10 timeout=300 state=started
- name: copy file
copy: src=/etc/hosts dest=/tmp/hosts
...
tags 标簽
預設情況下,ansible在執行一個playbook時,會執行playbook中定義的所有任務,ansible的标簽(tags)功能可以給角色(roles)、檔案、單獨的任務甚至整個playnook打上标簽,然後利用這些标簽來指定要運作playbook中的個别任務,或不執行指定的任務。
---
# 可以給整個playbook的所有任務打個标簽
- hosts: webserver
tags: deploy
roles:
# 給角色打的标簽會應用在角色下所有的任務
- { role: omcat, tags: ['tomcat','app'] }
tasks:
- name: notify on completion
local_action:
module: osx_say
msg: "{{inventory_hostbname}} is finished!"
voice: zarvox
tags:
- notifycations
- say
- include: foo.yml
tags: foo
...
如果隻執行“notify on completion”
ansible-playbook tags.yml --tags "say"
如果想跳過帶有“notifycations”标簽的任務,可以用--skip-tags選項。
ansible-playbook tags.yml --skip-tags "notifycations"
格式:
最簡潔的寫法
tags: ['one','two','there']
tags:
- one
- two
- three
Block塊
---
- host: web
tasks:
- block:
- yum: name=httpd state=present
- template: src=httpd.j2 dest=/etc/httpd/conf/httpd.conf
- service: name=httpd state=started enabled=yes
when: ansible_os_family == 'RedHat'
sudo: yes
…
taks:
- bolck:
- name: shell script to connect the app to a monitoring service
script: monitoring-connect.sh
rescue:
- name: 隻有腳本報錯時才執行
debug: msg="There was an error in the block."
always:
- name: 無論結果如何都執行
debug: msg="This always executes"