3.2.1 运维自动化之ansible模块

Ansible 原理

    使用者使用Ansible或Ansible-playbooks时,在服务器终端输入Ansible的Ad-Hoc命令集或palybook后,Ansible会遵循预先编排的规则将Playbooks逐条拆解为Play,再将paly组织成Ansible可识别的任务(Task),随后调用任务涉及的所有模块(modules)和插件(plugins),根据Inventory中定义的主机列表通过SSH将任务集以临时文件或命令的形式传输到远程客户端执行并返回执行结果,如果是临时文件,则执行完毕后自动删除。

    Ansible命令执行来源:

USER(普通用户)即SYSTEM ADMINISTRATOR
CMDB(配置管理数据库)API 调用
PUBLIC/PRIVATE CLOUD API调用

USER-> AnsiblePlaybook -> Ansibile

Ansible 特性与构架

    特性

模块化:调用特定的模块,完成特定任务
有Paramiko,PyYAML,Jinja2(模板语言)三个关键模块
支持自定义模块
基于Python语言实现
部署简单,基于python和SSH(默认已安装),agentless
安全,基于OpenSSH
支持playbook编排任务
幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况
无需代理不依赖PKI(无需ssl)
可使用任何编程语言写模块
YAML格式,编排任务,支持丰富的数据结构
较强大的多层解决方案

    架构


ANSIBLE PLAYBOOKS:任务剧本(任务集),编排定义Ansible任务集的配置文件,由Ansible顺序依次执行,通常是JSON格式的YML文件
INVENTORY:Ansible管理主机的清单/etc/anaible/hosts
MODULES:Ansible执行命令的功能模块,多数为内置核心模块,也可自定义
PLUGINS:模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插件等,该功能不常用
API:供第三方程序调用的应用程序编程接口
ANSIBLE:组合INVENTORY、API、MODULES、PLUGINS的绿框,可以理解为是ansible命令工具,其为核心执行工具

Ansible 部署

    1、使用 yum 命令通过 epel 源安装

[root@CentOS7 ~]#⮀yum install ansible

    2、使用 git 命令通过 github 安装

确认安装成功

[root@CentOS7 ~]# ansible --version
ansible 2.5.3
  config file = /etc/ansible/ansible.cfg
  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, Aug  4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]

查看 ansible 主程序

[root@CentOS7 ~]# ll /usr/bin/ansible
lrwxrwxrwx 1 root root 20 May 28 19:35 /usr/bin/ansible -> /usr/bin/ansible-2.7

    发现程序路径是一个指向 /usr/bin/ansible-2.7 的软连接,所以当安装新版本的 ansible 时,或者需要回滚至旧版本,改变软连接指向即可。

配置主机清单 /etc/ansible/hosts

[root@CentOS7 ~]#⮀cat /etc/ansible/hosts
# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
#
#   - Comments begin with the '#' character
#   - Blank lines are ignored
#   - Groups of hosts are delimited by [header] elements
#   - You can enter hostnames or ip addresses
#   - A hostname/ip can be a member of multiple groups

# Ex 1: Ungrouped hosts, specify before any group headers.

## green.example.com
## blue.example.com
## 192.168.100.1
## 192.168.100.10

# Ex 2: A collection of hosts belonging to the 'webservers' group

## [webservers]
## alpha.example.org
## beta.example.org
## 192.168.1.100
## 192.168.1.110

# If you have multiple hosts following a pattern you can specify
# them like this:

## www[001:006].example.com

# Ex 3: A collection of database servers in the 'dbservers' group

## [dbservers]
## 
## db01.intranet.mydomain.net
## db02.intranet.mydomain.net
## 10.25.1.56
## 10.25.1.57

# Here's another example of host ranges, this time there are no
# leading 0s:

## db-[99:101]-node.example.com

192.168.30.75    #添加控制主机
192.168.30.69

[group1]         #添加控制主机组
192.168.30.75
192.168.30.69

[group2]
192.168.30.75    #相同的主机可以同时出现在不同的主机组
192.168.30.174

[group]
192.168.30.69
192.168.30.174

[example]
www.jiangbowen.com:2222    #可以使用域名,也可以指定端口号,默认22
192.168.30.[1:100]         #支持范围指定
db[a:z].jiangbowen.com

配置 ansible 主配置文件

    ansible 的主配置文件存放在 /etc/ansible/ansible.cfg,一般不需要修改,可能修改的

[defaults]

# some basic default values...

