ansible

1、 What is ansible?

Ansible is a radically simple IT automation engine that automates cloud provisioningconfiguration managementapplication deploymentintra-service orchestration, and many other IT needs.

Ansible是一个颠覆性的运维工具,支持云配置、配置管理、应用部署、服务编配等运维工作。

Designed for multi-tier deployments since day one, Ansible models your IT infrastructure by describing how all of your systems inter-relate, rather than just managing one system at a time.

Ansible一开始就是为多层架构设计的,因此Ansible通过描述系统内部关系,进行整体建模。

AnsibleArchitecture

It uses no agents and no additional custom security infrastructure, so it’s easy to deploy - and most importantly, it uses a very simple language (YAML, in the form of Ansible Playbooks) that allow you to describe your automation jobs in a way that approaches plain English.

  • Ansible no agents
  • no additional custom security infrastucture, it use ssh
  • describe automation jobs by yaml

2、How to Ansible?

尽管各种平台的管理工具都可以安装Ansible,但是Ansible是Python开发的,所以Ansible的安装建议尽量使用pip:

1
pip install ansible

如果想使用平台管理工具安装,具体查询官网

检查安装结果:

1
ansible --version

输出结果:

1
2
3
4
5
6
ansible 2.7.6
config file = None
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Nov 6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]

使用pip安装的Ansible没有自动生成配置文件,需要手动生成。使用平台工具安装会自动生成Ansible配置文件。

Ansible的核心是PlaybooksPlaybooks是一个yaml格式的文本文件,用于描述事务状态。Playbooks的使用变量Variables描述,Variables可以在Playbooks、File、Inventories、Command line、Discovered variables、Ansible Tower等中定义。

Inventories类似中药药方,中药药方基本是这么写的:

1
2
3
4
5
当归莲子汤

当归 两钱
莲子 四钱
...

Inventories描述服务器的Host列表、范围、动态范围以及自定义。

Playbooks contain plays

Plays contain tasks

Tasks call modules

Tasks run sequentially

Handlers are triggered by Tasks, and are run once, at the end of Plays

高级Playbooks支持条件触发以及role等特征。定义好Playbooks之后,具体怎么运行Ansible呢?

运行Ansible有三种主流的方式:

  • Ad-Hoc:ansible -m
  • Playbooks:ansible-playbook
  • Automation Framework:Ansible Tower(AWX)

3、Could you give me a demo?

  • 创建ansible目录
1
mkdir -p /etc/ansible
  • 创建ansible.cfg
1
touch /etc/ansible/ansible.cfg
  • 编辑ansible.cfg
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
# config file for ansible -- https://ansible.com/
# ===============================================

# nearly all parameters can be overridden in ansible-playbook
# or with command line flags. ansible will read ANSIBLE_CONFIG,
# ansible.cfg in the current working directory, .ansible.cfg in
# the home directory or /etc/ansible/ansible.cfg, whichever it
# finds first

[defaults]

# some basic default values...

inventory = /etc/ansible/hosts
library = /usr/share/ansible/
#module_utils = /usr/share/my_module_utils/
#remote_tmp = ~/.ansible/tmp
#local_tmp = ~/.ansible/tmp
#plugin_filters_cfg = /etc/ansible/plugin_filters.yml
forks = 5
#poll_interval = 15
sudo_user = root
#ask_sudo_pass = True
#ask_pass = True
#transport = smart
remote_port = 22
#module_lang = C
#module_set_locale = False

[inventory]

[privilege_escalation]

[paramiko_connection]

[ssh_connection]

[persistent_connection]

[accelerate]

[selinux]

[colors]

[diff]

详细配置文件,请参考Github网页

  • 编辑Inventory /etc/ansible/hosts
1
192.168.0.142
  • 使用Ad-hoc方式运行命令:
1
2
3
ansible all -m ping

ansible all -a "/bin/echo hello"

4、Yelp, but how to do with complex deployment?

Playbooks is really good!!!

Playbooks is really good!!!

Playbooks is really good!!!

病比较复杂,就需要一系列工具来辅助治疗。最常用的工具有ansible和ansible-playbook。但是还有很多其他工具,比如:

ansible-config: 用于查看、编辑、和管理ansible配置。

