|
什么是Ansibleansible是新出现的运维工具是基于Python研发的糅合了众多老牌运维工具的优点实现了批量操作系统配置、批量程序的部署、批量运行命令等功能。
Ansible特性基于Python语言实现,由Paramiko, PyYAML和Jinjia2三个关键模块;
ansible是工作在agentless模式下具有幂等性。ansible在控制端只需要告诉监控端的期望状态就可以实现批量部署。
默认使用SSH协议;
(1) 基于密钥认证;
(2) 在inventory文件中指定账号和密码;
基于“模块”完成各种“任务”
支持自定义模块:支持各种编程语言
可以使用YAML语言定制playbook
Ansible架构图
Ansible核心组件说明:
Ansible:Ansible的核心程序
Host Lnventory:记录了每一个由Ansible管理的主机信息,信息包括ssh端口,root帐号密码,ip地址等等。
Playbooks:YAML格式文件,多个任务定义在一个文件中,使用时可以统一调用
Core Modules:Ansible执行任何管理任务都不是由Ansible自己完成,而是由核心模块完成;Ansible管理主机之前,先调用core Modules中的模块,然后指明管理Host Lnventory中的主机,就可以完成管理主机。
Custom Modules:自定义模块,完成Ansible核心模块无法完成的功能
Connection Plugins:连接插件,Ansible和Host通信使用
环境拓扑图
安装AnsibleAnsible在epel的yum中有提供,所以配置好epel源,直接使用yum命令安装即可
1
| [iyunv@node1 ~]# yum -y install ansible
|
查看生成的主要文件
1
2
3
| [iyunv@node1 ~]# rpm -ql ansible
/etc/ansible/ansible.cfg #主配置文件
/etc/ansible/hosts #invertory文件
|
说明:Ansible不是服务,所以不需要服务脚本
配置和被管理的主机直接建立基于ssh的密钥认证
1
2
3
4
| ssh-keygen -t rsa -f ~/.ssh/id_rsa -P ''
ssh-copy-id -i .ssh/id_rsa.pub 172.16.4.101
ssh-copy-id -i .ssh/id_rsa.pub 172.16.4.102
ssh-copy-id -i .ssh/id_rsa.pub 172.16.4.103
|
定义主机,将所有被管理的主机加入到/etc/ansible/hosts中,否则无法管理
1
2
3
4
5
6
| [iyunv@node1 ~]# vim /etc/ansible/hosts
[webserver] #定义一个组
172.16.4.101
172.16.4.102
[dbserver]
172.16.4.103
|
补充:如果没有设置基于ssh的密钥认证,可以在hosts文件中直接指定帐号和密码,方法如下所示:
1
2
3
4
5
| [webserver]
172.16.4.101 ansible_ssh_user=root ansible_ssh_pass=password
172.16.4.102 ansible_ssh_user=root ansible_ssh_pass=password
[dbserver]
172.16.4.103 ansible_ssh_user=root ansible_ssh_pass=password
|
模块使用:如何查看模块帮助:
ansible-doc -l #查看所有模块
ansible-doc -s MODULE_NAME #查看指定模块的详细帮助
ansible命令应用基础:
语法: ansible <host-pattern> [-f forks] [-m module_name] [-a args]
-f forks:启动的并发线程数;
-m module_name: 要使用的模块;
-a args: 模块特有的参数;
常见模块说明:Command功能:命令模块,默认模块,用于在远程主机执行命令,缺点:运行的命令中无法使用变量,管道。
1
2
3
4
5
6
7
8
| [iyunv@node1 ~]# ansible-doc -s command
- name: 在远程节点执行命令
action: command
chdir # 在执行命令之前,先切换到该目录
creates # 一个文件名,当这个文件存在,则该命令不执行
executable # 切换shell来执行命令,需要使用命令的绝对路径
free_form= #要执行的Linux指令,一般使用Ansible的-a参数代替。
removes #一个文件名,这个文件不存在,则该命令不执行
|
示例:查看被管理节点的时间,使用-m使用command模块,-a使用date命令即可
Cron1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| [iyunv@node1 ~]# ansible-doc -s cron
- name: 设置管理节点生成定时任务
action: cron
backup # 如果设置,创建一个crontab备份
cron_file #如果指定, 使用这个文件cron.d,而不是单个用户crontab
day # 日应该运行的工作( 1-31, *, */2, etc )
hour # 小时 ( 0-23, *, */2, etc )
job #指明运行的命令是什么
minute #分钟( 0-59, *, */2, etc )
month # 月( 1-12, *, */2, etc )
name #定时任务描述
reboot # 任务在重启时运行,不建议使用,建议使用special_time
special_time # 特殊的时间范围,参数:reboot(重启时),annually(每年),monthly(每月),weekly(每周),daily(每天),hourly(每小时)
state #指定状态,prsent表示添加定时任务,也是默认设置,absent表示删除定时任务
user # 以哪个用户的身份执行
weekday # 周 ( 0-6 for Sunday-Saturday, *, etc )
|
示例:设置webServer组的主机没10分钟运行一次hello world
删除定时任务的方法如下所示:只需要设置state为absent即可
User1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| [iyunv@node1 ~]# ansible-doc -s user
- name: 管理用户帐号
action: user
comment # 用户的描述信息
createhome # 是否创建家目录
force # 在使用`state=absent'是, 行为与`userdel --force'一致.
group # 指定基本组
groups # 指定附加组,如果指定为('groups=')表示删除所有组
home # 指定用户家目录
login_class #可以设置用户的登录类 FreeBSD, OpenBSD and NetBSD系统.
move_home # 如果设置为`home='时, 试图将用户主目录移动到指定的目录
name= # 指定用户名
non_unique # 该选项允许改变非唯一的用户ID值
password # 指定用户密码
remove # 在使用 `state=absent'时, 行为是与 `userdel --remove'一致.
shell # 指定默认shell
state #设置帐号状态,不指定为创建,指定值为absent表示删除
system # 当创建一个用户,设置这个用户是系统用户。这个设置不能更改现有用户。
uid #指定用户的uid
update_password # 更新用户密码
|
示例:创建一个用户
删除用户
Group1
2
3
4
5
6
7
| [iyunv@node1 ~]# ansible-doc -s group
- name: 添加或删除组
action: group
gid # 设置组的GID号
name= # 管理组的名称
state # 指定组状态,默认为创建,设置值为absent为删除
system # 设置值为yes,表示为创建系统组
|
示例:创建一个mysql组,并添加mysql用户加入到组中
Copy1
2
3
4
5
6
7
8
9
10
11
12
| [iyunv@node1 ~]# ansible-doc -s copy
- name: 将文件复制到被管理主机
action: copy
backup # 创建一个备份文件包括时间戳信息,如果以某种方式重创错了,还可以拿回原始文件
content # 取代src=,表示直接用此处指定的信息生成为目标文件内容;
dest= # 远程节点存放文件的路径,必须是绝对路径
directory_mode # 递归复制设置目录权限,默认为系统默认权限
force # 如果目标主机包含该文件,但内容不同,如果设置为yes,则强制覆盖,如果设置为no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为yes
group # 复制到远程主机后,指定文件或目录的属
mode # 复制到远程主机后,指定文件或目录权限,类似与 `chmod'指明如 0644
owner # 复制到远程主机后,指定文件或目录属主
src # 指定复制的源文件,可以是相对路径或者绝对路径,如果给出的源是目录,那么会把目录下的所有文件都复制过去
|
示例:将本地的/etc/fatab文件复制到目标主机的/tmp/fatab.ansbile,属主为root权限为640
验证:webserver组中的主机/tmp/目录下已经出现fstab.ansbile文件,属主和权限都正确
1
2
| [iyunv@node2 ~]# ll /tmp/fstab.ansbile
-rw-r----- 1 root root 921 Jun 28 14:16 /tmp/fstab.ansbile
|
示例:在webserver组主机创建文件,自己手动指定文件内容。
验证:查看文件内容
1
2
3
| [iyunv@node2 ~]# cat /tmp/test.ansible
Hello Ansible
Hello world[iyunv@node2 ~]#
|
File1
2
3
4
5
6
7
8
9
10
11
| [iyunv@node1 ~]# ansible-doc -s file
- name: 设置文件属性
action: file
force # 需要在两种情况下强制创建软连接,一种是源文件不存在但之后会建立的情况下;另一种是目标连接已存在,需要先取消之前的软连接,有两个选项:yes|no
group # 设置文件或目录的属组
mode # 设置文件或目录的权限
owner # 设置文件或目录的属主
path= # 必选项,定义文件或目录的路径
recurse # 递归设置文件的属性,只对目录有效
src # 要被链接到的路径,只应用与state=link的情况
state # directory:如果目录不存在,创建目录;file:即使文件不存在,也不会被创建;link:创建软连接;hard:创建硬连接;touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间;absent:删除目录、文件或者取消链接文件
|
示例:设置/tmp/fstab.ansbile属主和属组都为mysql,权限为644
示例:在webserver组创建/test/fstab.ansible的连接文件
Ping功能:测试指定主机是否能连接,如果成功返回pong。
Service1
2
3
4
5
6
7
8
9
10
| [iyunv@node1 ~]# ansible-doc -s service
- name: 管理服务
action: service
arguments # 向服务传递的命令行参数
enabled # 设置服务开机自动启动,参数为yes|no
name= # 控制服务的名称
pattern # 定义一个模式,如果通过status指令来查看服务的状态时,没有响应,就会通过ps指令在进程中根据该模式进行查找,如果匹配到,则认为该服务依然在运行
runlevel # 设置服务自启动级别
sleep # 如果执行了restarted,则在stop和start之间沉睡几秒钟
state # 启动`started' 关闭`stopped' 重新启动 `restarted' 重载 `reloaded'
|
查看httpd服务器信息:开机为不启动,当前状态为关闭
示例:启动httpd服务,并设置开机自动启动
Shell功能:执行的命令中有管道或者变量,就需要使用shell
1
2
3
4
5
6
7
8
| [iyunv@node1 ~]# ansible-doc -s shell
- name: Execute commands in nodes.
action: shell
chdir # 执行之前,先cd到指定目录在执行命令
creates # 一个文件名,当这个文件存在,则该命令不执行
executable # 切换shell来执行命令,需要使用命令的绝对路径
free_form= # 执行的命令
removes # 一个文件名,这个文件不存在,则该命令不执行
|
示例:为user1用户设置密码
Script1
2
3
4
5
6
| [iyunv@node1 ~]# ansible-doc -s script
- name: 将本地脚本复制到远程主机并运行之
action: script
creates # 一个文件名,当这个文件存在,则该命令不执行
free_form= # 本地脚本路径
removes # 一个文件名,这个文件不存在,则该命令不执行
|
示例:将本机的test.sh脚本在被管理主机运行
验证:
1
2
3
4
| [iyunv@node2 ~]# ll /tmp/script.ansible
-rw-r--r-- 1 root root 26 Jun 28 15:21 /tmp/script.ansible
[iyunv@node2 ~]# cat /tmp/script.ansible
hello ansible from script
|
yum1
2
3
4
5
6
7
8
9
| [iyunv@node1 ~]# ansible-doc -s yum
- name: Manages packages with the `yum' package manager
action: yum
conf_file # yum的配置文件
disable_gpg_check # 关闭gpg_check
disablerepo # 不启用某个源
enablerepo # 启用某个源
name= # 指定要安装的包,如果有多个版本需要指定版本,否则安装最新的包
state # 安装(`present'),安装最新版(`latest'),卸载程序包(`absent')
|
示例:安装zsh程序包
setup:收集远程主机的facts
每个被管理节点在接收并运行管理命令之前,会将自己主机相关信息,如操作系统版本、IP地址等报告给远程的ansbile主机;
示例:查看172.16.4.101主机状态信息,输出内容很多,但是通俗易懂,这里不做过多说明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
| [iyunv@node1 ~]# ansible 172.16.4.101 -m setup
172.16.4.101 | success >> {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"172.16.4.101"
],
"ansible_all_ipv6_addresses": [
"fe80::20c:29ff:fef1:ddb2"
],
"ansible_architecture": "x86_64",
"ansible_bios_date": "05/20/2014",
"ansible_bios_version": "6.00",
"ansible_cmdline": {
"KEYBOARDTYPE": "pc",
"KEYTABLE": "us",
"LANG": "en_US.UTF-8",
"SYSFONT": "latarcyrheb-sun16",
"crashkernel": "auto",
"quiet": true,
"rd_LVM_LV": "vg0/root",
"rd_NO_DM": true,
"rd_NO_LUKS": true,
"rd_NO_MD": true,
"rhgb": true,
"ro": true,
"root": "/dev/mapper/vg0-root"
},
"ansible_date_time": {
"date": "2015-06-28",
"day": "28",
"epoch": "1435476945",
"hour": "15",
"iso8601": "2015-06-28T07:35:45Z",
"iso8601_micro": "2015-06-28T07:35:45.390263Z",
"minute": "35",
"month": "06",
"second": "45",
"time": "15:35:45",
"tz": "CST",
"tz_offset": "+0800",
"weekday": "Sunday",
"year": "2015"
},
"ansible_default_ipv4": {
"address": "172.16.4.101",
"alias": "eth0",
"gateway": "172.16.0.1",
"interface": "eth0",
"macaddress": "00:0c:29:f1:dd:b2",
"mtu": 1500,
"netmask": "255.255.0.0",
"network": "172.16.0.0",
"type": "ether"
},
"ansible_default_ipv6": {},
"ansible_devices": {
"sda": {
"holders": [],
"host": "SCSI storage controller: LSI Logic / Symbios Logic 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (rev 01)",
"model": "VMware Virtual S",
"partitions": {
"sda1": {
"sectors": "409600",
"sectorsize": 512,
"size": "200.00 MB",
"start": "2048"
},
"sda2": {
"sectors": "125829120",
"sectorsize": 512,
"size": "60.00 GB",
"start": "411648"
}
},
"removable": "0",
"rotational": "1",
"scheduler_mode": "cfq",
"sectors": "377487360",
"sectorsize": "512",
"size": "180.00 GB",
"support_discard": "0",
"vendor": "VMware,"
},
"sr0": {
"holders": [],
"host": "IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)",
"model": "VMware IDE CDR10",
"partitions": {},
"removable": "1",
"rotational": "1",
"scheduler_mode": "cfq",
"sectors": "2097151",
"sectorsize": "512",
"size": "1024.00 MB",
"support_discard": "0",
"vendor": "NECVMWar"
}
},
"ansible_distribution": "CentOS",
"ansible_distribution_major_version": "6",
"ansible_distribution_release": "Final",
"ansible_distribution_version": "6.6",
"ansible_domain": "",
"ansible_env": {
"CVS_RSH": "ssh",
"G_BROKEN_FILENAMES": "1",
"HOME": "/root",
"LANG": "C",
"LC_CTYPE": "C",
"LESSOPEN": "||/usr/bin/lesspipe.sh %s",
"LOGNAME": "root",
"MAIL": "/var/mail/root",
"PATH": "/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin",
"PWD": "/root",
"QTDIR": "/usr/lib64/qt-3.3",
"QTINC": "/usr/lib64/qt-3.3/include",
"QTLIB": "/usr/lib64/qt-3.3/lib",
"SHELL": "/bin/bash",
"SHLVL": "2",
"SSH_ASKPASS": "/usr/libexec/openssh/gnome-ssh-askpass",
"SSH_CLIENT": "172.16.4.100 60862 22",
"SSH_CONNECTION": "172.16.4.100 60862 172.16.4.101 22",
"SSH_TTY": "/dev/pts/0",
"TERM": "linux",
"USER": "root",
"_": "/usr/bin/python"
},
"ansible_eth0": {
"active": true,
"device": "eth0",
"ipv4": {
"address": "172.16.4.101",
"netmask": "255.255.0.0",
"network": "172.16.0.0"
},
"ipv6": [
{
"address": "fe80::20c:29ff:fef1:ddb2",
"prefix": "64",
"scope": "link"
}
],
"macaddress": "00:0c:29:f1:dd:b2",
"module": "e1000",
"mtu": 1500,
"promisc": false,
"type": "ether"
},
"ansible_form_factor": "Other",
"ansible_fqdn": "node2",
"ansible_hostname": "node2",
"ansible_interfaces": [
"lo",
"eth0"
],
"ansible_kernel": "2.6.32-504.el6.x86_64",
"ansible_lo": {
"active": true,
"device": "lo",
"ipv4": {
"address": "127.0.0.1",
"netmask": "255.0.0.0",
"network": "127.0.0.0"
},
"ipv6": [
{
"address": "::1",
"prefix": "128",
"scope": "host"
}
],
"mtu": 65536,
"promisc": false,
"type": "loopback"
},
"ansible_lsb": {
"codename": "Final",
"description": "CentOS release 6.6 (Final)",
"id": "CentOS",
"major_release": "6",
"release": "6.6"
},
"ansible_machine": "x86_64",
"ansible_memfree_mb": 68,
"ansible_memtotal_mb": 474,
"ansible_mounts": [
{
"device": "/dev/mapper/vg0-root",
"fstype": "ext4",
"mount": "/",
"options": "rw",
"size_available": 19614814208,
"size_total": 21003628544
},
{
"device": "/dev/sda1",
"fstype": "ext4",
"mount": "/boot",
"options": "rw",
"size_available": 159812608,
"size_total": 198902784
},
{
"device": "/dev/mapper/vg0-usr",
"fstype": "ext4",
"mount": "/usr",
"options": "rw",
"size_available": 7437721600,
"size_total": 10434699264
},
{
"device": "/dev/mapper/vg0-var",
"fstype": "ext4",
"mount": "/var",
"options": "rw",
"size_available": 19657154560,
"size_total": 21003628544
}
],
"ansible_nodename": "node2",
"ansible_os_family": "RedHat",
"ansible_pkg_mgr": "yum",
"ansible_processor": [
"Intel(R) Core(TM) i5-4200M CPU @ 2.50GHz"
],
"ansible_processor_cores": 1,
"ansible_processor_count": 1,
"ansible_processor_threads_per_core": 1,
"ansible_processor_vcpus": 1,
"ansible_product_name": "VMware Virtual Platform",
"ansible_product_serial": "VMware-56 4d cf 50 b9 67 e1 67-fd ba 73 89 3c f1 dd b2",
"ansible_product_uuid": "564DCF50-B967-E167-FDBA-73893CF1DDB2",
"ansible_product_version": "None",
"ansible_python_version": "2.6.6",
"ansible_selinux": {
"status": "disabled"
},
"ansible_ssh_host_key_dsa_public": "AAAAB3NzaC1kc3MAAACBAJX6mCvtR/7SlWAQtqoJ7fGcOnCQUif9z8BNlTf8Zh0WadsNAOOm6bq48O8FKAuuUl+PDQdvfJteGSb0maqdzBL1A5BaOCIBFLAdcubrSPm9BjBu37M9Dd0/rGzeLmNRpKuEf0VpmJ0QJvp36iDnDsUCtekjrYlhhwcauJUSVqvxAAAAFQDVMMCA/SHSLd8bskYGRZztoVDHewAAAIB16IbxqPLWALteNs8HmFkk2+m43LQ8xJhzAoUB/rBYclWs0W8HHKF98p91rYfwVfitLIZ+S2gFEYxrMrMyRlJNpeChDDeEVZoMyhBeo8Y9PXd4eQCl+FJ2ZQJ31lC0EEB6T+zwdKuP5dQfCaJ7wVNr87UQuQf7t8My3GHkN7ErSAAAAIEAhPngSDosZGPofwHzNJG+dDITWQEJ7cI0tpYJUum0xREDnkYuWUhjI5soR4jotfToUeTwLRxRZMJXA7dCE6NtHJicEbhxiSXHYQUNhQvvrE0/MEvH/BChJK0Nqqt/RxpFNMF2yN5lJPYdufSKd92rgYEMIzELuh21GL6c4iGJWyM=",
"ansible_ssh_host_key_rsa_public": "AAAAB3NzaC1yc2EAAAABIwAAAQEA57ZIETHEsImga9O6N6pHClC6vXfhK01/odan1OdlZnCGTSx3J/fhvNxRidj6YwTb91lahWRRZHOx6EuQ35O4Ba/YVdOF/eF47i/tFNHuo5eEXj2n6fV1mHS97rBc2P+o+2TwL0Ezo9ifXjQPyUHRcCir0abh/if7m/DNfxofY0trW0MKKlA9Ig3CuKrg1k5DUD2HYTS2bbWXDppDG2hpXa6DgxiFO6iLWysR9rw6kY5Aj8WusUpLd2aDkolfIV4zHn2TF6tLP0c1pF2z3u7F5IjOg7aqbEfubmI7mU2d6VPVbxsAakvBNGXoClwt8Skxki1U4u4KXSZ8s/Vq75nRIQ==",
"ansible_swapfree_mb": 2047,
"ansible_swaptotal_mb": 2047,
"ansible_system": "Linux",
"ansible_system_vendor": "VMware, Inc.",
"ansible_user_id": "root",
"ansible_userspace_architecture": "x86_64",
"ansible_userspace_bits": "64",
"ansible_virtualization_role": "guest",
"ansible_virtualization_type": "VMware",
"module_setup": true
},
"changed": false
}
|
补充:
Ansible的跟多功能,如playbook,roles详见下文:
|
|