一、Ansible简介

Ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。

2015年RedHat收购了Ansible,并且将其多个平台自动化部署方案切换到Ansible。
Ansible官网
https://www.ansible.com/
Ansible帮助文档:http://docs.ansible.com/
RedHat 中国的Ansible支持页面:https://www.redhat.com/zh/technologies/management/ansible

Ansible的优势及特性
Ansible作为一个自动化运维工具,优势总共有一下几点:

* 轻量级:无需在客户端安装 **agent** ,并且也不需要启动服务。
* 配置灵活:Ansible基于SSH工作,可使用系统或自定义模块满足更为灵活的需求。
* 语法简洁:配置语言采用 **yaml** ,用来定义多条任务,语法更为简洁,Ansible简单易懂的自动化语言允许使用人员在很短的时间内完成自动化项目的部署。

二、Ansible的基本结构

* Ansible的核心管理主机:亦可以称为 **管理节点** ,用来管理其他的受控节点。
* 系统模块:Ansible本身自带一些模块,提供一些常用的功能。
* 扩展模块:若Ansible的系统模块无法满足批量化管理的特定需求,则可以添加一些扩展模块。
* 插件:完成模块功能的补充。
* 主机组:用来定义实际管理维护的主机服务器。
* 剧本(playbooks):用来定义多条任务,由Ansible统一去执行。
下载地址:
http://releases.ansible.com/https://github.com/ansible/

下载最新版软件包
安装:
[root@servera ~]# yum -y localinstall ansible-1.9.2-1.el7.noarch ansible-inventory-grapher-1.0.1-2.el7.noarch ansible-lint-2.0.1-1.el7.noarch


三、配置Ansible

1) ssh的基本配置
Ansible是基于ssh来实现批量化的配置,Ansible1.2.1及其之后的版本都会默认启用公钥认证。于是我们可以先来配置下ssh基于公钥的认证。
servera依旧作为管理节点,serverb作为受控节点。在这里我们使用密钥方式来保证servera和serverb的连接。

              ---> serverb
servera
              ---> serverc
[root@servera ~]# ssh-keygen
[root@servera ~]# ssh-copy-id [email protected]
[root@servera ~]# ssh-copy-id [email protected]

* ansible的配置,配置主目录/etc/ansible
ansible.cfg为主配置文件。hosts定义了主机组相关的内容。
[root@servera ~]# cd /etc/ansible/
[root@servera ansible]# vim /etc/ansible/ansible.cfg
private_key_file = /root/.ssh/id_rsa

2)定义inventory文件(定义主机组)

[root@servera ansible]# vim hosts 
[webserver]
node1
node2
[root@servera ansible]# vim /etc/hosts
172.25.1.11 node1
172.25.1.12 node2

测试(可以通过以下指令做简单的测试,具体操作后续分析):
[root@servera ansible]# ansible webserver -m ping
node2 | success >> {
    "changed": false, 
    "ping": "pong"
}
node1 | success >> {
    "changed": false, 
    "ping": "pong"
}
[root@servera ansible]# ansible webserver -m command -a "uptime"
node1 | success | rc=0 >>
 10:25:59 up 12 min,  2 users,  load average: 0.00, 0.01, 0.01

node2 | success | rc=0 >>
 10:25:59 up 12 min,  2 users,  load average: 0.08, 0.03, 0.03


有些时候我们可能会遇到一个问题,如果有个主机重新安装并在“known_hosts”中有了不同的key值记录,这会提示一个错误信息直到被纠正为止。如果有个主机没有在“known_hosts”中被初始化将会导致在交互使用Ansible或定时执行Ansible时对key信息的确认提示。如果你想禁用此项行为并明白其含义,你能够通过编辑 /etc/ansible/ansible.cfg来实现。
[root@servera ansible]# ls
ansible.cfg  hosts  roles
[root@servera ansible]# vim ansible.cfg
[defaults]
host_key_checking = False
[root@servera ansible]# pwd
/etc/ansible

四、ansible命令语法介绍