#inventory      = /etc/ansible/hosts                        #主机清单保存列表
#library        = /usr/share/my_modules/                    #库文件保存目录
#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                                      #sudo用户
#ask_sudo_pass = True                                       #是否需要询问sudo口令
#ask_pass      = True                                       #是否询问用户口令
#transport      = smart
#remote_port    = 22                                        #默认连接远程端口
#module_lang    = C
#module_set_locale = False
host_key_checking = False                                  #是否检查主机密钥
log_path = /var/log/ansible.log                            #日志记录保存目录

Ansible 使用

    ansible 命令

    语法:ansible 主机 [-m 模块] [-a 指令] [选项]

[root@CentOS7 ~]# ansible all --list-hosts
  hosts (3):
    192.168.30.75
    192.168.30.69
    192.168.30.174     #没有进行基于Key验证
[root@CentOS7 ~]# ansible group1 --list-hosts
  hosts (2):
    192.168.30.75
    192.168.30.69
[root@CentOS7 ~]# ansible group2 --list-hosts
  hosts (2):
    192.168.30.75
    192.168.30.174
[root@CentOS7 ~]# ansible group3 --list-hosts
  hosts (2):
    192.168.30.69
    192.168.30.174

    选项

-v 详细过程–vv-vvv更详细
--list-hosts 显示主机列表,可简写—list
-k, --ask-pass 提示连接密码,默认Key验证
-K, --ask-become-pass 提示输入sudo
-C, --check 检查,并不执行
-T, --timeout=TIMEOUT 执行命令的超时时间,默认10s
-u, --user=REMOTE_USER 执行远程执行的用户
-b, --become 代替旧版的sudo切换

    主机必须出现在主机清单中,可以是单个主机,指定多个台主机时使用 , 隔开,也可以

使用 all 表示主机清单中的所有主机

[root@CentOS7 ~]# ansible group1 -m ping
192.168.30.69 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.30.75 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

使用通配符 * 表示

[root@CentOS7 ~]# ansible 192.168.30.* -m ping
192.168.30.174 | UNREACHABLE! => {     #此处报错后面会解释,此处只需要了解 * 确实可以使用
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).\r\n", 
    "unreachable": true
}
192.168.30.75 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.30.69 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

使用逻辑关系注意使用单引号将主机引起来

[root@CentOS7 ~]# ansible 'group1:group2' -m ping   #:表示逻辑或
192.168.30.174 | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).\r\n", 
    "unreachable": true
}
192.168.30.69 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.30.75 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
[root@CentOS7 ~]# ansible 'group1:&group2' -m ping    #:&表示逻辑与
192.168.30.75 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
[root@CentOS7 ~]#⮀ansible 'group1:!group2' -m ping   #:!表示逻辑非
192.168.30.69 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

使用正则表达式

[root@CentOS7 ~]#⮀ansible 'group[1|2]' -m ping
192.168.30.174 | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).\r\n", 
    "unreachable": true
}
192.168.30.69 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.30.75 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

    ansible 默认基于 Key 验证,当目标主机没用进行基于 Key 验证时,需要使用 -k 选项输入对应用户的口令,但是只能输入一个口令,便会作用于所有需要输入口令的主机。所以建议在使用 ansible 之前先进行基于 Key 的验证。

[root@CentOS7 ~]# ansible all -m ping -k   #使用-k输入用户口令进行验证
SSH password:           #输入用户口令
192.168.30.69 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.30.75 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.30.174 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

    ansible 常用模块

command 模块用于在远程主机上执行命令。使用 ansible 命令时,默认使用 command 模块。

[root@CentOS7 ~]# ansible group2 -m command -a 'systemctl start httpd.service'
192.168.30.174 | SUCCESS | rc=0 >>


192.168.30.75 | SUCCESS | rc=0 >>

     选项

chdir=:切换目录后执行命令
creates=:当指定文件存在,则该命令不执行
removes=:当指定文件不存在,则该选项不执行

不支持使用管道,变量引用,重定向,逻辑判断等操作符

[root@CentOS7 ~]# ansible group1 -m command -a 'echo "new line" >> /etc/fstab'
192.168.30.69 | SUCCESS | rc=0 >> 
new line >> /etc/fstab             #只是将echo后字符串打印出来而已,并没有执行

192.168.30.75 | SUCCESS | rc=0 >>
new line >> /etc/fstab

shell 模块会通过指定用户的默认shell执行命令,所以支持管道,变量引用,重定向,逻辑判断等操作符。

[root@CentOS7 ~]#⮀ansible group1 -m shell -a 'echo "new line" >> /etc/fstab'
192.168.30.69 | SUCCESS | rc=0 >>


