Ansible常用模块和高级应用

本节所讲内容: 集中化管理平台Ansible的讲解与实战 ansible自动化环境搭建 用ansible自动化部署apache实战

Ansible官网:https://www.ansible.com/ Ansible在线文档:http://docs.ansible.com/ansible/index.html Ansible中文权威指南:http://www.ansible.com.cn/ Ansibl Playbook分享平台:https://galaxy.ansible.com/

Ansible 简介:

​ Ansible是一种集成IT系统的配置管理、应用部署、执行特定任务的开源平台,是由Cobbler和Func的作者于2012年创立的AnsibleWorks公司名下的项目,于2015年被RedHat收购。 Ansible基于Python语言实现,由Paramiko和PyYAML两个关键模块构建。

具有如下特点:

  • 部署简单,只需在主控端部署Ansible环境,被控端无需做任何操作;
  • 默认使用SSH协议对设备进行管理;
  • 主从集中化管理;
  • 配置简单、功能强大、扩展性强;
  • 支持API及自定义模块,可通过Python轻松扩展;
  • 通过Playbooks来定制强大的配置、状态管理;
  • 对云计算平台、大数据都有很好的支持;

Ansible的架构图如下:

ansible1

ansible core : ansible 自身核心模块
host inventory: 主机库,定义可管控的主机列表
connection plugins: 连接插件,一般默认基于 ssh 协议连接
modules:core modules ( 自带模块 ) 、custom modules ( 自定义模块 )
playbooks :剧本,按照所设定编排的顺序执行完成安排任务

​ Ansible与Saltstack和puppet的最大区别是Ansible无需在被控端部署任何客户端代理,默认直接通过SSH通道进行远程命令的执行或下发配置;相同点都是具备功能强大、灵活的的系统管理、状态配置,都使用YAML格式来描述配置,都具有丰富的模板及API。

​ Ansible提供了一个在线的Playbook分享平台,地址是:https://galaxy.ansible.com/,该平台汇聚了各类常用功能的角色,找到适合自己的Role(角色)后,只需要运行“ansible-galaxy install 作者id.角色包名称”就可以安装到本地。

**环境 ** 系统版本: [root@centos6-130-130 ansible]# ansible --version ansible 2.5.5

系统版本:CentOS release 6.5 (Final) 服务端: 192.168.10.129 客户端: 192.168.10.130 192.168.10.131

一.服务端进行安装ansible 服务:

1.需要进行安装epel源

[root@centos6-130-130~]# wget http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
[root@centos6-130-130~]# ls
anaconda-ks.cfg  epel-release-6-8.noarch.rpm  install.log  install.log.syslog
 [root@centos6-130-130~]# rpm -ivh epel-release-6-8.noarch.rpm 
warning: epel-release-6-8.noarch.rpm: Header V3 RSA/SHA256 Signature, key ID 0608b895: NOKEY
Preparing...    ########################################### [100%]
1:epel-release   ########################################### [100%]
生成缓存
[root@centos6-130-130 ~]# yum makecache
[root@centos6-130-130 ~]#  yum list | grep ansible
ansible.noarch                                 2.5.5-1.el6                  epel
ansible-doc.noarch                             2.5.5-1.el6                  epel
ansible-inventory-grapher.noarch               2.4.4-1.el6                  epel
ansible-lint.noarch                            3.4.21-1.el6                 epel
python2-ansible-tower-cli.noarch               3.1.7-1.el6                  epel

2.部署ansible

安装ansible
[root@centos6-130-130 ~]# yum install -y ansible
创建应用于存放ansible文件的目录,这里存放在
[root@centos6-130-130 ansible]# pwd
/opt/ansible
创建hosts 文件,定义主机群组
[root@centos6-130-130 ansible]# cat hosts 
[web]   #主机群组名称
192.168.10.131 #IP地址或主机名称
192.168.10.132

3.ansible 通讯加密设置

Ansible 使用ssh 协议进行通信,为了方便进行测试使用,ansible想要进行统一进行部署管理,需要进行免密认证。

[root@centos6-130-130 ~]# ssh-keygen -t rsa -P ""
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Created directory '/root/.ssh'.
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
db:da:0d:58:23:c1:2a:b6:2f:0b:9d:3d:f6:01:b6:fd root@centos6-130-130.com
The key's randomart image is:
+--[ RSA 2048]----+
|        o        |
|       . .       |
|    o + S o      |
|   o * + * .     |
|  . + = = o      |
|   ..o o = o     |
|    .o. o E .    |
+-----------------+
由于最小化安装	系统,ssh-copy-id 命令是没有的,需要单独的进行安装。
[root@centos6-130-130 ~]# yum -y install openssh-clients
把公钥发布到客户端服务器上,保证服务端能够正常登陆。
[root@centos6-130-130 ~]# ssh-copy-id  -i ~/.ssh/id_rsa.pub  192.168.10.131
The authenticity of host '192.168.10.131 (192.168.10.131)' can't be established.
RSA key fingerprint is 13:86:c3:34:61:1c:f4:85:30:e3:8e:81:bd:9a:7b:3e.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.10.131' (RSA) to the list of known hosts.
root@192.168.10.131's password: 
Now try logging into the machine, with "ssh '192.168.10.131'", and check in:
  .ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.

