1 概述


1. 关于Ansible

Ansible是一个IT自动化工具,它能够配置系统、部署软件以及持续性部署、零宕机滚动升级等高阶的IT任务,是系统运维员、开发人员、IT管理者的自动化解决方案的不二选择。

Ansible的特性之一是agentless,即不需要在受控机器上安装任何的客户端软件,而是通过使用SSH来进行通信和命令执行等。这样避免了额外开放端口(只使用SSH的22端口),提高了安全性,并且避免了“管理管理软件”的自动化配置管理软件的硬伤(如saltstack、puppet等)以及再利用了CPU循环。


2. 与salt的区别

与Salt强大的自动化管理和命令执行功能类似,Ansible也具有这些功能。但不同于Salt的master/minion的管理方式,Ansible基于非常安全的OpenSSH来管理受控端和进行通信、推送命令等,是一种无客户端的管理方式,从而避免了对其本身的管理,简化了自动化配置管理的执行过程。


执行速度方面,由于Salt是使用0mq来作为其消息传递机制,其速度非常的快,而Ansible默认是依赖SSH作为传输层,其速度要慢于Salt。不过Ansible也支持所谓的Fireball Mode,Fireball Mode使用SSH来自启动一个短暂的0mq守护进程(ephemeral 0mq daemon),其速度几乎与Salt无异。


安全性方面,由于0mq天生不支持加密,所以Salt使用自己的AES加密技术来保护有效载荷,然而在其最近的代码中发现了一个缺陷,这个缺陷会导致一些安全问题。Ansible由于使用安全的OpenSSH,其安全性得到有效的保证。考虑到Fireball Mode,Ansible的0mq AES加密的实现是通过keyczar而不是一个本地的解决方案,默认是不使能的,而且其连接由于是瞬时的,也提高了其安全性。


2 安装配置


1. 安装

Ansible是基于Python开发的,可以直接使用easy_install/pip来安装:

easy_install ansible

或者:

pip install ansible

由于Ansible也会需要使用到以下模块,所以一并安装:

pip install paramiko PyYAML jinja2 httplib2

其中Ansible的playbook是YAML格式,所以需要PyYAML的支持。


Ansible的代码也会托管在github上,所以也可以直接从Git资源库中克隆镜像到本地来安装使用


git clone git://github.com/ansible/ansible.git

cd ./ansible

source ./hacking/env-setup


对于特定的Linux发行版本,可以使用rpm(yum)或者dpkg(apt-get)等软件来安装:

yum install ansible        #RHEL/CentOS/Fedora,需要配置好EPEL

apt-get install ansible    #Debian/Ubuntu/LinuxMint

emerge -avt ansible        #Gentoo/Funtoo


ps:

  1. 受控端需要安装Python 2.4及以上版本,如果低于2.5,需要安装python-simplejson

  2. 远程受控机器上使能了SELinux的,在使用copy/file/template等相关的函数前,需要安装libselinux-python模块。如果是使用yum等软件来安装的Ansible就不需要上述操作



2. 配置

SSH authorized_keys文件:Ansible主机和各个受控端之间由于是通过SSH进行通信,为避免频繁的输入密码,可事先打通无密码SSH登录,将认证写入到主机的authorized_keys文件中


ansible.cfg文件:Ansible会执行以下的顺序来查找其配置文件:

    ANSIBLE_CONFIG    环境变量指定的位置

    ansible.cfg    当前目录下

    .ansible.cfg    用户家目录下

    /etc/ansible/ansible.cfg


Inventory文件:Inventory文件用来定义要管理的主机,默认保存为/etc/ansible/hosts,如果不存在,需要手动创建。格式为ini格式,hosts文件采用分组模式,分组也可以嵌套使用:

[local]

localhost

[vnode]

vm1

vm2

vm3

vm4

分组嵌套:

[vnode:CentOS]

vm1

vm2

[vnode:Ubuntu]

vm3

vm4

通过数字和字母模式来指定一系列连续主机:

[1:3].sysu        #等价于1.sysu,2.sysu,3.sysu

[a:c].sysu        #a.sysu,b.sysu,c.sysu


3. 验证使用

Ansible使用/usr/bin/ansible来执行一些命令,验证Ansible是否能正常工作:

ansible all -m ping -u root

vm1 | success >> {
    "changed": false,
    "ping": "pong"
}

localhost | success >> {
    "changed": false,
    "ping": "pong"
}


vm2 | success >> {
    "changed": false,
    "ping": "pong"
}

.......


4. 使用Ad-Hoc执行简单任务


Ansible中的临时命令的执行是通过Ad-Hoc来完成,能够快速执行,而且不需要保存执行的命令,例如:

ansible -i ~/hosts all -m command -a ‘who’ -u root

主要参数如下:

-u username     指定ssh连接的用户名,即执行后面命令的用户

-i inventory_file    指定所使用的inventory文件的位置,默认为/etc/ansible/hosts

-m module        指定使用的模块,默认为command

-f 10        指定并发数

--sudo [-k]        当需要root权限执行的化,-k参数用来输入root密码


查看远端机器vm1的uptime:

vm1 | success | rc=0 >>
 10:54:25 up  1:07,  1 user,  load average: 0.00, 0.00, 0.00


Ansible的更多模块可以查看以下文档:modules


5. 使用playbook管理复杂任务


类似于Salt的状态管理(sls),Ansible通过playbook来定义一个脚本或者配置文件,通过这个YAML格式的文件,Ansible可以执行需反复执行、较为复杂的任务。

playbook是Ansible真正强大的地方,是Ansible的配置、部署、流程化语言,它允许使用变量、条件、循环以及模板,也能通过角色以及包含指令来重用既有内容。

示例:cat playbook.yml

---
- hosts: vnode        #hosts中定义的主机
  remote_user: root    #远程执行的用户,如果和当前用户一致,则无需指定
  tasks:                        
    - name: whoami
      copy:src=~/hosts dest=~/hosts.deny

      notify:

            - clear copy

    handlers:

            - name:clear copy

              shell:'mv ~/hosts.dest hosts.del'        #假装删除


注解:

  1. tasks定义了playbook中要执行的任务,包括任务名name以及具体的任务内容

  2. notify:类似于Salt的require,表示当前面的任务完成后且有相应的变化时调用后面定义的handler

  3. handlers:与notify结合使用,被调用的handler的具体定义


Include

Ansible通过playbook的定义来管理一系列的复杂任务,当工作越来越复杂时,将会产生大量的YAML文件。通过include语句,Ansible能够重用这些文件,并在这些文件中形成一定的组织关系。类似于c等语言的include声明语句,ansible的include语句能够在某个task中包含另外的yml文件,从而达到复用的效果,简化了Playbook的结构。

示例:cat tasks/foo.yml

- name: placeholder foo

  command: /bin/foo

通过include将上述yml包含在bar.yml中:

tasks:

    - include:tasks/foo.yml

include也可以被使用在handlers部分,比如要定义如何重启apache服务:

cat handlers/handlers.yml

- name:restart apache

  service:name=apache state=restarted

在主playbook文件的底部添加以下语句来包含上述的handlers:

handlers:

    - include:handlers/handlers.yml


Roles:

Ansible通过Roles来更加高效的组织Playbook。通过角色定义,Roles能够实现自动加载某些vars_files,tasks,handlers,而且能够非常简单的实现在不同用户间的群组内容的共享。

Ansible主要是通过一个inventory来定义role和主机之间的匹配,通过一个ini风格的配置文件来管理所有的主机,通过一个 group_vars下与主机组同名的文件来管理变量,或者host_vars下与主机同名的文件来管理变量(和pillar类似),然后按照固定的目录 结构在角色名目录下创建好files, handlers, tasks, templates, vars(角色级别的变量)等目录;最后通过ansible命令再跟一系列的参数指定好inventory, playbooks, user等来触发对所有主机的配置。

通过Roles组织起来的Ansible项目结构示例:

site.yml
webservers.yml
fooservers.yml
roles/
   common/
     files/
     templates/
     tasks/
     handlers/
     vars/
     meta/
   webservers/
     files/
     templates/
     tasks/
     handlers/
     vars/
     meta/

playbook中表示为:

---
- hosts: webservers
  roles:
     - common
     - webservers

更多详细细节可参考官方文档:Roles and Include statements 

                                                                                                                              ——游响云停