天天看點

ansible文檔

目錄​

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的基本架構​

ansible文檔

上圖為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​
  1. 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​

ansible文檔

執行個體2​

ansible node -m command -a ‘hostname’-vvv​

ansible文檔

執行個體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的工作原理:

ansible文檔

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:将執行目前任務的所有主機。​

變量的優先級

官方給出了如下由高到低的優先級:​

  1. 在指令行中定義的變量(即用-e定義的變量)​
  2. 在Inventory中定義的連接配接變量(比如ansible_ssh_user)​
  3. 大多數的其他變量(指令行轉換、play中的變量、include的變量、role中的變量等)​
  4. 在Inventory中定義的其他變量​
  5. 由系統通過gather_facts方法發現的facts​
  6. 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處理程式當到一個地方​

應用的場景​

ansible文檔

有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"      

繼續閱讀