[root@centos6-130-130 ~]# ssh-copy-id  -i ~/.ssh/id_rsa.pub  192.168.10.132
The authenticity of host '192.168.10.132 (192.168.10.132)' can't be established.
RSA key fingerprint is 13:86:c3:34:61:1c:f4:85:30:e3:8e:81:bd:9a:7b:3e.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.10.132' (RSA) to the list of known hosts.
root@192.168.10.132's password: 
Now try logging into the machine, with "ssh '192.168.10.132'", and check in:
  .ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.

测试免密登陆:
[root@centos6-130-130 ~]# ssh root@192.168.10.131
Last login: Mon Aug 13 08:56:42 2018 from 192.168.10.1
 [root@centos6-130-130 ~]# ssh root@192.168.10.132
Last login: Mon Aug 13 08:56:48 2018 from 192.168.10.1

4.测试机器连通性

[root@centos6-130-130 ansible]# ansible -i hosts  web -m ping 
192.168.10.131 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.10.132 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

5.Ansible 语法

ansible   -i  指定配置文件名称   web 指定主机群组   -m 指定模块 –a 指定模块参数
模块查询命令
ansible-doc -l 列出所有的模块列表
ansible-doc -s 查看指定模块的参数

6.Ansible配置文件介绍

[root@centos6-130 ansible]# vim /etc/ansible/ansible.cfg
#inventory      = /etc/ansible/hosts  #指定主机清单文件
#library        = /usr/share/my_modules/  #指定模块地址
#module_utils   = /usr/share/my_module_utils/ 
#remote_tmp     = ~/.ansible/tmp  #指定远程执行的路径
#local_tmp      = ~/.ansible/tmp  #ansible 管理节点执行路径
#plugin_filters_cfg = /etc/ansible/plugin_filters.yml  
#forks          = 5  # 置默认情况下Ansible最多能有多少个进程同时工作,默认设置最多5个进程并行处理
#poll_interval  = 15  #轮询间隔
#sudo_user      = root  #sudo默认用户
#ask_sudo_pass = True  #是否需要用户输入sudo密码
#ask_pass      = True   #是否需要用户输入连接密码
#transport      = smart  #通信机制.默认 值为’smart’。如果本地系统支持 ControlPersist技术的话,将会使用(基于OpenSSH)‘ssh’,如果不支持将使用‘paramiko’.其他传输选项‘local’,‘chroot’,’jail’等等
#remote_port    = 22  #远程链接的端口
#module_lang    = C  #这是默认模块和系统之间通信的计算机语言,默认为’C’语言.
#module_set_locale = False
#timeout = 10    #SSH超时时间
#log_path = /var/log/ansible.log     #日志文件存放路径
#module_name = command     #ansible命令执行默认的模块
 #private_key_file = /path/to/file     //私钥文件存储位置

二.Ansible 常用模块介绍及演示:

1.ping 模块

测试目标主机是否在线

主机如果在线,则回复pong
 [root@centos6-130-130 ansible]# ansible -i hosts  web -m ping 
192.168.10.131 | SUCCESS => {
  "changed": false, 
  "ping": "pong"
}
192.168.10.132 | SUCCESS => {
  "changed": false, 
  "ping": "pong"
}

2.setup模块

setup模块,主要用于获取主机信息,在playbooks里经常会用到的一个参数gather_facts就与该模块相关。setup模块下经常使用的一个参数是filter参数,具体使用示例如下(由于输出结果较多,这里只列命令不写结果):

查看web主机群组内内存的情况
[root@centos6-130-130 ansible]# ansible -i hosts  web -m setup -a 'filter=ansible*mb'
查看web主机群组内网卡eth0的情况
[root@centos6-130-130 ansible]# ansible -i hosts  web -m setup -a 'filter=ansible_eth0'

3.file 模块

file模块主要用于远程主机上的文件操作,file模块包含如下选项: 

force:需要在两种情况下强制创建软链接,一种是源文件不存在但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes|no 

group:定义文件/目录的属组 
mode:定义文件/目录的权限
owner:定义文件/目录的属主
path:必选项,定义文件/目录的路径
recurse:递归的设置文件的属性,只对目录有效
src:要被链接的源文件的路径,只应用于state=link的情况
dest:被链接到的路径,只应用于state=link的情况 
state:  directory:如果目录不存在,创建目录
file:即使文件不存在,也不会被创建
link:创建软链接
hard:创建硬链接
touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
absent:删除目录、文件或者取消链接文件

3.1创建文件

[root@centos6-130-130 ansible]# ansible -i hosts  web -m file -a 'path=/tmp/bawei.txt state=touch'
192.168.10.131 | SUCCESS => {
    "changed": true, 
    "dest": "/tmp/bawei.txt", 
    "gid": 0, 
    "group": "root", 
    "mode": "0644", 
    "owner": "root", 
    "size": 0, 
    "state": "file", 
    "uid": 0
}
192.168.10.132 | SUCCESS => {
    "changed": true, 
    "dest": "/tmp/bawei.txt", 
    "gid": 0, 
    "group": "root", 
    "mode": "0644", 
    "owner": "root", 
    "size": 0, 
    "state": "file", 
    "uid": 0
}

3.2删除文件

[root@centos6-130-130 ansible]# ansible -i hosts  web -m file -a "path=/tmp/yum.log state=absent"
192.168.10.131 | SUCCESS => {
    "changed": true, 
    "path": "/tmp/yum.log", 
    "state": "absent"
}
192.168.10.132 | SUCCESS => {
    "changed": true, 
    "path": "/tmp/yum.log", 
    "state": "absent"
}