192.168.30.75 | SUCCESS | rc=0 >>


[root@CentOS7 ~]#⮀ansible group1 -m shell -a 'cat /etc/fstab | grep "new line"'
192.168.30.69 | SUCCESS | rc=0 >>
new line

192.168.30.75 | SUCCESS | rc=0 >>
new line

     选项

chdir=:切换目录后执行命令
creates=:当指定文件存在,则该命令不执行
removes=:当指定文件不存在,则该选项不执行

script 模块能够将主控端的脚本推送并运行在指定主机。

[root@CentOS7 ~]# ansible group1 -m script -a '/root/bin/9x9table.sh'   #对端主机并没有此脚本,脚本执行后也并没有保存此脚本
192.168.30.69 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.30.69 closed.\r\n", 
    "stdout": "1x1=1\t\r\n1x2=2\t2x2=4\t\r\n1x3=3\t2x3=6\t3x3=9\t\r\n1x4=4\t2x4=8\t3x4=12\t4x4=16\t\r\n1x5=5\t2x5=10\t3x5=15\t4x5=20\t5x5=25\t\r\n1x6=6\t2x6=12\t3x6=18\t4x6=24\t5x6=30\t6x6=36\t\r\n1x7=7\t2x7=14\t3x7=21\t4x7=28\t5x7=35\t6x7=42\t7x7=49\t\r\n1x8=8\t2x8=16\t3x8=24\t4x8=32\t5x8=40\t6x8=48\t7x8=56\t8x8=64\t\r\n1x9=9\t2x9=18\t3x9=27\t4x9=36\t5x9=45\t6x9=54\t7x9=63\t8x9=72\t9x9=81\t\r\n", 
    "stdout_lines": [
        "1x1=1\t", 
        "1x2=2\t2x2=4\t", 
        "1x3=3\t2x3=6\t3x3=9\t", 
        "1x4=4\t2x4=8\t3x4=12\t4x4=16\t", 
        "1x5=5\t2x5=10\t3x5=15\t4x5=20\t5x5=25\t", 
        "1x6=6\t2x6=12\t3x6=18\t4x6=24\t5x6=30\t6x6=36\t", 
        "1x7=7\t2x7=14\t3x7=21\t4x7=28\t5x7=35\t6x7=42\t7x7=49\t", 
        "1x8=8\t2x8=16\t3x8=24\t4x8=32\t5x8=40\t6x8=48\t7x8=56\t8x8=64\t", 
        "1x9=9\t2x9=18\t3x9=27\t4x9=36\t5x9=45\t6x9=54\t7x9=63\t8x9=72\t9x9=81\t"
    ]
}
192.168.30.75 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.30.75 closed.\r\n", 
    "stdout": "1x1=1\t\r\n1x2=2\t2x2=4\t\r\n1x3=3\t2x3=6\t3x3=9\t\r\n1x4=4\t2x4=8\t3x4=12\t4x4=16\t\r\n1x5=5\t2x5=10\t3x5=15\t4x5=20\t5x5=25\t\r\n1x6=6\t2x6=12\t3x6=18\t4x6=24\t5x6=30\t6x6=36\t\r\n1x7=7\t2x7=14\t3x7=21\t4x7=28\t5x7=35\t6x7=42\t7x7=49\t\r\n1x8=8\t2x8=16\t3x8=24\t4x8=32\t5x8=40\t6x8=48\t7x8=56\t8x8=64\t\r\n1x9=9\t2x9=18\t3x9=27\t4x9=36\t5x9=45\t6x9=54\t7x9=63\t8x9=72\t9x9=81\t\r\n", 
    "stdout_lines": [
        "1x1=1\t", 
        "1x2=2\t2x2=4\t", 
        "1x3=3\t2x3=6\t3x3=9\t", 
        "1x4=4\t2x4=8\t3x4=12\t4x4=16\t", 
        "1x5=5\t2x5=10\t3x5=15\t4x5=20\t5x5=25\t", 
        "1x6=6\t2x6=12\t3x6=18\t4x6=24\t5x6=30\t6x6=36\t", 
        "1x7=7\t2x7=14\t3x7=21\t4x7=28\t5x7=35\t6x7=42\t7x7=49\t", 
        "1x8=8\t2x8=16\t3x8=24\t4x8=32\t5x8=40\t6x8=48\t7x8=56\t8x8=64\t", 
        "1x9=9\t2x9=18\t3x9=27\t4x9=36\t5x9=45\t6x9=54\t7x9=63\t8x9=72\t9x9=81\t"
    ]
}

    选项