ansible HOST-PATTERN [-f FORKS] [-M MOD_NAME] [-a MOD_ARGS]
-f FORKS:表示一批处理几台主机,也就是当被管控主机很多时,ansible不是对所有主机同时发起管理操作,而是一批处理几台,然后再换一批,直到所有主机被处理完成,如果不指定,则默认是5台
-m MOD_NAME:指明调用哪个模块执行操作,各个模块所能实现的功能不同,如果不指定,默认是用-m command模块
-a MOD_ARGS:指明使用该模块的执行操作时的参数

列出所有模块:
[root@ansiable ~]# ansible-doc -l
[root@ansiable ~]# ansible-doc yum

五、常用Ansible模块
Ansible可以通过模块的方式来完成一些原理的管理工作,可以通过ansible-doc -l查看到所有自带的模块。 ansible-doc -s 模块名 可以用来查看具体模块对应的用法。

1.ping模块 探测助主机是否在线
[root@ansiable ~]# ansible webserver -m ping

2.command模块 在远程主机执行名,不支持管道,重定向等shell特性
[root@ansiable ~]# ansible webserver -m command -a "uptime"
--无效命令:
[root@ansiable ~]# ansible webserver -m command -a "echo redhat | passwd --stdin root"
常用参数:
chdir=   表示指明命令在远程主机上哪个目录下运行,也就是在命令执行前切换到哪个目录下
creates=   在命令运行时创建一个文件,如果文件已存在,则不会执行创建任务
removes=   在命令运行时移除一个文件,如果文件不存在,则不会执行移除任务
executeble=   指明运行命令的shell程序
[root@ansiable ~]# ansible webserver -m command -a 'chdir=/tmp ls ./'
node1 | success | rc=0 >>
zabbix_server.log
node2 | success | rc=0 >>
systemd-private-gFvMoV

不支持管道和重定向:
[root@ansiable ~]# ansible webserver -m command -a 'echo  "hello" > /tmp/aa.txt'

判断是否能够新建aa.txt(不会新建文件)

[root@serverb tmp]# touch aa.txt
[root@ansiable ~]# ansible webserver -m command -a 'chdir=/tmp ls ./ creates=aa.txt'
node2 | success | rc=0 >>
systemd-private-gFvMoV

node1 | success | rc=0 >>
skipped, since aa.txt exists
[root@ansiable ~]# ansible webserver -m command -a 'chdir=/tmp ls ./ removes=aa.txt'


3.shell模块
在远程主机执行命令,相当于调用远程主机的shell进程,然后在该shell下打开一个子shell运行命令
支持shell特性,如管道,重定向等

[root@ansiable ~]# ansible webserver -m shell -a "echo hello > /tmp/aa.txt"
[root@ansiable ~]# ansible webserver -m shell -a "cat /tmp/aa.txt"
node2 | success | rc=0 >>
hello
node1 | success | rc=0 >>
hello


4.copy模块
拷贝ansible管理端的文件到远程主机的指定位置
常见参数有:
        dest=   指明拷贝文件的目标目录位置,使用绝对路径,如果源是目录,则目标也要是目录,如果目标文件已存在,会覆盖原有内容
        src=   指明本地路径下的某个文件,可以使用相对路径和绝对路径,支持直接指定目录,如果源是目录,则目标也要是目录
        mode=   指明复制时,目标文件的权限
        owner=   指明复制时,目标文件的属主
        group=   指明复制时,目标文件的属组
        content=  指明复制到目标主机上的内容,不能与src一起使用,相当于复制content指明的数据,到目标文件中

[root@ansiable ~]# ansible webserver -m copy -a "src=/root/anaconda-ks.cfg dest=/tmp/ks.cfg mode=600 owner=root group=nobody"
[root@ansiable ~]# ansible webserver -m command -a 'chdir=/tmp ls -l ./ks.cfg'
node1 | success | rc=0 >>
-rw-------. 1 root nobody 9462 Oct 17 11:08 ./ks.cfg
node2 | success | rc=0 >>
-rw-------. 1 root nobody 9462 Oct 17 11:08 ./ks.cfg


记住: 不能与src一起使用
[root@ansiable ~]# ansible webserver -m copy -a 'content="hello hugo" dest=/tmp/abc.txt'