####3.3 创建一个目录 所属用户 所属组 以及权限

[root@centos6-130-130 ansible]# ansible -i hosts web -m file -a 'path=/tmp/bawei state=directory owner=root group=root mode=777'
192.168.10.131 | SUCCESS => {
    "changed": true, 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "root", 
    "path": "/tmp/bawei", 
    "size": 4096, 
    "state": "directory", 
    "uid": 0
}
192.168.10.132 | SUCCESS => {
    "changed": true, 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "root", 
    "path": "/tmp/bawei", 
    "size": 4096, 
    "state": "directory", 
    "uid": 0
}

3.4给/etc/hosts文件 创建硬链接

[root@centos6-130-130 ansible]# ansible -i hosts  web  -m file -a "path=/tmp/hardfile state=hard src=/etc/hosts"
192.168.10.131 | SUCCESS => {
    "changed": true, 
    "dest": "/tmp/hardfile", 
    "gid": 0, 
    "group": "root", 
    "mode": "0644", 
    "owner": "root", 
    "size": 158, 
    "src": "/etc/hosts", 
    "state": "hard", 
    "uid": 0
}
192.168.10.132 | SUCCESS => {
    "changed": true, 
    "dest": "/tmp/hardfile", 
    "gid": 0, 
    "group": "root", 
    "mode": "0644", 
    "owner": "root", 
    "size": 158, 
    "src": "/etc/hosts", 
    "state": "hard", 
    "uid": 0
}

4.copy 模块

backup:在覆盖之前将原文件备份,备份文件包含时间信息。有两个选项:yes|no
content:用于替代"src",可以直接设定指定文件的值
dest:必选项。要将源文件复制到的远程主机的绝对路径,如果源文件是一个目录,那么该路径也必须是个目录
directory_mode:递归的设定目录的权限,默认为系统默认权限
force:如果目标主机包含该文件,但内容不同,如果设置为yes,则强制覆盖,如果为no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为yes
others:所有的file模块里的选项都可以在这里使用
src:要复制到远程主机的文件在本地的地址,可以是绝对路径,也可以是相对路径。如果路径是一个目录,它将递归复制。在这种情况下,如果路径使用"/"来结尾,则只复制目录里的内容,如果没有使用"/"来结尾,则包含目录在内的整个内容全部复制,类似于rsync。

####4.1 copy /etc/hosts 文件到root 下面并赋予权限及所属用户 用户组

[root@centos6-130-130 ansible]# ansible -i hosts web -m  copy -a 'src=/etc/hosts dest=/root/file2 mode=755 owner=root group=root'
192.168.10.131 | SUCCESS => {
    "changed": true, 
    "checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa", 
    "dest": "/root/file2", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "54fb6627dbaa37721048e4549db3224d", 
    "mode": "0755", 
    "owner": "root", 
    "size": 158, 
    "src": "/root/.ansible/tmp/ansible-tmp-1534132243.73-96320200892462/source", 
    "state": "file", 
    "uid": 0
}
192.168.10.132 | SUCCESS => 
    "changed": true, 
    "checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa", 
    "dest": "/root/file2", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "54fb6627dbaa37721048e4549db3224d", 
    "mode": "0755", 
    "owner": "root", 
    "size": 158, 
    "src": "/root/.ansible/tmp/ansible-tmp-1534132243.75-178891778388558/source", 
    "state": "file", 
    "uid": 0
}

5.command 模块

command模块包含如下选项:
creates:一个文件名,当该文件存在,则该命令不执行
free_form:要执行的Linux指令
chdir:在执行指令之前,先切换到该指定的目录
removes:一个文件名,当该文件不存在,则该选项不执行
executable:切换shell来执行指令,该执行路径必须是一个绝对路径

####5.1查看主机时间

[root@centos6-130-130 ansible]# ansible -i hosts web  -m command -a 'date'
192.168.10.132 | SUCCESS | rc=0 >>
2018年 08月 13日 星期一 11:56:10 CST
192.168.10.131 | SUCCESS | rc=0 >>
2018年 08月 13日 星期一 11:56:09 CST

###6.Shell 模块 shell 支持管道

####6.1查看httpd 进程状态

[root@centos6-130-130 ansible]# ansible -i hosts web  -m shell -a 'ps -ef | grep httpd'
192.168.10.132 | SUCCESS | rc=0 >>
root       2085   2084  0 12:01 pts/1    00:00:00 /bin/sh -c ps -ef | grep httpd
root       2087   2085  0 12:01 pts/1    00:00:00 grep httpd
192.168.10.131 | SUCCESS | rc=0 >>
root       2123   2122  0 12:01 pts/1    00:00:00 /bin/sh -c ps -ef | grep httpd
root       2125   2123  0 12:01 pts/1    00:00:00 grep httpd

7.user group 模块