ansible-console:用于执行ansible ad-hoc 的repl console。

ansible-doc:插件文档工具,用于查看ansible modules的描述信息。

ansible-galaxy:ansible执行角色相关的操作。

ansible-inventory:用于查看inventory。

ansible-pull:从VCS仓库拉取playbooks并在本地执行。

ansible-vault:用于ansible数据文件加解密。

工具用的熟就好,但是主要工具不仅要用的熟,还得用的巧。ansible和ansible-playbook就是这样的工具。

ansible:用于定义和执行单一任务

ansible-playbook:运行ansible playbook,在目标主机群上执行定义的任务。

来看两个简单的ansible使用示例:

1
2
ansible all -a "/sbin/reboot" -f 10
ansible all -m shell -a 'echo $TERM'

第一个例子开启10个进程,让所有主机重启。当然,如果all中定义的主机数目小于10,比如5,那么有5个进程就是空闲的。如果all中有12个主机,那么有两个任务会等待。参数 -f 10 用来指定进程数目。

第二个例子打印TERM参数,但是使用-m指定了模块,一般默认的模块是’command’。

这两个都是简单的例子,ansible的模块支持更加复杂的任务。比如文件操作:

1
2
3
ansible all -m copy -a "src=/etc/hosts dest=/tmp/hosts"

# 类似于scp
1
2
3
ansible all -m file -a "dest=/srv/foo/a.txt mode=600"
ansible all -m file -a "dest=/srv/foo/b.txt mode=600 owner=mdehaan group=mdehaan"
# 类似于chmod等命令
1
2
3
ansible webservers -m file -a "dest=/path/to/c mode=755 owner=mdehaan group=mdehaan state=directory"

# 类似于mkdir -p
1
2
3
ansible webservers -m file -a "dest=/path/to/c state=absent"

# 类似于rm

比如管理包:

1
2
3
4
5
6
7
8
ansible webservers -m yum -a "name=acme state=present"
# 确保安装,但是不升级
ansible webservers -m yum -a "name=acme-1.5 state=present"
# 确保安装指定版本
ansible webservers -m yum -a "name=acme state=latest"
# 确保安装最新版本
ansible webservers -m yum -a "name=acme state=absent"
# 确保未安装

比如用户和组的管理:

1
2
3
4
ansible all -m user -a "name=foo password=<crypted password here>"
# 创建用户
ansible all -m user -a "name=foo state=absent"
# 删除用户

比如源码部署:

1
ansible webservers -m git -a "repo=https://foo.example.org/repo.git dest=/srv/myapp version=HEAD"

比如服务管理:

1
2
3
4
5
6
ansible webservers -m service -a "name=httpd state=started"
# 开启
ansible webservers -m service -a "name=httpd state=restarted"
# 重启
ansible webservers -m service -a "name=httpd state=stopped"
# 关闭

比如限时后台任务:

1
2
3
4
5
6
ansible all -B 3600 -P 0 -a "/usr/bin/long_running_operation --do-stuff"
# /usr/bin/long_running_operation一个后台任务,-B表示超时时间,-P表示轮询polling
ansible web1.example.com -m async_status -a "jid=488359678239.2844"
# 使用async_status检查异步任务状态
ansible all -B 1800 -P 60 -a "/usr/bin/long_running_operation --do-stuff"
# 在启动任务的同时开启轮询模式,任务执行30分钟,每60秒检查一次状态

比如获取系统信息:

1
ansible all -m setup

嗯,ansible ad-hoc是很好用,但是我想把任务记录下来,下次直接执行,怎么办呢?

这个就要用到ansible-playbook了,不过我们先来看看inventory。

ansible运行在复杂环境架构中,为了任务管理、运行方便,可以从inventory list中选取需要操作的主机组进行操作。inventory默认的存储文件是/etc/ansible/hosts,不过可以使用-i path进行指定。

inventory支持多文件同时配置,支持动态拉取,支持不同格式的文件。

1
2
3
4
5
6
7
8
9
10
mail.example.com

[webservers]
foo.example.com
bar.example.com

[dbservers]
one.example.com
two.example.com
three.example.com