chdir=:切换目录后执行命令
creates=:当指定文件存在,则该命令不执行
removes=:当指定文件不存在,则该选项不执行

当脚本需要读取标准输入时,脚本并不会正常运行。因为脚本是在对端主机的后台运行,而得不到标准输入,便会一直等待下去,除非在脚本中设置超时时间。

[root@CentOS7 ~]# ansible group1 -m script -a '/root/bin/chessboard.sh'   
^C [ERROR]: User interrupted execution

root       2211  0.0  0.0 113180  1184 pts/1    S+   23:48   0:00 /bin/bash ~None/.ansible/tmp/ansible-tmp-1527580121.43-60904787174182/chessboard.sh

此时可以在 /root/~None/.ansible/tmp/ 查看命令的临时文件

[root@CentOS7 tmp]#⮀tree
.
└── ansible-tmp-1527577052.42-180110633770421
    └── command.py

1 directory, 1 file

copy 模块能够实现从主控端向目标主机复制单个文件

[root@CentOS7 ~]# ansible group1 -m copy -a 'src=/etc/fstab dest=/data/secfstab owner=jiangbowen mode=644'    #将本机的/etc/fstab文件复制到目标主机上,并将所有者设为jiangbowen用户,权限设为644
192.168.30.69 | SUCCESS => {
    "changed": true, 
    "checksum": "6fbb65e6bb62d7666d77297c188a46c9e215bb84", 
    "dest": "/data/secfstab", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "427fa130e12a6c41daafe68f78c886b1", 
    "mode": "0644", 
    "owner": "jiangbowen", 
    "size": 734, 
    "src": "~None/.ansible/tmp/ansible-tmp-1527581713.59-139108316398323/source", 
    "state": "file", 
    "uid": 500
}
192.168.30.75 | SUCCESS => {
    "changed": true, 
    "checksum": "6fbb65e6bb62d7666d77297c188a46c9e215bb84", 
    "dest": "/data/secfstab", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "427fa130e12a6c41daafe68f78c886b1", 
    "mode": "0644", 
    "owner": "jiangbowen", 
    "secontext": "system_u:object_r:default_t:s0", 
    "size": 734, 
    "src": "~None/.ansible/tmp/ansible-tmp-1527581713.58-232064196823164/source", 
    "state": "file", 
    "uid": 1000
}
[root@CentOS7 ~]#⮀ansible group1 -m copy -a 'src=/root/bin/9x9table.sh dest=/data/secfstab owner=jiangbowen mode=644 backup=yes'   #将本机的/etc/fstab文件复制到目标主机上,并将所有者设为jiangbowen用户,权限设为644,同时在复制时,如果文件已存在同时备份原文件按
192.168.30.69 | SUCCESS => {
    "backup_file": "/data/secfstab.6192.2018-05-29@16:19:02~", 
    "changed": true, 
    "checksum": "8b1bd1f6a042036eeaa74f69df6a7f4183b31ee7", 
    "dest": "/data/secfstab", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "7be915baaec4daf296ad4765ed76b2ff", 
    "mode": "0644", 
    "owner": "jiangbowen", 
    "size": 455, 
    "src": "~None/.ansible/tmp/ansible-tmp-1527581943.02-122324632902056/source", 
    "state": "file", 
    "uid": 500
}
192.168.30.75 | SUCCESS => {
    "backup_file": "/data/secfstab.3478.2018-05-30@00:18:52~", 
    "changed": true, 
    "checksum": "8b1bd1f6a042036eeaa74f69df6a7f4183b31ee7", 
    "dest": "/data/secfstab", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "7be915baaec4daf296ad4765ed76b2ff", 
    "mode": "0644", 
    "owner": "jiangbowen", 
    "secontext": "system_u:object_r:default_t:s0", 
    "size": 455, 
    "src": "~None/.ansible/tmp/ansible-tmp-1527581943.02-121032871897130/source", 
    "state": "file", 
    "uid": 1000
}
[root@CentOS7 ~]#⮀ansible group1 -m shell -a 'll /data/secfstab*'   #使用ll别名查看文件,发现shell并不支持别名
192.168.30.69 | FAILED | rc=127 >>
/bin/sh: ll: command not foundnon-zero return code


192.168.30.75 | FAILED | rc=127 >>
/bin/sh: ll: command not foundnon-zero return code