user模块:管理用户的模块。user模块是请求的是useradd, userdel, usermod三个指令,goup模块请求的是groupadd, groupdel, groupmod 三个指令。
模块参数详解:
    name:指定用户名
    password:设定用户密码,password参数需要接受md5加密后的值
    state:用户状态,默认为present
        present:表示添加用户
        absent:表示删除用户
    update_password:修改用户密码
        always:新密码和旧密码不同时进行修改
        on_create:为新创建的用户指定密码
    createhome:创建家目录
        yes:默认项,即创建用户默认是有家目录的
        no:创建用户时不创建家目录
    remove:
        yes:删除用户家目录,需要指定此参数
        no:默认项,删除用户时默认不删除用户的家目录
    system:
        yes:默认创建为普通用户,而非系统用户
    如果不指定默认生成的选项有:
        home:创建家目录
        shell:创建默认的shell为/bin/bash
        system:默认创建为普通用户,而非系统用户,指定是用yes

7.1 增加ansible用户 指定用户 用户组 及uid

[root@centos6-130-130 ansible]# ansible -i hosts  web -m user -a  "name=ansible uid=2018 group=ansible state=present"
192.168.10.132 | SUCCESS => {
    "changed": true, 
    "comment": "", 
    "create_home": true, 
    "group": 2018, 
    "home": "/home/ansible", 
    "name": "ansible", 
    "shell": "/bin/bash", 
    "state": "present", 
    "system": false, 
    "uid": 2018
}
192.168.10.131 | SUCCESS => {
    "changed": true, 
    "comment": "", 
    "create_home": true, 
    "group": 2018, 
    "home": "/home/ansible", 
    "name": "ansible", 
    "shell": "/bin/bash", 
    "state": "present", 
    "system": false, 
    "uid": 2018
}

7.2 使用user 模块删除用户,及家目录

[root@centos6-130-130 ansible]# ansible -i hosts  web -m user -a  "name=test  state=absent remove=yes"
192.168.10.132 | SUCCESS => {
    "changed": true, 
    "force": false, 
    "name": "test", 
    "remove": true, 
    "state": "absent"
}
192.168.10.131 | SUCCESS => {
    "changed": true, 
    "force": false, 
    "name": "test", 
    "remove": true, 
    "state": "absent"
}

7.3 group模块

#####7.3.1 增加ansible 组指定gid

root@centos6-130-130 ansible]# ansible -i hosts  web -m group -a  "name=ansible gid=2018 "
192.168.10.131 | SUCCESS => {
    "changed": true, 
    "gid": 2018, 
    "name": "ansible", 
    "state": "present", 
    "system": false
}
192.168.10.132 | SUCCESS => {
    "changed": true, 
    "gid": 2018, 
    "name": "ansible", 
    "state": "present", 
    "system": false

#####7.3.2 删除用户群组

[root@centos6-130-130 ansible]# ansible -i hosts  web -m group -a  "name=test state=absent"
192.168.10.132 | SUCCESS => {
    "changed": true, 
    "name": "test", 
    "state": "absent"
}
192.168.10.131 | SUCCESS => {
    "changed": true, 
    "name": "test", 
    "state": "absent"
}

8.yum 模块

state:
name:必选的项目
默认值; present 
选项值  present/latest/absent 用于描述安装包最终状态,present/latest用于安装包,absent用于remove安装包

8.1进行部署安装openssh-clients

[root@centos6-130 ansible]# ansible -i hosts web  -m yum -a "state=present name=openssh-clients"

9.Script模块

script 模块可以帮助我们在远程主机上执行 ansible 管理主机上的脚本,也就是说,脚本一直存在于 ansible 管理主机本地,不需要手动拷贝到远程主机后再执行。 学习此模块之前,请先学习 command 模块。
chdir参数 : 此参数的作用就是指定一个远程主机中的目录,在执行对应的脚本之前,会先进入到 chdir 参数指定的目录中。
creates参数 :使用此参数指定一个远程主机中的文件,当指定的文件存在时,就不执行对应脚本,可参考 command 模块中的解释。
removes参数 :使用此参数指定一个远程主机中的文件,当指定的文件不存在时,就不执行对应脚本,可参考 command 模块中的解释。

####9.1 执行ansible 管理端的脚本


[root@centos6-130 ansible]# ansible -i hosts web  -m script -a "chdir=/tmp  /tmp/test.sh"
192.168.10.131 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.10.131 closed.\r\n", 
    "stdout": "", 
    "stdout_lines": []
}
192.168.10.132 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.10.132 closed.\r\n", 
    "stdout": "", 
    "stdout_lines": []
}
192.168.10.130 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.10.130 closed.\r\n", 
    "stdout": "", 
    "stdout_lines": []
}

10. server模块

模块参数详解:  
enabled:表示设置服务开机是否启动,取值为true或者false;enabled=yes
name=:表示要控制哪一个服务
state:
	started:表示现在就启动此服务
	stopped:表示现在关闭此服务
    restarted:表示重启此服务
    sleep:如果执行了restarted,在stop和start之间沉睡几秒
    runlevel:定义在哪些级别可以自启动
    arguments:表示向命令行传递的参数

10.1 启动httpd 服务