这是一个ini格式的inventory,[webservers]表示group,可以方便的选取执行相关任务的主机,并且表明主机的用途。yaml格式的像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
all:
hosts:
mail.example.com:
children:
webservers:
hosts:
foo.example.com:
bar.example.com:
dbservers:
hosts:
one.example.com:
two.example.com:
three.example.com:

如果ssh使用的不是标准端口,需要在inventory中标明:

1
badwolf.example.com:5309

inventory支持使用变量定义主机:

1
jumper ansible_port=5555 ansible_host=192.0.2.50
1
2
3
4
5
...
hosts:
jumper:
ansible_port: 5555
ansible_host: 192.0.2.50

inventory支持模式匹配,如果主机类型模式类似,可以像这样:

1
2
[webservers]
www[01:50].example.com
1
2
[databases]
db-[a:f].example.com

inventory支持定义连接类型和用户:

1
2
3
4
5
[targets]

localhost ansible_connection=local
other1.example.com ansible_connection=ssh ansible_user=mpdehaan
other2.example.com ansible_connection=ssh ansible_user=mdehaan

可以在inventory中直接定义变量,但是更常用的方法是在host_vars目录的单独文件中进行定义,然后在inventory中进行引用:

1
2
3
[atlanta]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909
1
2
3
4
5
6
7
[atlanta]
host1
host2

[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com
1
2
3
4
5
6
7
[atlanta]
host1
host2

[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com

host和group均支持变量。但是切记,这只是一种表示方法,实际执行的时候会用literal替代。

inventory有两个默认组:all和ungrouped。all包含所有主机,ungrouped包含没有分组的主机。当然inventory支持更复杂的定义方式,但是,这只是入门级使用手册,不一一赘述。快点进入重点吧,怎么用Playbooks呢?

如果你有一间作坊,那么modules就是你的工具,Playbooks就是你的操作手册,inventory就是原料。

记住,Playbooks是ansible的语言、的语言、的语言…

5、Oh,No!sophisticated Playbooks…

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
- hosts: webservers
remote_user: root

tasks:
- name: ensure apache is at the latest version
yum:
name: httpd
state: latest
- name: write the apache config file
template:
src: /srv/httpd.j2
dest: /etc/httpd.conf

- hosts: databases
remote_user: root

tasks:
- name: ensure postgresql is at the latest version
yum:
name: postgresql
state: latest
- name: ensure that postgresql is started
service:
name: postgresql
state: started

这个Playbooks示例中,有两个play,第一个现在webservers group执行apache安装和配置,第二个在databases group执行postgresql安装和启动。Playbooks顺序执行。

Playbooks contain plays

Plays contain tasks

Tasks call modules

Tasks run sequentially

Handlers are triggered by Tasks, and are run once, at the end of Plays

一个play必须指定目标主机和操作用户,注意是远程操作用户。目标主机通过-hosts指定,操作用户使用remote_user指定,支持细分task指定不同操作用户,支持用户切换。hosts是目标主机的列表,若有多组目标主机,使用冒号分割。一个play可以有多个task,每个task必须指定任务名称,任务调用模块,模块的调用格式为module: options。options分为key-value形式和非key-value形式的。

1
2
3
4
5
6
7
tasks:
- name: make sure apache is running
service:
name: httpd
state: started

# key-value
1
2
3
4
5
tasks:
- name: enable selinux
command: /sbin/setenforce 1

# non key-value

根据上面的两个例子,可以看出options的格式根据modules发生变化。任务可以出发handler,比如两个任务task均涉及到nginx配置文件的修改,在task 的notify中均定义了handler,那么在play执行的最后,将只执行一次handler,避免nginx重复重启。

1
2
3
4
5
6
7
name: template configuration file
template:
src: template.j2
dest: /etc/foo.conf
notify:
- restart memcached
- restart apache
1
2
3
4
5
6
7
8
9
handlers:
- name: restart memcached
service:
name: memcached
state: restarted
- name: restart apache
service:
name: apache
state: restarted

执行Playbooks的命令行:

1
ansible-playbook playbook.yml

一个简单的nginx安装示例:

1
2
3
4
5
6
7
8
- hosts: all
remote_user: root

tasks:
- name: yum install nginx
yum:
name: nginx
state: latest
分享到