[root@CentOS7 ~]#⮀ansible group1 -m shell -a 'ls -l /data/secfstab*'   #使用ls -l查看文件
192.168.30.69 | SUCCESS | rc=0 >>
-rw-r--r-- 1 jiangbowen root 455 May 29 16:19 /data/secfstab
-rw-r--r-- 1 jiangbowen root 734 May 29 16:15 /data/secfstab.6192.2018-05-29@16:19:02~


192.168.30.75 | SUCCESS | rc=0 >>
-rw-r--r--. 1 jiangbowen root 455 May 30 00:18 /data/secfstab
-rw-r--r--. 1 jiangbowen root 734 May 30 00:15 /data/secfstab.3478.2018-05-30@00:18:52~

    选项

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

注意:shell 和 command 模块不支持使用别名,同时 CentOS7 中 PATH 变量也会改变

[root@CentOS7 ~]#⮀ansible group1 -m shell -a 'alias'   #使用alias查看对端主机的别名为空
192.168.30.69 | SUCCESS | rc=0 >>


192.168.30.75 | SUCCESS | rc=0 >>


[root@CentOS7 ~]#⮀ansible group1 -m shell -a 'echo $PATH'  #查看对端主机的PATH变量,CentOS7没有/root/bin路径
192.168.30.69 | SUCCESS | rc=0 >>
/app/bin:/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

192.168.30.75 | SUCCESS | rc=0 >>
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bins

也可以利用内容,在对端主机上直接生成文件

[root@CentOS7 ~]#⮀ansible group1 -m copy -a 'content="CentOS\nLinux\ntest" dest=/data/test.txt'   #将指定内容直接创建在对端的/data/test.txt中
192.168.30.69 | SUCCESS => {
    "changed": true, 
    "checksum": "0f7fd4a4cccdbf903bdb895e22abfa4d594ca2b6", 
    "dest": "/data/test.txt", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "d244d5f01cc6ae8f6dbd6e478f4aa43e", 
    "mode": "0644", 
    "owner": "root", 
    "size": 17, 
    "src": "~None/.ansible/tmp/ansible-tmp-1527582726.73-72421110990483/source", 
    "state": "file", 
    "uid": 0
}
192.168.30.75 | SUCCESS => {
    "changed": true, 
    "checksum": "0f7fd4a4cccdbf903bdb895e22abfa4d594ca2b6", 
    "dest": "/data/test.txt", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "d244d5f01cc6ae8f6dbd6e478f4aa43e", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "system_u:object_r:default_t:s0", 
    "size": 17, 
    "src": "~None/.ansible/tmp/ansible-tmp-1527582726.71-83329890814862/source", 
    "state": "file", 
    "uid": 0
}
[root@CentOS7 ~]#⮀ansible group1 -m shell -a 'cat /data/test.txt'   #查看对端主机的/data/test.txt文件
192.168.30.69 | SUCCESS | rc=0 >>
CentOS
Linux
test

192.168.30.75 | SUCCESS | rc=0 >>
CentOS
Linux
test

fetch 模块用于将对端主机的文件拉取到主控端。

[root@CentOS7 fetch_test]# ansible group2 -m fetch -a 'src=/etc/fstab dest=/data/fetch_test'
192.168.30.174 | SUCCESS => {
    "changed": true, 
    "checksum": "2b1777d51b0d5a8ca780204e76d8cbfbe1841856", 
    "dest": "/data/fetch_test/192.168.30.174/etc/fstab", 
    "md5sum": "020f628f8334bd9b8c3d3bd7f70307ad", 
    "remote_checksum": "2b1777d51b0d5a8ca780204e76d8cbfbe1841856", 
    "remote_md5sum": null
}
192.168.30.75 | SUCCESS => {
    "changed": true, 
    "checksum": "cfafdc9012666a8e6e02dd5edb67dafc6ba4d181", 
    "dest": "/data/fetch_test/192.168.30.75/etc/fstab", 
    "md5sum": "f5fbd1248d0b8c3e1b7003897a3d8d84", 
    "remote_checksum": "cfafdc9012666a8e6e02dd5edb67dafc6ba4d181", 
    "remote_md5sum": null
}
[root@CentOS7 fetch_test]# tree   #当拉取多个主机上文件时,默认会将不同主机文件保存在各自的目录下,没有此目录则会创建
.
├── 192.168.30.174
│   └── etc
│       └── fstab
└── 192.168.30.75
    └── etc
        └── fstab

4 directories, 2 files

    选项

src:必选项。要拉取到本机的远程主机文件
dest:本机保存路径
flat:默认为no,当为 yes 时,将不会保存路径信息