[root@centos6-130 ansible]# ansible -i hosts  web -m service  -a "name=httpd state=started"
192.168.10.132 | SUCCESS => {
    "changed": true, 
    "name": "httpd", 
    "state": "started"
}
192.168.10.130 | SUCCESS => {
    "changed": true, 
    "name": "httpd", 
    "state": "started"
}
192.168.10.131 | SUCCESS => {
    "changed": true, 
    "name": "httpd", 
    "state": "started"

10.2 使用service模块重启httpd并设定开机自启

[root@centos6-130 ansible]# ansible -i hosts  web -m service  -a "name=httpd enabled=yes state=restarted"
192.168.10.132 | SUCCESS => {
    "changed": true, 
    "enabled": true, 
    "name": "httpd", 
    "state": "started"
}
192.168.10.131 | SUCCESS => {
    "changed": true, 
    "enabled": true, 
    "name": "httpd", 
    "state": "started"
}
192.168.10.130 | SUCCESS => {
    "changed": true, 
    "enabled": true, 
    "name": "httpd", 
    "state": "started"
}

11.cron 模块

backup:对远程主机上的原任务计划内容修改之前做备份
cron_file:如果指定该选项,则用该文件替换远程主机上的cron.d目录下的用户的任务计划
day:日(1-31,*,*/2,……)
hour:小时(0-23,*,*/2,……)
minute:分钟(0-59,*,*/2,……)
month:月(1-12,*,*/2,……)
weekday:周(0-7,*,……)
job:要执行的任务,依赖于state=present
name:该任务的描述
special_time:指定什么时候执行,参数:reboot,yearly,annually,monthly,weekly,daily,hourly
state:确认该任务计划是创建还是删除
user:以哪个用户的身份执行

####11.1 查看计划任务

[root@centos6-130 ansible]# ansible -i hosts web -m shell  -a 'crontab -l'
192.168.10.131 | SUCCESS | rc=0 >>
#Ansible: reboot system
* 2 * * * /sbin/reboot
192.168.10.132 | SUCCESS | rc=0 >>
#Ansible: reboot system
* 2 * * * /sbin/reboot

####11.2 root用户下 重启系统计划任务 每天的两点进行重启系统

[root@centos6-130 ansible]# ansible -i hosts web -m cron -a 'name="reboot system" hour=2 user=root job="/sbin/reboot"'
192.168.10.132 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "reboot system"
    ]
}
192.168.10.131 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "reboot system"
    ]
}

11.3 删除计划任务 用absent

[root@centos6-130 ansible]#  ansible -i hosts web -m cron -a 'name="reboot system" hour=2 user=root job="/sbin/reboot" state=absent'
192.168.10.131 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": []
}
192.168.10.132 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": []
}

11.4 每10分钟进行同步一次时间

[root@centos6-130 ansible]# ansible -i hosts web -m cron -a 'name="sync time from ntpserver" minute=*/10 job="/usr/sbin/ntpdate 3.cn.pool.ntp.org"'
192.168.10.132 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "sync time from ntpserver"
    ]
}
192.168.10.131 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "sync time from ntpserver"
    ]
}

12.synchronize模块

archive                # 是否采用归档模式同步,即以源文件相同属性同步到目标地址
checksum               # 是否效验
compress               # 开启压缩,默认为开启
copy_links             # 同步的时候是否复制连接
delete                 # 删除源中没有而目标存在的文件(即以推送方为主)
dest=                  # 目标地址
dest_port              # 目标接受的端口,ansible配置文件中的 ansible_ssh_port 变量优先级高于该 dest_port 变量
dirs                   # 以非递归的方式传输目录
existing_only          # Skip creating new files on receiver.
group                  # Preserve group
links                  # Copy symlinks as symlinks.
mode                   # 模式,rsync 同步的方式 PUSH\PULL,默认都是推送push。如果你在使用拉取pull功能的时候,可以参考如下来实现mode=pull   更改推送模式为拉取模式
recursive              # 是否递归 yes/no
rsync_opts             # 使用rsync 的参数
rsync_path             # 服务的路径,指定 rsync 命令来在远程服务器上运行。这个参考rsync命令的--rsync-path参数,--rsync-path=PATH     # 指定远程服务器上的rsync命令所在路径信息
rsync_timeout          # 指定 rsync 操作的 IP 超时时间,和rsync命令的 --timeout 参数效果一样.
set_remote_user        # put user@ for the remote paths. If you have a custom ssh config to define the remote user for
src=\‘#\‘"                  # 源,同步的数据源
times                  # 
--exclude=.Git  忽略同步.git结尾的文件
由于模块默认启用了archive参数,该参数默认开启了recursive, links, perms, times, owner,group和-D参数。如果你将该参数设置为no,那么你将停止很多参数,比如会导致如下目的递归失败,导致无法拉取
使用rsync 模块,系统必须安装rsync 包,否则无法使用这个模块

12.1 先进行部署安装rsync服务

[root@centos6-130-130 ~]# ansible -i hosts  web -a "yum install rsync -y"

12.2 把/tmp 目录中的test.txt 文件 同步到root 目录下

[root@centos6-130-130 ansible]# ansible -i hosts  web -m synchronize -a "src=/tmp/test.txt dest=/root/"
192.168.10.132 | SUCCESS => {
    "changed": true, 
    "cmd": "/usr/bin/rsync --delay-updates -F --compress --archive --rsh=/usr/bin/ssh -S none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null --out-format=<<CHANGED>>%i %n%L /tmp/test.txt 192.168.10.132:/root/", 
    "msg": "<f+++++++++ test.txt\n", 
    "rc": 0, 
    "stdout_lines": [
        "<f+++++++++ test.txt"
    ]
}
192.168.10.131 | SUCCESS => {
    "changed": true, 
    "cmd": "/usr/bin/rsync --delay-updates -F --compress --archive --rsh=/usr/bin/ssh -S none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null --out-format=<<CHANGED>>%i %n%L /tmp/test.txt 192.168.10.131:/root/", 
    "msg": "<f+++++++++ test.txt\n", 
    "rc": 0, 
    "stdout_lines": [
        "<f+++++++++ test.txt"
    ]
}

