相信大家对运维这个词都比较熟悉,何为运维? 运维就是保障服务器资源安全,稳定,合理。 但是安全稳定不易,合理更难。在达到该目标之前, 运维人员会运用各种工具来方便自己管理服务器资源,最简单基础的就是Shell,在Shell中定义好自己的各种功能,需要时执行即可, 但面对大型的运维环境,光靠Shell是有些力不从心的,还需要一些更强大方便的工具, 如常用的脚本语言Ruby,Python等,当然还有些专门为运维人员准备的工具, 如Fabric, SaltStack,Ansible等,本文将对Ansible进行探讨。
Ansible是一个基于SSH的自动化运维工具, 使用python编写。由于基于SSH, 因此不需要在远程主机上安装额外的软件。
安装Ansible之前,需安装 Python2.6或2.7, 并支持各种安装。 如在Centos上,可以直接使用yum安装:
yum install ansible
安装好后,可初试一下ansible使用:
ansible -i hosts haolin-apps -m ping
haolin-apps | success >> {
"changed": false,
"ping": "pong"
}
-i hosts指定了主机配置文件, haolin-apps则为其中的一个主机或主机组, -m ping表示执行ping模块。
* ANSIBLE_CONFIG (环境变量)
* ansible.cfg (当前目录)
* .ansible.cfg (用户主目录)
* /etc/ansible/ansible.cfg
* ansible.cfg (当前目录)
* ANSIBLE_CONFIG (环境变量)
* .ansible.cfg (用户主目录)
* /etc/ansible/ansible.cfg
Ansible执行任务前,需要先加载Inventory信息, 默认文件为/etc/ansible/hosts, 可通过-i参数指定,格式大概如下:
test
[api]
api01
api02
[db]
db01
db02
[all:children]
api
db
..
test定义了一个主机, api定义了一个主机组, 包含主机api01和api02 all定义了一个父主机组, 其包含了子主机组api,db。
主机和主机组均支持定义额外的变量,如
# 主机变量
[atlanta]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909
# 主机组变量
[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com
当主机信息变得越来越多时,单个文件就比较难以维护,而应该采用多个文件来存储, 建议可以在Ansible配置文件中添加inventory目录:
[defaults]
# ansible 1.9 之前叫hostfile
inventory = /path/to/inventory
这样Ansible会合并/path/to/inventory目录下的主机文件。
上面使用命令行方式(Ad-Hoc)运行了Ansible任务, 但实际中这样做是很少的,往往任务不会只有一个,而常会执行多个任务,于是需要一种描述语言来描述一些列任务的执行, 这就是Playbook。 Playbook使用YAML文件格式编写,如:
---
- hosts: webservers # 主机列表
vars: # 变量
http_port: 80
max_clients: 200
remote_user: root # ssh用户
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
notify:
- restart apache
- name: ensure apache is running (and enable it at boot)
service: name=httpd state=started enabled=yes
handlers: # 通知处理器
- name: restart apache
service: name=httpd state=restarted
Playbook主要由几部分组成: hosts(任务执行的目标主机), vars(任务执行上下文的变量信息), tasks(任务执行列表)和handlers(任务执行完成的通知处理器)。 上面的Playbook 将以root用户在webservers服务器上执行一些列任务: yum安装最新apache包, 配置httpd, 重启apache, 开机自启动apache。
可以通过ansible-playbook执行编写好的Playbook:
ansible-playbook -i [inventory] my_playbook.yml
Ansible提供了很多可用的模块, 这些模块可以直接在远程主机上执行,如上面的Playbook使用到了 yum, template, service模块。
当编写的Playbook越来越多,则需要一种更好的方式来组织这些Playbook,这时就需要Roles。 Roles规范出了Playbook的一些通用目录,在运行Playbook时,会自动加载这些目录中的信息,目录列表大致如:
site.yml
webservers.yml
fooservers.yml
roles/
common/
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
webservers/
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
上面目录中,包含两个角色common和webservers, 每个角色包含一些可选的目录,在Playbook中可以调用角色:
---
- hosts: webservers
roles:
- common
- webservers
Playbook执行中,会使用对应角色目录下的文件, tasks/main.yml存放任务列表, handlers/main.yml存放处理器列表, vars/main.yml存放变量, defaults/main.yml存放默认变量(优先级最低), meta/main.yml存放角色依赖关系, files/存放文件复制操作中使用到的文件(此时可以仅指定文件名,而不需要绝对路径), templates/存放template模块操作的模板文件。
调用角色时,可以传递一些额外参数,如:
- hosts: webservers
roles:
- common
- { role: role_one, dir: '/opt/a', port: 5000 } # 定义变量dir,port
- { role: role_two, when: "ansible_os_family == 'RedHat'" } # 增加条件限制
可以在meta/main.yml中定义角色依赖关系,如:
---
dependencies:
- { role: common, some_parameter: 3 }
- { role: apache, port: 80 }
- { role: postgres, dbname: blarg, other_parameter: 12 }
使用Role组织脚本是官方强烈推荐的, 实际中,应尽量做到Role细粒度化, 需要执行某些任务时,则将这些Role进行自由组合来达到目的, 以实现复用。
Ansible提供了一个第三方Role平台Ansible Galaxy,可以通过ansible-galaxy安装使用。