[root@CentOS7 fetch_test]# ansible 192.168.30.75 -m fetch -a  'src=/etc/fstab dest=/data/fetch_test/test'
192.168.30.75 | SUCCESS => {
    "changed": true, 
    "checksum": "cfafdc9012666a8e6e02dd5edb67dafc6ba4d181", 
    "dest": "/data/fetch_test/test/192.168.30.75/etc/fstab", 
    "md5sum": "f5fbd1248d0b8c3e1b7003897a3d8d84", 
    "remote_checksum": "cfafdc9012666a8e6e02dd5edb67dafc6ba4d181", 
    "remote_md5sum": null
}
[root@CentOS7 fetch_test]# tree   #拉取文件时并能不保存并改名,当指定一个不存在的路径时,则会创建为目录
.
└── test
    └── 192.168.30.75
        └── etc
            └── fstab

3 directories, 1 file
[root@CentOS7 fetch_test]# ansible 192.168.30.75 -m fetch -a  'flat=yes src=/etc/fstab dest=/data/fetch_test/test'
192.168.30.75 | SUCCESS => {
    "changed": true, 
    "checksum": "cfafdc9012666a8e6e02dd5edb67dafc6ba4d181", 
    "dest": "/data/fetch_test/test", 
    "md5sum": "f5fbd1248d0b8c3e1b7003897a3d8d84", 
    "remote_checksum": "cfafdc9012666a8e6e02dd5edb67dafc6ba4d181", 
    "remote_md5sum": null
}
[root@CentOS7 fetch_test]# tree    #当flat=yes时,拉取文件时并不保留原路径
.
└── test

0 directories, 1 file

cron 模块用于创建计划任务。

[root@CentOS7 fetch_test]#⮀ansible all  -m cron -a 'minute=5 weekday=2,4,6 user=jiangbowen job="/usr/bin/wall CentOS!" name=Linux'
192.168.30.69 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "Linux"
    ]
}
192.168.30.174 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "Linux"
    ]
}
192.168.30.75 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "Linux"
    ]
}

切换到 jiangbowen 用户,使用 cron -e 查看创建出的计划任务文件

#Ansible: Linux
5 * * * 2,4,6 /usr/bin/wall CentOS!    

    选项

minute:分钟    hour:小时    day:天    month:月    weekday:星期
reboot:当下次开机时  yearly:每年  monthly:每月  weekly:每周  ...
name:计划任务的描述信息,同名的计划任务将会被后创建覆盖
disable:设为 yes 为禁用指定计划任务
job:执行的操作
state:设为 absent 为删除指定计划任务,present 为创建计划任务,缺省为 present
cron_file:指定计划任务文件名,计划任务将创建在 cron.d 目录下,再次创建同名的计划任务文件会覆盖掉原有的计划任务,且无视 backup 选项,在创建时要指定user

user:以指定用户身份创建计划任务

[root@CentOS7 fetch_test]# ansible all  -m cron -a 'state=absent user=jiangbowen name=Linux'  #删除计划任务时,需要指定name,当不是默认用户时,还需要指定用户
192.168.30.69 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": []
}
192.168.30.174 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": []
}
192.168.30.75 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": []
}
[root@CentOS7 fetch_test]# ansible all  -m cron -a 'state=absent user=root cron_file=MyCron'   #删除计划任务文件时,需要指定文件名与用户,
192.168.30.69 | SUCCESS => {   
    "changed": true, 
    "cron_file": "MyCron", 
    "state": "absent"
}
192.168.30.174 | SUCCESS => {
    "changed": true, 
    "cron_file": "MyCron", 
    "state": "absent"
}
192.168.30.75 | SUCCESS => {
    "changed": true, 
    "cron_file": "MyCron", 
    "state": "absent"
}

file 模块可以管理文件的属性

[root@CentOS7 ~]# ansible group1 -m file -a 'state=absent dest=/data/secfstab'
192.168.30.69 | SUCCESS => {
    "changed": true, 
    "path": "/data/secfstab", 
    "state": "absent"
}
192.168.30.75 | SUCCESS => {
    "changed": true, 
    "path": "/data/secfstab", 
    "state": "absent"
}

    选项

state:修改文件状态
    directory:创建目录,支持多级创建
    file:判断文件存在性
    link:创建软链接
    hard:创建硬链接接
    absent:删除文件,如果是目录将会被递归删除
    touch:创建文件,如果文件已经存在,将修改时间戳
dest:目标文件或目录的路径和名称
src:指定链接文件的源文件
mode:设置文件权限
owner:设置文件的属主信息
group:设置文件的属组信息

force:强制创建链接文件,即使源文件不存在,如果链接文件已存在,便覆盖state:修改文件状态