12.3 把tmp 目录同步到root目录下tmp目录中

[root@centos6-130-130 ansible]# ansible -i hosts  web -m synchronize -a "src=/tmp/ dest=/root/tmp"

ansbible


三.ansible --yaml语法

介绍:

​ YAML是一个可读性高的用来表达资料序列的格式。YAML参考了其他多种语言,包括:XML、C语言、Python、Perl等。

​ YAML不是XML,不过,在开发的这种语言时,YAML的意思其实是:“Yet Another Makup Language”(仍是一种标记语言)

###特点:

  • 可读性好

  • 和脚本的交互性好

  • 使用实现怨言的数据类型

  • 有一个一致的信息模型

  • 易于实现。

  • 可以基于流来处理。

  • 表达能力强,扩展性好

###YAML语法:

YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。其结构(structure)通过空格来展示。

序列(sequence):里的项用“-”来代表,来代表不同元素。 MAP里的键值对,用":"分隔,比如:

name:tom
age:22
gender:Male
spouse:
          name:lili
          age:18
          gender:Female
children:
         - name:tom1
            age:5
            gender:Male
         - name:tom2
           age:5
           gender:Female

一个键值对,可以一个键值对应一个value,也可以一个键值对应另一个键值对。 序列,相同的数据类型,元素间用"-"表示一个序列内,元素是键值对。 用空格来表示结构关系,不是tab。

###ansible中YAML

在ansible中叫序列为列表,列表为序列都可以。他们之间元素用"-"开头例如:

1 # a list of colors
2 - red
3 - blue
4 - black
dictionary:

字典:通过key:value 进行标识。例如:

1 # tom information
2 name:tom
3 age:22
4 job:it

如上3个键值对表示一个实体,也可以用{}来表示一个实体,也就是说将上面3个键值对放在一个{}中来表示一个实体。

1 #tom information
2 1 {name:tom,age:22,job:it}

##四.PlayBook介绍

playbook是由一个或者多个play组成的列表,主要功能是将task定义好的角色归并为一组进行统一管理。

playbooks本身组成部分有如下几份:
hosts: 用于指定操作对象节点,多个节点用逗号分隔
tasks: 用于指定要处理的内容
name:task的名称,ansible可以把很多task使用playbook编排起来,通过名称,实际执行的时候可以清楚地看到执行情况

shell: ansible的shell模块,在前面的实例中我们已经知道command/shell/raw等的区别,所以可以知道这个简单的例子中使用哪个模块都能实现这个简单的功能。

示例:

[root@centos6-130 ansible]# cat hello.playbook 
- hosts: web #主机群组
  gather_facts: false  #facts不会被收集,这个选项当有需求节省fact收集时比较有用
  tasks:  #运行的动作
    - name:  say hello task  #运行动作的名称
      shell: echo hello world `date` by `hostname` >/tmp/hello.log  # 所执行的动作语句
[root@centos6-130 ansible]# ansible-playbook hello.playbook 
PLAY [web] ***********************************************************************************
TASK [say hello task] *************************************************************************
changed: [192.168.10.131]
changed: [192.168.10.132]
PLAY RECAP ************************************************************************************
192.168.10.131             : ok=1    changed=1    unreachable=0    failed=0   
192.168.10.132             : ok=1    changed=1    unreachable=0    failed=0  
验证tmp 下面生成hello.log 文件
[root@centos6-130 ansible]# ansible -i hosts web -m command -a "ls /tmp/"
192.168.10.131 | SUCCESS | rc=0 >>
ansible_8mboRu
hello.log
192.168.10.132 | SUCCESS | rc=0 >>
ansible_vExmQp
hello.log

1. ansible 来部署apache服务

1.1 定义主机群组hosts文件

[root@centos6-130 ansible]# cat hosts
[web]
192.168.10.131
192.168.10.132

思路:

  • 明确playbook做哪些任务?
  • web组的主机完成下列任务
  • 远程执行用户为root
  • 安装httpd
  • apache配置文件实现自定义http端口和客户端连接数
  • 启动httpd,并设置其开机自启动

1.2 编辑playbook文件

[root@centos6-130 ansible]# cat  httpd.yml
- hosts: web
  remote_user: root
  tasks:
  - name: install httpd
    yum: name=httpd state=present
  - name: install configure file
    copy: src=/root/httpd.conf dest=/etc/httpd/conf/
  - name: start httpd service
service: name=httpd state=started
注意:这里的src 指的是ansible 服务器上的文件位置。
[root@centos6-130 ansible]#  grep ^Listen /root/httpd.conf
Listen 808
除了端口,其他的配置文件都是相同的。

1.3 测试playbook

ansible3

1.4 运行playbook

ansible4

####1.5 查看服务启动时的端口

[root@centos6-130 ansible]# ansible -i hosts  web -m shell -a "ss -tnl| grep :808"
192.168.10.131 | SUCCESS | rc=0 >>
LISTEN     0      128         :::808                     :::*                  
192.168.10.132 | SUCCESS | rc=0 >>
LISTEN     0      128         :::808                     :::*  

