一、配置文件 ansible.cfg
/etc/ansible/ansible.cfg 是ansible安裝好后的默認(rèn)配置文件,但是配置文件可以存在于多個地方,ansible讀取配置文件的順序依次是:當(dāng)前命令執(zhí)行目錄 ---> **用戶家目錄下的 .ansible.cfg ** ---> /etc/ansible/ansible.cfg,先找到哪個就使用哪個的配置。ansible.cfg中的配置均可在命令行通過參數(shù)傳遞或定義在playbooks中。
以下是[defaults]常用的配置項:
1)inventory
該參數(shù)表示資源清單inventory文件的位置,資源清單就是一些Ansible需要連接管理的主機列表
inventory = /root/ansible/hosts
2)library
Ansible的操作動作,無論是本地或遠(yuǎn)程,都使用一小段代碼來執(zhí)行,這小段代碼稱為模塊,這個library參數(shù)就是指向存放Ansible模塊的目錄
library = /usr/share/ansible
3)forks
設(shè)置默認(rèn)情況下Ansible最多能有多少個進程同時工作,默認(rèn)設(shè)置最多5個進程并行處理。具體需要設(shè)置多少個,可以根據(jù)控制主機的性能和被管理節(jié)點的數(shù)量來確定。
forks = 5
4)sudo_user
這是設(shè)置默認(rèn)執(zhí)行命令的用戶,也可以在playbook中重新設(shè)置這個參數(shù)sudo_user = root
//注意:新版本已經(jīng)作了修改,如ansible2.4.1下已經(jīng)為: default_sudo_user = root
5)remote_port
這是指定連接被關(guān)節(jié)點的管理端口,默認(rèn)是22,除非設(shè)置了特殊的SSH端口,不然這個參數(shù)一般是不需要修改的
remote_port = 22
6)host_key_checking
這是設(shè)置是否檢查SSH主機的密鑰??梢栽O(shè)置為True或False
host_key_checking = False
7)timeout
這是設(shè)置SSH連接的超時間隔,單位是秒。
timeout = 20
8)log_path
Ansible系統(tǒng)默認(rèn)是不記錄日志的,如果想把Ansible系統(tǒng)的輸出記錄到人i治穩(wěn)健中,需要設(shè)置log_path來指定一個存儲Ansible日志的文件
log_path = /var/log/ansible.log
另外需要注意,執(zhí)行Ansible的用戶需要有寫入日志的權(quán)限,模塊將會調(diào)用被管節(jié)點的syslog來記錄,口令是不會出現(xiàn)的日志中的
9)private_key_file 在使用ssh公鑰私鑰登錄系統(tǒng)時候,使用的密鑰路徑。
private_key_file=/path/to/file.pem
作者: Jeson老師
鏈接:https://www.imooc.com/article/22513
來源:慕課網(wǎng)
更多配置項請參考官方文檔
二、主機清單(Inventory)文件hosts
2.1 hosts文件定義
默認(rèn)存放在 **/etc/ansible/hosts **,命令行使用時,還可以通過 -i 或 --inventory-file 指定讀取某個hosts文件,如:
//讀取當(dāng)前用戶家目錄下的hosts文件
ansible -i ~/ansible/hosts webs -m ping
如下是hosts文件中的常用常用的定義主機方法:
# 定義單獨的主機
192.168.1.189 //可以直接為IP地址
ntp.cgy.com:2222 //也可以主機名:端口,端口默認(rèn)是22
# 定義主機組
[apache]
httpd1.cgy.com
httpd[10:20].cgy.com //[10:20]表示10~20之間所有數(shù)字(包括10和20)
# 定義主機變量
[nginx]
ngx-a.cgy.com http_port=808 //自定義這臺主機的nginx端口為808,可以寫多個變量,每個變量用空格間隔即可
ngx-[b:f].cgy.com //[b:f]表示b到f之間所有字母
# 定義主機組變量
[nginx:vars]
ntp_server=ntp.cgy.com //定義nginx組中所有的主機ntp_server值為ntp.cgy.com
# 定義組嵌套及組變量
[webservers:children]
apache
nginx
[webservers:vars]
ntp_server=ntp.cgy.com
2.2 主機匹配
- all(全量)匹配,匹配所有主機
// all和 * 號功能相同,但 * 號需要引起來
ansible all -m ping
ansible "*" -m ping
// 匹配192.168.1.0/24網(wǎng)段的主機
ansible 192.168.1.* -m ping
- 邏輯或(or)匹配
如果希望同時對多臺主機或多個組同時執(zhí)行,相互之間用
:(冒號)分隔即可。
使用方式如下:
ansible "webservers:dbservers" -m ping
- 邏輯非(?。┢ヅ?/li>
邏輯非用感嘆號(?。┍硎荆饕槍Χ嘀貤l件的匹配規(guī)則,使用方法如下:
// 所有在nginx組,但不包括ngx-c.cgy.com的主機
ansible "nginx:!ngx-c.cgy.com" -m ping
- 邏輯與(&)匹配
與邏輯非一樣,只是邏輯上的判斷不同。
// apache組和nginx組中同時存在的主機
ansible "apache:&nginx" -m ping
- 模糊匹配
*通配符在ansible表示0個或多個任意字符。
ansible "http*.cgy.com" -m ping
- 域切割
hosts文件如下:
[webservers]
cobweb
webbing
weber
通過截取數(shù)組下標(biāo)即可以獲取對應(yīng)主機:
webservers[0] # == cobweb
webservers[-1] # == weber
webservers[0:1] # == cobweb, webbing
webservers[1:] # == webbing, weber
- 正則匹配
ansible同樣完整支持正則匹配功能,
~開始表示正則匹配
ansible "~(beta|web|green)\.example\.(com|org)" -m ping
ansible ~192\.168\.[0-9]\{\2}\.[0-9]\{2,} -m ping
三、Ad-Hoc命令集
Ad-Hoc命令,也就是臨時命令的意思,就是通常在命令行下操作的ansible命令,區(qū)別于ansible-playbook。
Ad-Hoc 注重于解決一些簡單或者平時工作中臨時遇到的任務(wù),相當(dāng)于Linux系統(tǒng)命令行下的Shell命令;
Ansible-playbook 更適合解決復(fù)雜或需要固化下來的任務(wù),相當(dāng)于Linux系統(tǒng)的Shell腳本。
3.1 ansible命令用法
格式:ansible <host-pattern> [options]
可用選項如下:
-v, --verbose: 輸出更詳細(xì)的執(zhí)行過程信息,**-vvv** 可得到所有執(zhí)行過程信息。
-i PATH, --inventory=PATH: 指定inventory信息,默認(rèn)/etc/ansible/hosts。
-f NUM, --forks=NUM: 并發(fā)線程數(shù),默認(rèn)5個線程。
--private-key=PRIVATE_KEY_FILE: 指定密鑰文件。
-m NAME, --module-name=NAME: 指定執(zhí)行使用的模塊。
-M DIRECTORY, --module-path=DIRECTORY: 指定模塊存放路徑,默認(rèn)/usr/share/ansible,也可以通過ANSIBLE_LIBRARY設(shè)定默認(rèn)路徑。
-a 'ARGUMENTS', --args='ARGUMENTS': 模塊參數(shù)。
-k, --ask-pass SSH: 認(rèn)證密碼。
-K, --ask-sudo-pass sudo: 用戶的密碼(—sudo時使用)。
-o, --one-line: 標(biāo)準(zhǔn)輸出至一行。
-s, --sudo: 相當(dāng)于Linux系統(tǒng)下的sudo命令。
-t DIRECTORY, --tree=DIRECTORY: 輸出信息至DIRECTORY目錄下,結(jié)果文件以遠(yuǎn)程主機名命名。
-T SECONDS, --timeout=SECONDS: 指定連接遠(yuǎn)程主機的最大超時,單位是:秒。
-B NUM, --background=NUM: 后臺執(zhí)行命令,超NUM秒后kill正在執(zhí)行的任務(wù)。
-P NUM, --poll=NUM: 定期返回后臺任務(wù)進度。
-u USERNAME, --user=USERNAME: 指定遠(yuǎn)程主機以USERNAME運行命令。
-U SUDO_USERNAME, --sudo-user=SUDO_USERNAM: 使用sudo,相當(dāng)于Linux下的sudo命令。
-c CONNECTION, --connection=CONNECTION: 指定連接方式,可用選項paramiko (SSH), ssh, local。Local方式常用于crontab 和 kickstarts。
-l SUBSET, --limit=SUBSET: 指定運行主機。
-l ~REGEX, --limit=~REGEX: 指定運行主機(正則)。
--list-hosts: 列出符合條件的主機列表,不執(zhí)行任何其他命令
3.2 ansible命令執(zhí)行流程圖

3.3 常用模塊介紹
使用ansible-doc -l可以列出所有ansible支持的模塊;
使用ansible-doc 模塊名獲取模塊幫助信息;
/etc/ansible/hosts文件內(nèi)容如下:
[root@LOCALHOST ~]# cat /etc/ansible/hosts
[load-node]
openstack-load1
openstack-load2
[compute-node]
openstack-compute1
openstack-compute2
[control-node]
openstack-control1
openstack-control2
[openstack:children]
load-node
compute-node
control-node
3.3.1 ?command模塊
如果沒有用-m指定一個模塊,則ansible默認(rèn)使用的就是command模塊。如下:
查看load-node組的主機名:
[root@LOCALHOST ~]# <strong>ansible load-node -a "hostname"</strong>
openstack-load2 | SUCCESS | rc=0 >>
openstack-load2
openstack-load1 | SUCCESS | rc=0 >>
openstack-load1.example.com
注意:command 模塊不支持 shell 變量,也不支持管道等 shell 相關(guān)的東西.如果你想使用 shell相關(guān)的這些東西, 請使用’shell’ 模塊。
特別注意:執(zhí)行ansible命令之前需要將主機清單中所有主機關(guān)閉selinux狀態(tài)置于disabled狀態(tài),就是將
/etc/sysconfig/selinux中的SELINUX=disabled,然后重啟生效。
3.3.2 ?shell模塊
示例一(讀取變量):
[root@LOCALHOST ~]# **ansible load-node -m shell -a "echo $TERM"**
openstack-load2 | SUCCESS | rc=0 >>
xterm
openstack-load1 | SUCCESS | rc=0 >>
xterm
示例二(支持管道):
[root@LOCALHOST ~]# ansible load-node -m shell -a "netstat -tunlp | grep sshd"
openstack-load1 | SUCCESS | rc=0 >>
tcp 0 0 0.0.0.0:2002 0.0.0.0:* LISTEN 845/sshd
tcp6 0 0 :::2002 :::* LISTEN 845/sshd
openstack-load2 | SUCCESS | rc=0 >>
tcp 0 0 0.0.0.0:2002 0.0.0.0:* LISTEN 853/sshd
tcp6 0 0 :::2002 :::* LISTEN 853/sshd
3.3.3 ?copy模塊
[root@LOCALHOST ~]# **ansible load-node -m copy -a "src=/root/upgrade.log dest=/root/"**
openstack-load2 | SUCCESS => {
"changed": true,
"checksum": "792f7f450667adc5c89fbaeb06f778488149b87b",
"dest": "/root/upgrade.log",
"gid": 0,
"group": "root",
"md5sum": "1c1a33178d6a6aeb42fb4126ab420ba0",
"mode": "0644",
"owner": "root",
"size": 36,
"src": "/root/.ansible/tmp/ansible-tmp-1522073638.68-199717195987657/source",
"state": "file",
"uid": 0
}
...省略部分輸出...
注意:copy模塊還有一個remote_src參數(shù),不寫此參數(shù),默認(rèn)為:
remote_src=no,將控制主機的src復(fù)制到目標(biāo)主機的dest。如果加上參數(shù)remote_src=yes,那么將從遠(yuǎn)程目標(biāo)主機的src復(fù)制到遠(yuǎn)程主機的dest。
3.3.5 ?file模塊
使用file模塊可以做到修改文件的屬主和權(quán)限:
$ ansible webservers -m file -a "dest=/srv/foo/a.txt mode=600"
$ ansible webservers -m file -a "dest=/srv/foo/b.txt mode=600 owner=mdehaan group=mdehaan"
使用file模塊也可以創(chuàng)建目錄,與執(zhí)行mkdir -p 效果類似:
$ ansible webservers -m file -a "dest=/path/to/c mode=755 owner=mdehaan group=mdehaan state=directory"
刪除目錄(遞歸的刪除)和刪除文件:
$ ansible webservers -m file -a "dest=/path/to/c state=absent"
3.3.6 ?yum模塊
安裝軟件包:
$ ansible control-node -m yum -a "name=httpd state=present"
// 或者state=installed 安裝軟件
// state=latest 安裝最新版本
卸載軟件包:
$ ansible control-node -m yum -a "name=httpd state=absent"
// 或者state=removed 卸載軟件包
yum模塊在playbook中的用法:
# 以下只寫出了tasks部分內(nèi)容:
//安裝指定版本的軟件
- name: install one specific version of Apache
yum:
name: httpd-2.2.29-1.4.amzn1
state: present
// 升級所有軟件包
- name: upgrade all packages
yum:
name: '*'
state: latest
// 升級所有軟件包,不包括內(nèi)核和foo相關(guān)的軟件包
- name: upgrade all packages, excluding kernel & foo related packages
yum:
name: '*'
state: latest
exclude: kernel*,foo*
// 從遠(yuǎn)程倉庫安裝nginx
- name: install the nginx rpm from a remote repo
yum:
name: http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
state: present
// 安裝開發(fā)環(huán)境包組
- name: install the 'Development tools' package group
yum:
name: "@Development tools"
state: present
// 列出指定軟件包信息并注冊至變量result
- name: List ansible packages and register result to print with debug later.
yum:
list: ansible
register: result
3.3.7 ?user模塊
使用 user 模塊可以方便的創(chuàng)建賬戶,刪除賬戶,或是管理現(xiàn)有的賬戶:
// 添加用戶foo
$ ansible all -m user -a "name=foo password=123456"
// 刪除用戶foo
$ ansible all -m user -a "name=foo state=absent"
// state=absent結(jié)合remove=yes使用,相當(dāng)于shell命令userdel --remove 刪除用戶家目錄及郵件目錄
3.3.8 ?git模塊
可以直接使用git模塊部署webapp:
$ ansible webservers -m git -a "repo=git://foo.example.org/repo.git dest=/srv/myapp version=HEAD"
3.3.9 ?service模塊
用service模塊來管理各種服務(wù)的啟停:
// 開啟httpd
$ ansible webservers -m service -a "name=httpd state=started"
// 重啟httpd
$ ansible webservers -m service -a "name=httpd state=restarted"
// state可以選擇stopped(停止)、reloaded(重載配置)
需要注意的是,
started和stopped是 <font color=green size=4>冪等操作</font>,也就是說,如果某項服務(wù)已經(jīng)開啟或關(guān)閉,那么就不再繼續(xù)操作。
3.3.10 ?pip模塊
// 安裝Django
$ ansible app -m pip -a "name=django state=present"
3.3.11 ?mysql_user模塊
mysql_user模塊,是對mysql用戶進行管理的模塊。
事實上,Ansible也支持如Openstack、Mongodb、PostgreSQL、RabbitMQ等應(yīng)用的管理。
新增mysql用戶stanley,密碼123456,對zabbix.*表有所有權(quán)限,命令如下:
$ ansible db -m mysql_user -a "login_host=localhost login_user=root login_password=laksdvcx name=stanley password=123456 priv=zabbix.*:ALL state=present"
注意:上述命令直接將Mysql登錄信息完全暴露在命令行,存在很大的安全隱患。如果在遠(yuǎn)程主機的
~/.my.conf文件中定義登錄用戶及密碼,則可以在上述命令中省略登錄相關(guān)信息。
3.3.12? setup模塊
獲取遠(yuǎn)程主機的系統(tǒng)信息,這些系統(tǒng)信息在playbook中可以直接當(dāng)作變量引用,如 {{ ansible_all_ipv4_addresses }}就可以獲取到遠(yuǎn)程主機的所有IP地址[ "10.0.1.105", "43.240.137.105"],這些變量被稱作facts變量。
$ ansible compute-node -m setup
openstack-compute2 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"10.0.1.105",
"43.240.137.105"
],
"ansible_all_ipv6_addresses": [
"fe80::5054:ff:fe13:38cc",
"fe80::5054:ff:fe2b:60e5"
],
"ansible_apparmor": {
"status": "disabled"
},
"ansible_architecture": "x86_64",
"ansible_bios_date": "01/01/2007",
"ansible_bios_version": "0.5.1",
"ansible_cmdline": {
"BOOT_IMAGE": "/vmlinuz-3.10.0-327.el7.x86_64",
"LANG": "zh_CN.UTF-8",
"biosdevname": "0",
"crashkernel": "auto",
"net.ifnames": "0",
"quiet": true,
"rd.lvm.lv": "centos/swap",
"rhgb": true,
"ro": true,
"root": "/dev/mapper/centos-root"
},
... 省略 ...
"ansible_system_capabilities_enforced": "True",
"ansible_system_vendor": "Red Hat",
"ansible_uptime_seconds": 313578,
"ansible_user_dir": "/root",
"ansible_user_gecos": "root",
"ansible_user_gid": 0,
"ansible_user_id": "root",
"ansible_user_shell": "/bin/bash",
"ansible_user_uid": 0,
"ansible_userspace_architecture": "x86_64",
"ansible_userspace_bits": "64",
"ansible_virtualization_role": "guest",
"ansible_virtualization_type": "kvm",
"gather_subset": [
"all"
],
"module_setup": true
},
"changed": false
過濾顯示:
$ ansible compute-node -m setup -a 'filter=ansible_eth[0-1]'
$ ansible compute-node -m setup -a 'gather_subset=network,virtual'
$ ansible compute-node -m setup -a 'gather_subset=!all,!any,network,virtual'
3.3.13 ?cron模塊
cron模塊是用來添加或刪除定時任務(wù)的;
// 添加一個定時任務(wù),每過2分鐘從time.aliyun.com同步一次時間
[root@LOCALHOST ~]# ansible load-node -m cron -a "name='sync time from ntpserver' minute=*/2 job='/sbin/ntpdate time.aliyun.com &> /dev/null'"
openstack-load1 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"sync time from ntpserver"
]
}
openstack-load2 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"sync time from ntpserver"
]
}
注意:如果
hour、day、month、weekday都沒指定,則都表示*;
state沒寫,默認(rèn)等于present,就是創(chuàng)建定時任務(wù)。
刪除一個定時任務(wù):
[root@LOCALHOST ~]# ansible load-node -m cron -a "name='sync time from ntpserver' state=absent"
openstack-load1 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": []
}
openstack-load2 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": []
3.3.14 ?script模塊
script模塊是將本地腳本先拷貝一份到目標(biāo)主機上去執(zhí)行,執(zhí)行完成后再將目標(biāo)主機上的拷貝刪除。
// 在目標(biāo)主機上執(zhí)行控制機root目錄下的test.sh腳本
[root@LOCALHOST ~]# ansible load-node -m script -a "/root/test.sh"
openstack-load2 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "",
"stdout": "",
"stdout_lines": []
}
openstack-load1 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "",
"stdout": "",
"stdout_lines": []
}
// 驗證腳本在目標(biāo)主機是否執(zhí)行成功
[root@LOCALHOST ~]# ansible load-node -m shell -a "cat /tmp/ansible.txt"
openstack-load1 | SUCCESS | rc=0 >>
openstack-load1.example.com: Ansible is very good !!!
openstack-load2 | SUCCESS | rc=0 >>
openstack-load2: Ansible is very good !!!
3.3.15 ?archive和unarchive模塊
archive與unarchive模塊是打包壓縮與解壓縮模塊;
archive模塊默認(rèn)情況下,它假定目標(biāo)主機上存在壓縮源;
$ ansible load-node -m archive -a "path=/tmp/test exclude_path=/tmp/test/sub2 format=bz2 dest=/tmp/test.tar.bz2"
- path:指定遠(yuǎn)程主機上將要壓縮的目錄或文件;
- exclude_path:指定要排除的文件或目錄;
- format:指定壓縮格式,choices:gz、bz2、zip、tar、xz (ansible 2.5支持),默認(rèn)是gz格式;
- dest:壓縮后的文件名。
unarchive模塊默認(rèn)情況下,它將在解包之前將源文件從本地系統(tǒng)復(fù)制到目標(biāo)主機。設(shè)置remote_src = yes將解包目標(biāo)主機上已有的壓縮包。
$ ansible load-node -m unarchive -a "src=/tmp/test.tar.bz2 dest=/root list_files=yes remote_src=yes"
常用模塊就介紹這么多,更多模塊學(xué)習(xí)請使用ansible-doc 模塊名稱獲取幫助。