5.cron模块
管理计划任务的模块
        常见参数有:
        minute=  指明计划任务的分钟,支持格式:0-59,*,*/2等,与正常cron任务定义的一样的语法,省略时,默认为*,也就是每分钟都执行
        hour=  指明计划任务的小时,支持的语法:0-23,*,*/2等,省略时,默认为*,也就是每小时都执行
        day=  指明计划任务的天,支持的语法:1-31,*,*/2等,省略时,默认为*,也就是每天都执行
        month=  指明计划任务的月,支持的语法为:1-12,*,*/2等,省略时,默认为*,也就是每月都执行
        weekday=  指明计划任务的星期几,支持的语法为:0-6,*等,省略时,默认为*,也就是每星期几都执行
        reboot  指明计划任务执行的时间为每次重启之后
      name=   给该计划任务取个名称,必须要给明。每个任务的名称不能一样。删除任务时,只需要给明任务的名称即可
        job=  执行的任务是什么,当state=present时才有意义
        state=present|absent   表示这个任务是创建还是删除,present表示创建,absent表示删除,默认是present

注意: 给该计划任务取个名称,必须要给明

[root@ansiable ~]# ansible webserver -m 
cron -a 'minute=*/5 hour=* day=17 month=10 weekday=* name="test crontab"
 job="touch /opt/test.out" state=present'
[root@ansiable ~]# ansible webserver -m shell -a "crontab -l"
node1 | success | rc=0 >>
#Ansible: test crontab
*/5 * 17 10 * touch /opt/test.out
node2 | success | rc=0 >>
#Ansible: test crontab
*/5 * 17 10 * touch /opt/test.out


删除

[root@ansiable ~]# ansible webserver -m cron -a 'name="test crontab" state=absent'
node2 | success >> {
    "changed": true, 
    "jobs": []
}
node1 | success >> {
    "changed": true, 
    "jobs": []
}
[root@ansiable ~]# ansible webserver -m shell -a "crontab -l"
node1 | success | rc=0 >>

node2 | success | rc=0 >>


6.fetch模块
从远程主机拉取文件到本地
        一般情况下,只会从一个远程节点拉取数据
        常见参数有:
        dest=  从远程主机上拉取的文件存放在本地的位置,一般只能是目录
        src=   指明远程主机上要拉取的文件,只能是文件,不能是目录
[root@ansiable ~]# ansible node1 -m fetch -a "src=/tmp/a1.txt dest=/opt/"
[root@ansiable ~]# find /opt/node1/
/opt/node1/
/opt/node1/tmp
/opt/node1/tmp/a1.txt

7.file模块
用于设定远程主机上的文件属性
        常见参数有:
        path=   指明对哪个文件修改其属性
        src=   指明path=指明的文件是软链接文件,其对应的源文件是谁,必须要在state=link时才有用
        state=directory|link|absent   表示创建的文件是目录还是软链接
        owner=   指明文件的属主
        group=   指明文件的属组
        mode=   指明文件的权限

        创建软链接的用法:
            src=  path=  state=link
        修改文件属性的用法:
            path=  owner=  mode=  group=
        创建目录的用法:
            path=  state=directory
        删除文件:
            path= state=absent

新建软连接:
[root@ansiable ~]#  ansible webserver -m file -a 'src=/tmp/aa.txt path=/home/test.link state=link'
删除:
[root@ansiable ~]#  ansible webserver -m file -a 'path=/home/test.link state=absent'
修改文件属性:
[root@ansiable ~]# ansible webserver -m file -a 'path=/tmp/aa.txt owner=nobody group=nobody mode=000'
创建目录:
[root@ansiable ~]# ansible webserver -m file -a 'path=/tmp/dir state=directory'


8.hostname模块
       管理远程主机上的主机名
       常用参数有
       name=  指明主机名

[root@ansiable ~]# ansible node1 -m hostname -a "name=node1.ansible.com"
node1 | success >> {
    "changed": true, 
    "name": "node1.ansiable.com"
}
[root@ansiable ~]# ansible node2 -m hostname -a "name=node2.ansible.com"
node2 | success >> {
    "changed": true, 
    "name": "node2.ansiable.com"
}