###2.Playbook常用的功能:

  • playbook里面的变量使用

  • playbook里面的循环

  • Playbook 中的 条件判断

  • playbook中的handlers

  • playbook中的notify

  • playbook中的roles角色

2.1playbook里面的变量使用

增加用户

[root@centos6-130 ansible]# cat  create_user.yml 
---
- name: create_user
  hosts: web
  user: root
  gather_facts: false
  vars:
    - user: "test"
  tasks:
    - name: create user
      user: name="{{ user }}"

查看用户

[root@centos6-130 ansible]# cat while.yml
---
- hosts: web
  user: root
  tasks:
    - name: change mode for files
      file: path=/tmp/{{ item }} state=touch mode=600
      with_items:
        - 1.txt
        - 2.txt
        - 3.txt
解释说明:
file模块可以对文件进行相关的操作,例如创建文件或者更改文件权限等,具体可以查看该模块的文档
with_items为循环的对象,相当于是一个数组或集合,写在下面的1.txt、2.txt以及3.txt是该集合的元素。而item则表示的是遍历出来的元素,也就是说item指代的是1.txt、2.txt以及3.txt。
state的值设置为touch表示如果该文件不存在就进行创建
path表示文件的路径
mode设置权限

ansible5 查看生成的文件

[root@centos6-130 ansible]# ansible -i hosts web -m command -a "ls  /tmp"
192.168.10.132 | SUCCESS | rc=0 >>
1.txt
2.txt
3.txt
192.168.10.131 | SUCCESS | rc=0 >>
1.txt
2.txt
3.txt

###3.Playbook 中的 条件判断

我们都知道在脚本中循环和条件判断是必不可少的语句,所以在playbook里这两种语句也是有的,循环我们已经介绍完了,接下来我们通过一个简单的创建文件的例子演示一下条件判断语句的使用方式。
我们一般以setup模块收集到的主机信息,来作为判断条件。所以在编写代码之前,我们需要先获取相应的信息,例如我要以ip地址来作为判断条件,那么我就得先从setup里获取主机ip的相关信息。

获取信息查看文件

[root@centos6-130 ansible]# ansible web -m setup
[root@centos6-130 ansible]# cat when.yml 
---
- hosts: web
  user: root
  gather_facts: True
  tasks:
    - name: use when
      shell: touch /tmp/when.txt
      when: ansible_eth0.ipv4.address == "192.168.10.131"

ansible6

结果显示:192.168.10.132 changed=0 没有进行改变 when 条件判断生效。

查看是否创建文件:

[root@centos6-130 ansible]# ansible web -m shell -a 'ls /tmp/when.txt'
192.168.10.132 | FAILED | rc=2 >>
ls: 无法访问/tmp/when.txt: 没有那个文件或目录non-zero return code
192.168.10.131 | SUCCESS | rc=0 >>
/tmp/when.txt

4.playbook中的handlers

handlers: 在发生改变时执行的操作
handlers是另一种的tasks,handlers是另一种的任务列表,handlers中的任务会被tasks中的任务进行调用,但是调用并不意味着就一定会被执行,只有当tasks中的任务真正执行以后(真在的进行实际操作,造成实际的改变),handles中被调用的任务才会执行,如果tasks中的任务并没有做出任何的实际操作,那么handlers 中的任务即使被调用,也不会执行。

配置文件

[root@centos6-130 ansible]# cat handlers.yml
- hosts: web
  remote_user: root
  tasks:
  - name: install redis package
    yum: name=redis state=latest
  - name: install conf file
    copy: src=/root/redis.conf dest=/etc/redis.conf owner=redis group=root mode=644
    tags: instconf
    notify: restart redis service
  - name: start redis service
    service: name=redis state=started
  handlers: 
  - name: restart redis service
service: name=redis state=restarted

注意:/root/redis.conf 是在ansible 服务端,这里我对redis.conf 端口进行了调整6399

条件式触发:handler,满足条件的时候触发条件 handlers:处理器,配置文件被修改的时候才执行,条件定义在notify 以下命令,表示当配置文件被更改的时候,notify就会触发handler,实现重启的操作.注意格式的书写。

ansible7

###5.playbook中的notify

notify这个action可用于在每个play的最后被触发,这样可以避免多次有改变发生时每次都执行指定的操作,取而代之,仅在所有的变化发生完成后一次性地执行指定操作。

###6.playbook中的roles角色

什么场景会使用roles? 假如我们现在有3个被管理主机,第一个要配置成httpd,第二个要配置成php服务器,第三个要配置成MySQL服务器。我们如何来定义playbook? 第一个play用到第一个主机上,用来构建httpd,第二个play用到第二个主机上,用来构建php,第三个play用到第三个主机上,用来构建MySQL。这些个play定义在playbook中比较麻烦,将来也不利于模块化调用,不利于多次调。比如说后来又加进来一个主机,这个第4个主机既是httpd服务器,又是php服务器,我们只能写第4个play,上面写上安装httpd和php。这样playbook中的代码就重复了。 为了避免代码重复,roles能够实现代码重复被调用。定义一个角色叫websrvs,第二个角色叫phpappsrvs,第三个角色叫dbsrvs。那么调用时如下来调用:

创建hosts

[root@centos6-130 ansible]# cat hosts
[mysqld]
192.168.10.130
[httpd]
192.168.10.131
[php]
192.168.10.132

