一、配置文件 ansible.cfg
/etc/ansible/ansible.cfg 是ansible安装好后的默认配置文件,但是配置文件可以存在于多个地方,ansible读取配置文件的顺序依次是:当前命令执行目录 ---> **用户家目录下的 .ansible.cfg ** ---> /etc/ansible/ansible.cfg,先找到哪个就使用哪个的配置。ansible.cfg中的配置均可在命令行通过参数传递或定义在playbooks中。
以下是[defaults]
常用的配置项:
1)inventory
该参数表示资源清单inventory文件的位置,资源清单就是一些Ansible需要连接管理的主机列表
inventory = /root/ansible/hosts
2)library
Ansible的操作动作,无论是本地或远程,都使用一小段代码来执行,这小段代码称为模块,这个library参数就是指向存放Ansible模块的目录
library = /usr/share/ansible
3)forks
设置默认情况下Ansible最多能有多少个进程同时工作,默认设置最多5个进程并行处理。具体需要设置多少个,可以根据控制主机的性能和被管理节点的数量来确定。
forks = 5
4)sudo_user
这是设置默认执行命令的用户,也可以在playbook中重新设置这个参数sudo_user = root
//注意:新版本已经作了修改,如ansible2.4.1下已经为: default_sudo_user = root
5)remote_port
这是指定连接被关节点的管理端口,默认是22,除非设置了特殊的SSH端口,不然这个参数一般是不需要修改的
remote_port = 22
6)host_key_checking
这是设置是否检查SSH主机的密钥。可以设置为True或False
host_key_checking = False
7)timeout
这是设置SSH连接的超时间隔,单位是秒。
timeout = 20
8)log_path
Ansible系统默认是不记录日志的,如果想把Ansible系统的输出记录到人i治稳健中,需要设置log_path来指定一个存储Ansible日志的文件
log_path = /var/log/ansible.log
另外需要注意,执行Ansible的用户需要有写入日志的权限,模块将会调用被管节点的syslog来记录,口令是不会出现的日志中的
9)private_key_file 在使用ssh公钥私钥登录系统时候,使用的密钥路径。
private_key_file=/path/to/file.pem
作者: Jeson老师
链接:https://www.imooc.com/article/22513
来源:慕课网
更多配置项请参考官方文档
二、主机清单(Inventory)文件hosts
2.1 hosts文件定义
默认存放在 **/etc/ansible/hosts
**,命令行使用时,还可以通过 -i
或 --inventory-file
指定读取某个hosts文件,如:
//读取当前用户家目录下的hosts文件
ansible -i ~/ansible/hosts webs -m ping
如下是hosts文件中的常用常用的定义主机方法:
# 定义单独的主机
192.168.1.189 //可以直接为IP地址
ntp.cgy.com:2222 //也可以主机名:端口,端口默认是22
# 定义主机组
[apache]
httpd1.cgy.com
httpd[10:20].cgy.com //[10:20]表示10~20之间所有数字(包括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网段的主机
ansible 192.168.1.* -m ping
- 逻辑或(or)匹配
如果希望同时对多台主机或多个组同时执行,相互之间用
:
(冒号)分隔即可。
使用方式如下:
ansible "webservers:dbservers" -m ping
- 逻辑非(!)匹配
逻辑非用感叹号(!)表示,主要针对多重条件的匹配规则,使用方法如下:
// 所有在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
通过截取数组下标即可以获取对应主机:
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命令,区别于ansible-playbook。
Ad-Hoc 注重于解决一些简单或者平时工作中临时遇到的任务,相当于Linux系统命令行下的Shell命令;
Ansible-playbook 更适合解决复杂或需要固化下来的任务,相当于Linux系统的Shell脚本。
3.1 ansible命令用法
格式:ansible <host-pattern> [options]
可用选项如下:
-v, --verbose: 输出更详细的执行过程信息,**-vvv** 可得到所有执行过程信息。
-i PATH, --inventory=PATH: 指定inventory信息,默认/etc/ansible/hosts。
-f NUM, --forks=NUM: 并发线程数,默认5个线程。
--private-key=PRIVATE_KEY_FILE: 指定密钥文件。
-m NAME, --module-name=NAME: 指定执行使用的模块。
-M DIRECTORY, --module-path=DIRECTORY: 指定模块存放路径,默认/usr/share/ansible,也可以通过ANSIBLE_LIBRARY设定默认路径。
-a 'ARGUMENTS', --args='ARGUMENTS': 模块参数。
-k, --ask-pass SSH: 认证密码。
-K, --ask-sudo-pass sudo: 用户的密码(—sudo时使用)。
-o, --one-line: 标准输出至一行。
-s, --sudo: 相当于Linux系统下的sudo命令。
-t DIRECTORY, --tree=DIRECTORY: 输出信息至DIRECTORY目录下,结果文件以远程主机名命名。
-T SECONDS, --timeout=SECONDS: 指定连接远程主机的最大超时,单位是:秒。
-B NUM, --background=NUM: 后台执行命令,超NUM秒后kill正在执行的任务。
-P NUM, --poll=NUM: 定期返回后台任务进度。
-u USERNAME, --user=USERNAME: 指定远程主机以USERNAME运行命令。
-U SUDO_USERNAME, --sudo-user=SUDO_USERNAM: 使用sudo,相当于Linux下的sudo命令。
-c CONNECTION, --connection=CONNECTION: 指定连接方式,可用选项paramiko (SSH), ssh, local。Local方式常用于crontab 和 kickstarts。
-l SUBSET, --limit=SUBSET: 指定运行主机。
-l ~REGEX, --limit=~REGEX: 指定运行主机(正则)。
--list-hosts: 列出符合条件的主机列表,不执行任何其他命令
3.2 ansible命令执行流程图
3.3 常用模块介绍
使用ansible-doc -l
可以列出所有ansible支持的模块;
使用ansible-doc 模块名
获取模块帮助信息;
/etc/ansible/hosts文件内容如下:
[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默认使用的就是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 相关的东西.如果你想使用 shell相关的这些东西, 请使用’shell’ 模块。
特别注意:执行ansible命令之前需要将主机清单中所有主机关闭selinux状态置于disabled状态,就是将
/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参数,不写此参数,默认为:
remote_src=no
,将控制主机的src
复制到目标主机的dest
。如果加上参数remote_src=yes
,那么将从远程目标主机的src
复制到远程主机的dest
。
3.3.5 file模块
使用file
模块可以做到修改文件的属主和权限:
$ 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
模块也可以创建目录,与执行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部分内容:
//安装指定版本的软件
- 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
// 升级所有软件包,不包括内核和foo相关的软件包
- name: upgrade all packages, excluding kernel & foo related packages
yum:
name: '*'
state: latest
exclude: kernel*,foo*
// 从远程仓库安装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
// 安装开发环境包组
- 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
模块可以方便的创建账户,删除账户,或是管理现有的账户:
// 添加用户foo
$ ansible all -m user -a "name=foo password=123456"
// 删除用户foo
$ ansible all -m user -a "name=foo state=absent"
// state=absent结合remove=yes使用,相当于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
模块来管理各种服务的启停:
// 开启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>,也就是说,如果某项服务已经开启或关闭,那么就不再继续操作。
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等应用的管理。
新增mysql用户stanley,密码123456,对zabbix.*
表有所有权限,命令如下:
$ 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登录信息完全暴露在命令行,存在很大的安全隐患。如果在远程主机的
~/.my.conf
文件中定义登录用户及密码,则可以在上述命令中省略登录相关信息。
3.3.12 setup模块
获取远程主机的系统信息,这些系统信息在playbook中可以直接当作变量引用,如 {{ ansible_all_ipv4_addresses }}
就可以获取到远程主机的所有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
模块是用来添加或删除定时任务的;
// 添加一个定时任务,每过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
没写,默认等于present
,就是创建定时任务。
删除一个定时任务:
[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
模块是将本地脚本先拷贝一份到目标主机上去执行,执行完成后再将目标主机上的拷贝删除。
// 在目标主机上执行控制机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": []
}
// 验证脚本在目标主机是否执行成功
[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
模块默认情况下,它假定目标主机上存在压缩源;
$ ansible load-node -m archive -a "path=/tmp/test exclude_path=/tmp/test/sub2 format=bz2 dest=/tmp/test.tar.bz2"
- path:指定远程主机上将要压缩的目录或文件;
- exclude_path:指定要排除的文件或目录;
- format:指定压缩格式,choices:gz、bz2、zip、tar、xz (ansible 2.5支持),默认是gz格式;
- dest:压缩后的文件名。
unarchive
模块默认情况下,它将在解包之前将源文件从本地系统复制到目标主机。设置remote_src = yes
将解包目标主机上已有的压缩包。
$ ansible load-node -m unarchive -a "src=/tmp/test.tar.bz2 dest=/root list_files=yes remote_src=yes"
常用模块就介绍这么多,更多模块学习请使用ansible-doc 模块名称
获取帮助。