9.yum模块
基于yum机制,对远程主机管理程序包
        常用参数有:
        name=   指明程序包的名称,可以带上版本号,不指明版本,就是默认最新版本。
        state=present|latest|absent   指明对程序包执行的操作,present表示安装程序包,latest表示安装最新版本的程序包,absent表示卸载程序包
        disablerepo=    在用yum安装时,临时禁用某个仓库,仓库的ID
        enablerepo=    在用yum安装时,临时启用某个仓库,仓库的ID
        conf_file=   指明yum运行时采用哪个配置文件,而不是使用默认的配置文件
        diable_gpg_check=yes|no  是否启用gpg-check
注意区别:
[root@ansiable ~]# ansible webserver -m yum -a "name=nmap disable_gpg_check=yes disablerepo=yum  state=present"   #yum指向配置文件里的标签[yum]
[root@ansiable ~]# ansible webserver -m yum -a "name=nmap disable_gpg_check=yes   state=present"
[root@ansiable ~]# ansible webserver -m yum -a "name=nmap disable_gpg_check=yes   state=absent"

10.service模块
用来管理远程主机上的服务的模块
        常见参数有:
        name=   被管理的服务名称
        state=started|stopped|restarted   表示启动或关闭或重启
        enabled=yes|no  表示要不要设定该服务开机自启动
        runlevel=   如果设定了enabled开机自动启动,则要定义在哪些运行级别下自动启动

[root@ansiable ~]# ansible webserver -m shell -a "yum -y install vsftpd"
[root@ansiable ~]# ansible webserver -m service  -a "name=vsftpd state=started"
node2 | success >> {
    "changed": true, 
    "name": "vsftpd", 
    "state": "started"
}

node1 | success >> {
    "changed": true, 
    "name": "vsftpd", 
    "state": "started"
}
[root@ansiable ~]# ansible webserver -m service  -a "name=vsftpd enabled=yes"


11. uri模块
        如果远端是web服务器,可以利用ansible直接请求某个网页
        常见参数有:
        url=  指明请求的url的路径,如:
http://10.1.32.68/test.jpg
        user=  如果请求的url需要认证,则认证的用户名是什么
        password=  如果请求的url需要认证,则认证的密码是什么
        method=  指明请求的方法,如GET、POST…
        body=   指明报文中实体部分的内容,一般是POST方法或PUT方法时用到
        HEADER_   自定义请求报文中的添加的首部
注意: 安装模块
[root@node1 ~]# yum localinstall python-
httplib2-0.7.7-3.el7.noarch.rpm
[root@ansiable pkg]#  ansible webserver -m uri -a 'url=http://172.25.1.11/test.html'

12 模块 group
13 模块 user

[root@ansiable ~]# ansible webserver -m group -a "name=tomcat gid=888 state=present"
[root@ansiable ~]# ansible webserver -m shell -a "tail -1 /etc/group"
node2 | success | rc=0 >>
tomcat:x:888:
node1 | success | rc=0 >>
tomcat:x:888:
[root@ansiable
 ~]# ansible webserver -m user -a "name=tomcat uid=888 group=tomcat 
comment="apache-tomcat" shell=/bin/bash state=present"
--直接覆盖修改:
[root@ansiable
 ~]# ansible webserver -m user -a "name=tomcat uid=888 group=tomcat 
comment="apache-tomcat" shell=/sbin/nologin state=present"
[root@ansiable ~]# ansible webserver -m group -a "name=testgroup gid=2000 state=present"
 --设置明文密码:
[root@ansiable
 ~]# ansible webserver -m user -a 'name=testuser group=testgroup 
uid=2000 home=/home/testuser shell=/sbin/nologin system=yes 
comment=testtest password=123'
[root@ansiable ~]# ansible webserver 
-m user -a 'name=testuser group=testgroup uid=2000 home=/home/testuser 
shell=/sbin/nologin system=yes comment=testtest 
password=$1$ty46Y/$YZBMaOM9qGUkETZtA/M4e1'


14 模块: script
[root@ansiable ~]# ansible webserver -m script -a "/root/test.sh"

15 模块: setup  --获取主机信息(变量)
[root@ansiable ~]# ansible webserver -m setup

16 模块: template
模板
[root@ansiable ~]# vim temp.txt
my hostname ` ansible_hostname `