示例: 假设有3台主机,192.168.10.130主机上安装MySQL,192.168.10.131上安装httpd,192.168.10.132上安装MySQL和httpd。我们建立两个角色websrvs和dbsrvs,然后应用到这几个主机上。

6.1创建目录

[root@centos6-130 ansible]# mkdir -pv ansible_playbooks/roles/{websrvs,dbsrvs}/{tasks,files,templates,meta,handlers,vars}
mkdir: 已创建目录 "ansible_playbooks"
mkdir: 已创建目录 "ansible_playbooks/roles"
mkdir: 已创建目录 "ansible_playbooks/roles/websrvs"
mkdir: 已创建目录 "ansible_playbooks/roles/websrvs/tasks"
mkdir: 已创建目录 "ansible_playbooks/roles/websrvs/files"
mkdir: 已创建目录 "ansible_playbooks/roles/websrvs/templates"
mkdir: 已创建目录 "ansible_playbooks/roles/websrvs/meta"
mkdir: 已创建目录 "ansible_playbooks/roles/websrvs/handlers"
mkdir: 已创建目录 "ansible_playbooks/roles/websrvs/vars"
mkdir: 已创建目录 "ansible_playbooks/roles/dbsrvs"
mkdir: 已创建目录 "ansible_playbooks/roles/dbsrvs/tasks"
mkdir: 已创建目录 "ansible_playbooks/roles/dbsrvs/files"
mkdir: 已创建目录 "ansible_playbooks/roles/dbsrvs/templates"
mkdir: 已创建目录 "ansible_playbooks/roles/dbsrvs/meta"
mkdir: 已创建目录 "ansible_playbooks/roles/dbsrvs/handlers"
mkdir: 已创建目录 "ansible_playbooks/roles/dbsrvs/vars"

[root@centos6-130 ansible]# tree ansible_playbooks/
ansible_playbooks/
└── roles
    ├── dbsrvs
    │   ├── files
    │   ├── handlers
    │   ├── meta
    │   ├── tasks
    │   ├── templates
    │   └── vars
    └── websrvs
        ├── files
        ├── handlers
        ├── meta
        ├── tasks
        ├── templates
        └── vars

每个role下面有个目录叫meta,在里面可以新建文件main.yml,在文件中可以设置该role和其它role之前的关联关系。

6.2配置角色websrvs

[root@centos6-130 ansible]# cd ansible_playbooks/roles/
[root@centos6-130 roles]# cd websrvs/
[root@centos6-130 websrvs]# ls
files  handlers  meta  tasks  templates  vars

6.2.1 上传配置文件

将httpd配置文件上传到files目录下,我这里假设httpd.conf每台主机都是一样的,实际上应该用模板,先用一样的配置文件举例

[root@centos6-130 websrvs]# cp /etc/httpd/conf/httpd.conf  files/

6.2.2 配置任务tasks列表

[root@centos6-130 websrvs]# cat tasks/main.yml 
- name: install httpd package
  yum: name=httpd
- name: install configuration file
  copy: src=/root/httpd.conf dest=/etc/httpd/conf
  tags:
  - conf
  notify:
  - restart httpd
- name: start httpd
  service: name=httpd state=started

ansible8

于上面的tasks中定义了notify,所以要定义handlers

[root@centos6-130 websrvs]# cat handlers/main.yml 
- name: restart httpd
  service: name=httpd state=restarted

如果需要定义变量,则在vars目录下创建main.yml文件,在文件中写入变量,以key:value的形式定义,比如:

[root@centos6-130 websrvs]# cat vars/main.yml 
http_port: 8080

6.3 配置角色dbservs

[root@centos6-130 dbsrvs]# ls
files  handlers  meta  tasks  templates  vars

6.3.1将MySQL配置文件上传到files目录下。

[root@centos6-130 files]# ls
my.cnf
[root@centos6-130 files]# pwd
/etc/ansible/ansible_playbooks/roles/dbsrvs/files

6.3.2 编写任务列表tasks

[root@centos6-130 dbsrvs]# cat tasks/main.yml 
- name: install mysql-server package
  yum:
      name: "{{item}}"
      state: present
  with_items:
  - mysql
  - mysql-server
  - mysql-libs
- name: install configuration file
  copy: src=/root/my.cnf dest=/etc/my.cnf
  tags:
  - conf
  notify:
  - restart mysqld
- name:
  service: name=mysqld enabled=true state=started

6.3.3 定义handlers

[root@centos6-130 dbsrvs]# cat handlers/main.yml 
- name: restart mysqld
  service: name=mysqld state=restarted

6.4 创建playbooks

[root@centos6-130 ansible_playbooks]# cat db.yml 
- hosts: mysqld
  roles:
  - dbsrvs 
[root@centos6-130 ansible_playbooks]# cat web.yml 
- hosts: httpd
  roles:
  - websrvs
[root@centos6-130 ansible_playbooks]# cat site.yml 
- hosts: php
  roles:
  - websrvs
  - dbsrvs

6.5运行进行测试

[root@centos6-130 ansible_playbooks]# ansible-playbook web.yml

ansible9

[root@centos6-130 ansible_playbooks]# ansible-playbook db.yml

ansible10

[root@centos6-130 ansible_playbooks]# ansible-playbook site.yml

ansible11