一、简介
1、ansible 简介
ansible官方的title是“Ansible is Simple IT Automation”——简单的自动化IT工具。这个工具的目标有这么几项:自动化部署APP;自动化管理配置项;自动化的持续交付;自动化的(AWS)云服务管理。
所有的这几个目标本质上来说都是在一个台或者几台服务器上,执行一系列的命令而已,而如果你要管理的服务器是成千上万台的,那你用一台服务器去管理控制这大批量的服务器,势必会造成这台主控机的相当可观的资源消耗和性能的低下(即使可以使用 ansible -f 参数并行执行),这时就需要有种 p2p 的概念,让每一台被同步、配置的服务器也可以做为一台 ansible 中控机去同步配置其它的服务器。
Ansible 无需安装服务端和客户端,只要 SSH 即可。这意 味着,任何一台装有 Ansible 的机器都可以成为强大的管理端。Ansible 上手十分快,用 Ad-Hoc 可以应付简单的管理任务,麻烦点的也可以定义 Playbook 文 件来搞定。
2、强大的自动化运维工具
强大的自动化工具有:ansible,puppet,saltstack
puppet与saltstack这2个软件都需要安装客户端,而saltstack与ansible很相似,都是属于python流的,但saltstack不是很稳定,所以ansible的搜索率是saltstack的3倍也不是没有原因的。puppet虽然稳定,但命令执行的时候,需要配置模块儿,非常麻烦,而且还需要安装客户端,如果公司和别的公司有合作关系的话,很显然,安装客户端是一个不得不考虑的因素;因此,ansible在性能方面并不弱于这两个工具,而且使用还并不繁琐,关键ansible是基于paramiko 开发的,paramiko是一个纯Python实现的ssh协议库。ansible不需要在远程主机上安装client/agents,因为它是基于ssh来和远程主机通讯的。
3、ansible的特点
(1) No agents:不需要在被管控主机上安装任意客户端;
(2) No server:无服务器端,使用时直接运行命令即可;
(3) Modules in any languages:基于模块工作,可使用任意语言开发模块
(4) YAML,not code:使用yaml语言定制剧本playbook;
(5) SSH by default:基于SSH工作;
(6) Strong multi-tier solution:可实现多级指挥;
二、ansible基本使用
1、安装ansible
1
|
[root@localhost ~]
# yum install -y ansible
|
2、主要文件
1
2
3
|
[root@DBSlave ~]
# ls /etc/ansible/
ansible.cfg
#主配置文件,可不修改
hosts
#添加需操作的主机组
|
3、ansible使用格式
1
2
3
4
5
6
7
|
ansible <host-pattern> [-f forks] [-m module_name] [-a args]
host-pattern
# 可以是all,或者配置文件中的主机组名
-f forks
# 指定并行处理的进程数
-m module
# 指定使用的模块,默认模块为command
-a args
# 指定模块的参数
如果你有多台服务器的话,想并发运行,可以使用-f参数,默认是并发5
|
4、查看各模块的使用方法
1
2
3
|
ansible-doc [options] [modules] :Show Ansible module documentation
-l 列出所有的ansible模块
-s 列出该模块的相关指令
|
5、首次使用ansible
(1)安装ansible
1
|
[root@localhost ~]
# yum install -y ansible
|
(2)设置主机组(host-pattern)
1
2
3
4
5
6
7
8
9
10
|
# vim /etc/ansible/hosts
[web servers]
192.168.200.211
192.168.200.212
192.168.200.213
192.168.200.214
[db servers]
192.168.200.215
192.168.200.216
|
(3)创建SSH公钥与私钥
1
|
[root@localhost ~]
# ssh-keygen
|
(4)将公钥文件复制到目标服务器 [注: ssh-copy-id 把公钥追加到远程主机的 .ssh/authorized_key 上.]
1
2
3
4
|
[root@localhost ~]
# ssh-copy-id root@192.168.200.211
[root@localhost ~]
# ssh-copy-id root@192.168.200.212
[root@localhost ~]
# ssh-copy-id root@192.168.200.213
...
|
(5)连接与验证测试
1
|
[root@localhost ~]
# ansible -i /etc/ansible/hosts all -m ping
|
(6)模块儿
查看各模块的使用方法
1
2
3
4
5
|
ansible-doc [options] [modules] :Show Ansible module documentation
-l 列出所有的ansible模块
-s 列出该模块的相关指令
可以直接使用 ansible-doc 模块儿名 来查看模块儿的使用,如
# ansible-doc htpasswd
|
几个示例
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
|
ansible all -a
"/bin/echo hello"
(不写-m,默认模块是shell)
ansible all -m
command
-a
"/bin/echo hello, world"
ansible all -m shell -a
"ping baidu.com -c 1"
ansible all -m
ping
# ping操作 -i 参数可不指定,默认找 /etc/ansible/hosts
ansible
"web servers"
-a
'date'
(可省略-m
command
)
# 执行date命令
ansible
"db servers"
-m copy -a “src=
/root/ansible
.rpm dest=
/tmp/
”
# 复制文件
ansible all -m
cron
-a ‘name=
"custom job"
minute=*
/3
hour=* day=* month=* weekday=* job=
"/usr/sbin/ntpdate 192.168.200.16"
’
# 配置crontab任务
ansible all -m user -a
'name=mysql shell=/sbin/nologin createhome=no'
ansible all -m user -a
"name=tester remove=yes state=absent"
ansible all -m group -a
"name=mysql gid=36 system=yes"
# 创建组
ansible all -m yum -a
"name=httpd state=present"
# 通过yum安装httpd
ansible all -m service -a
"name=httpd state=started enabled=yes"
# 配置服务开启启动
ansible
test
-m
file
-a
'dest=/root/test.txt owner=text group=text mode=644 state=touch'
ansible
test
-m
file
-a
'src=/root/test.txt dest=/tmp/test.txt mode=440 owner=test group=test state=link'
创建递归文件夹
# ansible 192.168.200.225 -m file -a "dest=/tmp/a/b/c owner=root group=root mode=755 state=directory"
192.168.200.225 | success >> {
"changed"
:
true
,
"gid"
: 0,
"group"
:
"root"
,
"mode"
:
"0755"
,
"owner"
:
"root"
,
"path"
:
"/tmp/a/b/c"
,
"size"
: 4096,
"state"
:
"directory"
,
"uid"
: 0
}
查看结果:
192.168.200.225 | success | rc=0 >>
/tmp
|-- a
| `-- b
| `-- c
`-- hsperfdata_root
`-- 14306
4 directories, 1
file
|
常用模块儿
常用的模块:copy、command、service、yum、apt、file、raw、shell、script、cron、user、state、template、
1
2
|
ansible -i
/etc/ansiblehosts
all -m
'service'
-a
'name=httpd state=stoped'
ansible -m yum -a
'name=gcc state=present'
|
yum模块常用来安装软件
service模块常用来对服务的开关操作
shell模块可以用来执行命令以及脚本
raw和command、shell类似,但是它可以传递管道
三、YAML语法
YAML Ain't Markup Language,即YAML不是XML。不过,在开发的这种语言时,YAML的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)。
YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。其结构(Structure)通过空格来展示,序列(Sequence)里的项用"-"来代表,Map里的键值对用":"分隔。下面是一个示例。
YAML文件扩展名通常为.yaml,如example.yaml。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
name: John Smith
age: 41
gender: Male
spouse:
name: Jane Smith
age: 37
gender: Female
children:
- name: Jimmy Smith
age: 17
gender: Male
- name: Jenny Smith
age 13
gender: Female
|
四、ansible playbook(剧本)
playbook使用:ansible-playbook test.yaml
playbook是由一个或多个“play”组成的列表。play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来讲,所谓task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让它们联同起来按事先编排的机制同唱一台大戏
下面就是一个只包含了一个play的playbook,在写playbook的时候,一定要记住在 hosts,yum(模块儿名)等后带空格,否则会报错
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#这个是你选择的主机
- hosts: webservers
#这个是变量
vars:
http_port: 80
max_clients: 200
#远端的执行权限
remote_user: root
tasks:
#利用yum模块来操作
- name: ensure apache is at the latest version
yum: pkg=httpd state=latest
- name: write the apache config
file
template: src=
/srv/httpd
.j2 dest=
/etc/httpd
.conf
#触发重启服务器
notify:
- restart apache
- name: ensure apache is running
service: name=httpd state=started
#这里的restart apache 和上面的触发是配对的。这就是handlers的作用。相当于tag
handlers:
- name: restart apache
service: name=httpd state=restarted
|
1、HOSTS和Users
playbook中的每一个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。
hosts用于指定要执行指定任务的主机,其可以是一个或多个由冒号分隔主机组;
remote_user则用于指定远程主机上的执行任务的用户。如上面示例中的
1
2
|
-hosts: webnodes
remote_user: root
|
不过,remote_user也可用于各task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户。
1
2
3
4
5
6
7
|
- hosts: webnodes
remote_user: root
tasks:
- name:
test
connection
ping
:
remote_user: root
sudo
:
yes
|
2、任务列表和cation
play的主体部分是task list。task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后再开始第二个。在运行自下而下某playbook时,如果中途发生错误,所有已执行任务都将回滚,因此,在更正playbook后重新执行一次即可。
task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致。
每个task都应该有其name,用于playbook的执行结果输出,建议其内容尽可能清晰地描述任务执行步骤。如果未提供name,则action的结果将用于输出。
定义task的可以使用“action: module options”或“module: options”的格式,推荐使用后者以实现向后兼容。如果action一行的内容过多,也中使用在行首使用几个空白字符进行换行。
1
2
3
|
tasks:
- name:
make
sure apache is running
service: name=httpd state=running
|
在众多模块中,只有command和shell模块仅需要给定一个列表而无需使用“key=value”格式,例如:
1
2
3
|
tasks:
- name: disable selinux
command
:
/sbin/setenforce
0
|
如果命令或脚本的退出码不为零,可以使用如下方式替代:
1
2
3
|
tasks:
- name: run this
command
and ignore the result
shell:
/usr/bin/somecommand
||
/bin/true
|
或者使用ignore_errors来忽略错误信息:
1
2
3
4
|
tasks:
- name: run this
command
and ignore the result
shell:
/usr/bin/somecommand
ignore_errors: True
|
3、handlers
用于当关注的资源发生变化时采取一定的操作。
“notify”这个action可用于在每个play的最后被触发,这样可以避免多次有改变发生时每次都执行指定的操作,取而代之,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作。
1
2
3
4
5
|
- name: template configuration
file
template: src=template.j2 dest=
/etc/foo
.conf
notify:
- restart memcached
- restart apache
|
handler是task列表,这些task与前述的task并没有本质上的不同。
1
2
3
4
5
|
handlers:
- name: restart memcached
service: name=memcached state=restarted
- name: restart apache
service: name=apache state=restarted
|
五、playbook案例
1、heartbeat.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
heartbeat.yaml
- hosts: hbhosts
remote_user: root
tasks:
- name: ensure heartbeat latest version
yum: name=heartbeat state=present
- name: authkeys configure
file
copy: src=
/root/hb_conf/authkeys
dest=
/etc/ha
.d
/authkeys
- name: authkeys mode 600
file
: path=
/etc/ha
.d
/authkeys
mode=600
notify:
- restart heartbeat
- name: ha.cf configure
file
copy: src=
/root/hb_conf/ha
.cf dest=
/etc/ha
.d
/ha
.cf
notify:
- restart heartbeat
handlers:
- name: restart heartbeat
service: name=heartbeat state=restarted
|
2、corosync.yaml
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
|
- hosts: hanodes
#指定要执行任务的主机,可由冒号分隔主机组
remote_user: root
#指定远程主机上执行任务的用户
vars:
#定义如下2个变量
crmsh: crmsh-1.2.6.4.el6.x86_64.rpm
pssh: pssh-2.3.1-2.el6.x86_64.rpm
tasks:
#指定需执行的任务列表,每个task都有其name和使用的模块及参数
- name:
test
connection
ping
:
#ping模块无需执行参数
remote_user: jason
#在task中指定远程主机上执行任务的用户
sudo
:
yes
#使用sudo在远程主机上执行任务
- name: corosync installing
yum: name=corosync state=present
- name: pacemaker installing
#定义一个软件安装任务
yum: name=pacemaker state=present
#使用yum安装,并配置需安装的软件名(name),及状态(state)
- name: crmsh rpm packages
copy: src=
/ansible/corosync/packages/
{{ crmsh }} dest=
/tmp/
{{ crmsh }}
- name: pssh rpm packages
copy: src=
/ansible/corosync/packages/
{{ pssh }} dest=
/tmp/
{{ pssh }}
- name: crmsh installing
command
: yum -y reinstall
/tmp/
{{ crmsh }}
/tmp/
{{ pssh }}
- name: authkey configure
file
copy: src=
/ansible/corosync/conf/authkey
dest=
/etc/corosync/authkey
- name: authkey mode 400
#定义一个文件权限设置任务
file
: path=
/etc/corosync/authkey
mode=400
notify:
#定义一个通知,当此任务执行时,可以激发响应的handler
- restart corosync
- name: corosync.conf configure
file
copy: src=
/ansible/corosync/conf/corosync
.conf dest=
/etc/corosync/corosync
.conf
tags:
- conf
notify:
- restart corosync
- name: ensure the corosync service startup on boot
service: name=corosync state=started enabled=
yes
handlers:
#定义当关注的资源发生变化时,需采取的操作
- name: restart corosync
#定义一个服务重启任务
service: name=corosync state=restarted
|