[root@CentOS7 ~]# ansible all -m file -a 'force=yes state=link src=/data/NewFile dest=/data/LinkFile'    #192.168.30.174主机中没有/data/NewFile文件
192.168.30.69 | SUCCESS => {
    "changed": true, 
    "dest": "/data/LinkFile", 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "root", 
    "size": 13, 
    "src": "/data/NewFile", 
    "state": "link", 
    "uid": 0
}
 [WARNING]: Cannot set fs attributes on a non-existent symlink target. follow should be set to False to avoid this.
#提示没有源文件,但是制定了force选项,还是创建了指向不存在文件的链接文件
192.168.30.174 | SUCCESS => {
    "changed": true, 
    "dest": "/data/LinkFile", 
    "src": "/data/NewFile", 
    "state": "absent"
}
192.168.30.75 | SUCCESS => {
    "changed": true, 
    "dest": "/data/LinkFile", 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:etc_runtime_t:s0", 
    "size": 13, 
    "src": "/data/NewFile", 
    "state": "link", 
    "uid": 0
}
[root@CentOS7 ~]# ansible all -m shell -a 'ls -l /data/LinkFile'
192.168.30.69 | SUCCESS | rc=0 >>
lrwxrwxrwx 1 root root 13 May 30 20:04 /data/LinkFile -> /data/NewFile

192.168.30.174 | SUCCESS | rc=0 >>
lrwxrwxrwx 1 root root 13 May 30 08:04 /data/LinkFile -> /data/NewFile   #/data/NewFile文件不存在

192.168.30.75 | SUCCESS | rc=0 >>
lrwxrwxrwx. 1 root root 13 May 31 04:04 /data/LinkFile -> /data/NewFileh

hostname 模块用于管理对端主机名。

[root@CentOS7 ~]#⮀ansible 192.168.30.174 -m hostname -a 'name=NewName'
192.168.30.174 | SUCCESS => {
    "ansible_facts": {
        "ansible_domain": "", 
        "ansible_fqdn": "NewName", 
        "ansible_hostname": "NewName", 
        "ansible_nodename": "NewName"
    }, 
    "changed": true, 
    "name": "NewName"
}

yum 模块能够管理软件包。

[root@CentOS7 ~]#⮀ansible 192.168.30.174 -m yum -a 'name=bind state=installed'
192.168.30.174 | SUCCESS => {
    "changed": true, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "Loaded plugins: fastestmirror, langpacks\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Running transaction check\n---> Package bind.x86_64 32:9.9.4-50.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package      Arch           Version                  Repository           Size\n================================================================================\nInstalling:\n bind         x86_64         32:9.9.4-50.el7          development         1.8 M\n\nTransaction Summary\n================================================================================\nInstall  1 Package\n\nTotal download size: 1.8 M\nInstalled size: 4.3 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : 32:bind-9.9.4-50.el7.x86_64                                  1/1 \n  Verifying  : 32:bind-9.9.4-50.el7.x86_64                                  1/1 \n\nInstalled:\n  bind.x86_64 32:9.9.4-50.el7                                                   \n\nComplete!\n"
    ]
}

    选项

disablerepo:禁用某个 yum 源
enblerepo:启用某个 yum 源
name:软件包名
state:installed 为安装,removed 为卸载
lsit:显示"installed","updates","available'"和"repos"中的包

service 模块能够管理服务。

[root@CentOS7 ~]# ansible group1 -m service -a 'name=httpd state=started'
192.168.30.75 | SUCCESS => {
    "changed": true, 
    "name": "httpd", 
    "state": "started", 
    "status": {
        "ActiveEnterTimestampMonotonic": "0", 
        "ActiveExitTimestampMonotonic": "0", 
        "ActiveState": "inactive", 
        "After": "systemd-journald.socket system.slice remote-fs.target basic.target network.target tmp.mount -.mount nss-lookup.target", 
        "AllowIsolate": "no", 
        ...
    }
}
192.168.30.69 | SUCCESS => {
    "changed": true, 
    "name": "httpd", 
    "state": "started"
}

    选项

enabled:开机是否启动
name:服务名
runleval:指定运行级别
sleep:在重启服务时,启动前会等待指定时间
state:
    started:启动
    stopped:停止
    restarted:重启
    reloaded:重载

user 模块用于管理用户的信息。

[root@CentOS7 ~]# ansible 192.168.30.174 -m user -a 'name=TestUser group=jiangbowen comment="test user" system=yes'
192.168.30.174 | SUCCESS => {
    "changed": true, 
    "comment": "test user", 
    "create_home": true, 
    "group": 1000, 
    "home": "/home/TestUser", 
    "name": "TestUser", 
    "shell": "/bin/bash", 
    "state": "present", 
    "system": true, 
    "uid": 996
}

    选项

name:用户名
state:缺省 present 为添加用户,absent 为删除用户
system:是否创建为系统用户
home:指定家目录
creathome:是否创建家目录
uid:指定 UID
group:指定用户组
password:此选项会将明文密码存入 /etc/shadow 文件中,但是在登陆时会将输入的密码加密后与文件中的密码比对,所以在设置密码时需要使用 openssl passwd -1 "密码" 命令生成密文后再使用 ansible 设置密码。

[root@CentOS7 ~]# ansible 192.168.30.174 -m user -a 'name=TestUser password=centos'
192.168.30.174 | SUCCESS => {
    "append": false, 
    "changed": true, 
    "comment": "test user", 
    "group": 1000, 
    "home": "/home/TestUser", 
    "move_home": false, 
    "name": "TestUser", 
    "password": "NOT_LOGGING_PASSWORD", 
    "shell": "/bin/bash", 
    "state": "present", 
    "uid": 996
}
[root@CentOS7 ~]# ansible 192.168.30.174 -m shell -a 'getent shadow TestUser'
192.168.30.174 | SUCCESS | rc=0 >>
TestUser:centos:17681::::::   #密码为明文,会导致登陆密码错误

group 模块可以管理用户组。

[root@CentOS7 ~]# ansible 192.168.30.174 -m group -a 'name=TestUser gid=1111'
192.168.30.174 | SUCCESS => {
    "changed": true, 
    "gid": 1111, 
    "name": "TestUser", 
    "state": "present", 
    "system": false
}
[root@CentOS7 ~]# ansible 192.168.30.174 -m shell -a 'getent group TestUser'
192.168.30.174 | SUCCESS | rc=0 >>
TestUser:x:1111:x

    选项

name:用户名
state:缺省 present 为添加组,absent 为删除组
system:是否创建为系统组
gid:指定 GID

mount 模块用于挂载文件

[root@CentOS7 ~]#⮀ansible 192.168.30.75 -m mount -a 'src=/dev/sr0 path=/mnt/cdrom state=mounted fstype=iso9660'
192.168.30.75 | SUCCESS => {         #必须指定文件系统
    "changed": true, 
    "dump": "0", 
    "fstab": "/etc/fstab", 
    "fstype": "iso9660", 
    "name": "/mnt/cdrom", 
    "opts": "defaults", 
    "passno": "0", 
    "src": "/dev/sr0"
}
[root@CentOS7 ~]#⮀ansible 192.168.30.75 -m shell -a 'cat /etc/fstab'
192.168.30.75 | SUCCESS | rc=0 >>

#
# /etc/fstab
# Created by anaconda on Wed May 23 01:10:20 2018
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=8a963d68-4561-4fe2-9479-47ed2421ab9d /                       xfs     defaults        0 0
UUID=04af341f-9ac3-4da3-9298-71759aff9e41 /boot                   xfs     defaults        0 0
UUID=ec1cbe64-cf82-4d3b-aee5-d321f9500f8e /data                   xfs     defaults        0 0
UUID=d5eb5f25-9563-4a26-bac2-cadde7466cbf swap                    swap    defaults        0 0
/dev/sr0 /mnt/cdrom iso9660 defaults 0 0

[root@CentOS7 ~]#⮀ansible 192.168.30.75 -m shell -a 'df'
192.168.30.75 | SUCCESS | rc=0 >>
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sda2       52403200 3630368  48772832   7% /
devtmpfs          748312       0    748312   0% /dev
tmpfs             764204       0    764204   0% /dev/shm
tmpfs             764204   10220    753984   2% /run
tmpfs             764204       0    764204   0% /sys/fs/cgroup
/dev/sda3       20961280  245792  20715488   2% /data
/dev/sda1        1038336  157936    880400  16% /boot
tmpfs             152844       0    152844   0% /run/user/0
/dev/sr0         9176232 9176232         0 100% /mnt/cdrom   #挂载成功

    选项

src:要挂载的设备

path:挂载路径

state:

    present:在 /etc/fstab 文件中添加挂载信息

    absent:在 /etc/fstab 中删除挂载信息并卸载设备

    mounted:在 /etc/fstab 文件中添加挂载信息后再挂载设备

    unmounted:卸载指定路径挂载设备

fstype:指定文件系统类型





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章