自动化运维之Ansible(三)

Ansible系列命令

ansible有许多的命令,ansible、ansible-doc、ansible-playbook、ansible-vault、ansible-console、ansible-galaxy、ansible-pull,以下以较常用的几个命令做详细的说明。

ansible-doc命令

ansible-doc用来显示ansible中各种模块的简要帮助信息

语法:

1
ansible-doc [-l|-F|-s] [options] [-t <plugin type> ] [plugin]
选项 说明
-l 列出可用模块
-a 显示所有模块的文档
-s 显示指定模块的playbook片段

示例:

1
2
3
4
5
6
#列出所有模块
[root@localhost ~]# ansible-doc -l
#查看指定模块的用法
[root@localhost ~]# ansible-doc ping
#查看指定模块的简单用法
[root@localhost ~]# ansible-doc -s ping

ansible命令

ansible通过ssh实现配置管理、应用部署、任务执行等功能。

语法:

1
ansible <host-patten> [-m module_name] [-a args]
选项 说明
–version 显示版本
-m module 指定模块,默认为command,可以通过修改配置文件进行修改
-v 显示详细过程 -vv -vvv可以显示更加详细的内容
–list-hosts 显示主机列表,可以缩写–list
-k 提示输入ssh连接密码,默认KEY验证
-C 检查不执行
-T,–timeout=TIMEOUT 执行命令的超时时长
-u,–user=REMOTE_USER 指定远程执行的用户
-b,–become 代替旧版的sudo其替换
–become-user=USERNAME 指定sudo的runas用户,默认为root
-K,–ask-become-pass 提示输入sudo时的口令

ansible的模块

ping模块

ping 用来测试主机的连通性

使用ansible-doc命令可以查看模块用法,使用-s可以简单的查看简单相关用法

1
2
3
4
5
6
7
8
[root@ansible ~]# ansible-doc -s ping
- name: Try to connect to host, verify a usable python and return `pong' on success
ping:
data: # Data to return for the `ping' return value. If this
parameter is set to `crash',
the module will cause an
exception.

测试1:

使用ping模块进行测试时报错,提示错误,因为默认为key连接由于没有配置key所以报错

1
2
3
4
5
6
[root@ansible ~]# ansible 192.168.73.134 -m ping
192.168.73.134 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: Permission denied (publickey,password).",
"unreachable": true
}

测试2:

带上-k选项后

1
2
3
4
5
6
[root@ansible ~]# ansible 192.168.73.134 -m ping -k
SSH password:
192.168.73.134 | SUCCESS => {
"changed": false,
"ping": "pong"
}

测试3:

使用组名,由于此处只给与一次输入密码,所以要确保被管理的两台主机必须要密码相同

1
2
3
4
5
6
7
8
9
10
[root@ansible ~]# ansible webserver -m ping -k
SSH password:
192.168.73.134 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.73.135 | SUCCESS => {
"changed": false,
"ping": "pong"
}

测试4:

指定由哪个用户执行操作

1
2
3
4
5
6
7
8
9
10
[root@ansible ~]# ansible webserver -m ping -u masuri -k
SSH password:
192.168.73.135 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.73.134 | SUCCESS => {
"changed": false,
"ping": "pong"
}

测试5:

使用-b让普通用户用sudo的方法进行操作,如果没有授予sudo的权限,会失败

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@ansible ~]# ansible webserver -m ping -u masuri -k -b
SSH password:
192.168.73.134 | FAILED! => {
"changed": false,
"module_stderr": "Shared connection to 192.168.73.134 closed.\r\n",
"module_stdout": "sudo: a password is required\r\n",
"msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
"rc": 1
}
192.168.73.135 | FAILED! => {
"changed": false,
"module_stderr": "Shared connection to 192.168.73.135 closed.\r\n",
"module_stdout": "sudo: a password is required\r\n",
"msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
"rc": 1
}

测试6:

分别授予sudo权限后再次测试,此次带上-K选项,表示输入sudo口令执行命令,若要不输入口令,可以在sudo的配置文件中使用NOPASSWD选项。(一般不常用)

1
2
3
4
5
6
7
8
9
10
11
12
[root@ansible ~]# ansible webserver -m ping -u masuri -k -b -K
SSH password:
SUDO password[defaults to SSH password]:
192.168.73.135 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.73.134 | SUCCESS => {
"changed": false,
"ping": "pong"
}

以上为基于密钥的验证方法,ansible真正在生产环境中使用时还是需要基于key的验证方法

基于key的验证方法

在ansible主机上创建私钥文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@ansible ~]# ssh-keygen -t rsa -P "" -f .ssh/id_rsa
Generating public/private rsa key pair.
Your identification has been saved in .ssh/id_rsa.
Your public key has been saved in .ssh/id_rsa.pub.
The key fingerprint is:
SHA256:UAFYDd5EBqFIyC81+UYk9DZ3lRDZ3XUkr4K/FetFu+c root@ansible
The key's randomart image is:
+---[RSA 2048]----+
|..ooo+*B*+=.o o.=|
|.o =++ =...o . +.|
| + =+o... .|
| . ..oo.. . . |
| . . S . . o .|
| . . +.|
| . o..|
| + .o|
| . .oE|
+----[SHA256]-----+

将公钥复制到被管理的主机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@ansible ~]# ssh-copy-id 192.168.73.134
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.73.134's password:

Number of key(s) added: 1

Now try logging into the machine, with: "ssh '192.168.73.134'"
and check to make sure that only the key(s) you wanted were added.

[root@ansible ~]# ssh-copy-id 192.168.73.135
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.73.135's password:

Number of key(s) added: 1

Now try logging into the machine, with: "ssh '192.168.73.135'"
and check to make sure that only the key(s) you wanted were added.

测试7:

此时再使用ping模块时不再需要带任何参数

1
2
3
4
5
6
7
8
9
[root@ansible ~]# ansible webserver -m ping 
192.168.73.134 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.73.135 | SUCCESS => {
"changed": false,
"ping": "pong"
}

shell模块

shell模块用于执行shell命令

查看shell模块简单用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@ansible ~]# ansible-doc -s shell
- name: Execute commands in nodes.
shell:
chdir: # cd into this directory before running the command
creates: # a filename, when it already exists, this step will *not* be
run.
executable: # change the shell used to execute the command. Should be an
absolute path to the
executable.
free_form: # (required) The shell module takes a free form command to
run, as a string. There's
not an actual option named
"free form". See the
examples!
removes: # a filename, when it does not exist, this step will *not* be
run.
stdin: # Set the stdin of the command directly to the specified
value.
warn: # if command warnings are on in ansible.cfg, do not warn about
this particular line if set
to no/false.

示例1:

使用shell来修改用户口令

1
2
3
4
5
6
7
8
[root@ansible ~]# ansible webserver -m shell -a 'echo 123456 | passwd --stdin masuri'
192.168.73.134 | CHANGED | rc=0 >>
Changing password for user masuri.
passwd: all authentication tokens updated successfully.

192.168.73.135 | CHANGED | rc=0 >>
Changing password for user masuri.
passwd: all authentication tokens updated successfully.

示例2:
在shell模块中使用变量时参数需要使用单引号,若使用双引号则变量指向的是本机的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#单引号效果
[root@ansible ~]# ansible webserver -m shell -a 'echo $HOSTNAME'
192.168.73.134 | CHANGED | rc=0 >>
web1

192.168.73.135 | CHANGED | rc=0 >>
web2
#双引号的效果
[root@ansible ~]# ansible webserver -m shell -a "echo $HOSTNAME"
192.168.73.135 | CHANGED | rc=0 >>
ansible

192.168.73.134 | CHANGED | rc=0 >>
ansible

示例3:

使用shell重定向

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@ansible ~]# ansible webserver -m shell -a 'chdir=/data echo welcome to magedu > test.log'
192.168.73.135 | CHANGED | rc=0 >>


192.168.73.134 | CHANGED | rc=0 >>

#查看重定向是否成功
[root@ansible ~]# ansible webserver -m shell -a 'chdir=/data cat test.log'
192.168.73.135 | CHANGED | rc=0 >>
welcome to magedu

192.168.73.134 | CHANGED | rc=0 >>
welcome to magedu

示例4:

使用sed对文件进行修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@ansible ~]# ansible webserver -m shell -a 'sed -i "s/welcome to magedu/welcome to mylinuxops/" /data/test.log'
[WARNING]: Consider using the replace, lineinfile or template module rather than running
'sed'. If you need to use command because replace, lineinfile or template is insufficient
you can add 'warn: false' to this command task or set 'command_warnings=False' in
ansible.cfg to get rid of this message.

192.168.73.134 | CHANGED | rc=0 >>


192.168.73.135 | CHANGED | rc=0 >>

#验证是否修改
[root@ansible ~]# ansible webserver -m shell -a 'cat /data/test.log'
192.168.73.134 | CHANGED | rc=0 >>
welcome to mylinuxops

192.168.73.135 | CHANGED | rc=0 >>
welcome to mylinuxops

script模块

script 模块是在远程主机上运行ansible服务器上的脚本

示例1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@ansible ~]# vim hello.sh      #构建出一个简单的脚本
#!/bin/bash
echo "hello world"
[root@ansible ~]# chmod +x hello.sh
[root@ansible ~]# ansible webserver -m script -a '/root/hello.sh'
192.168.73.134 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.73.134 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.73.134 closed."
],
"stdout": "hello world\r\n",
"stdout_lines": [
"hello world"
]
}
192.168.73.135 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.73.135 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.73.135 closed."
],
"stdout": "hello world\r\n",
"stdout_lines": [
"hello world"
]
}

copy模块

copy 从主控端复制文件到远程主机

参数 说明
src 本机的源文件位置
dest 目标主机存放文件位置
owner 修改属主
group 修改属组
mode 修改权限
backup 备份,copy时文件若是存在会直接覆盖
content 指定生成文件的内容

示例1:

复制本机文件到远程主机,并修改属主,修改权限。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@ansible ~]# ansible webserver -m copy -a 'src=/etc/fstab dest=/data/fstab2 owner=masuri mode=666 backup=yes'
192.168.73.134 | CHANGED => {
"changed": true,
"checksum": "e18dfdc22b5e67945358018dfcca8f1c8b25722c",
"dest": "/data/fstab2",
"gid": 0,
"group": "root",
"md5sum": "4c98128827229df5554dee614d84d607",
"mode": "0666",
"owner": "masuri",
"size": 595,
"src": "/root/.ansible/tmp/ansible-tmp-1556157419.7-268980429666588/source",
"state": "file",
"uid": 1000
}
192.168.73.135 | CHANGED => {
"changed": true,
"checksum": "e18dfdc22b5e67945358018dfcca8f1c8b25722c",
"dest": "/data/fstab2",
"gid": 0,
"group": "root",
"md5sum": "4c98128827229df5554dee614d84d607",
"mode": "0666",
"owner": "masuri",
"size": 595,
"src": "/root/.ansible/tmp/ansible-tmp-1556157419.7-28176178316202/source",
"state": "file",
"uid": 1000
}

示例2:

使用content直接生成文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
[root@ansible ~]# ansible webserver -m copy -a 'content="hello word\nwelcome to mylinuxops\n" dest=/data/test1'
192.168.73.134 | CHANGED => {
"changed": true,
"checksum": "89b51930dc2793a1ea796637d25b982d1c93aa90",
"dest": "/data/test1",
"gid": 0,
"group": "root",
"md5sum": "b16c04a75e320a9862568401301b6b02",
"mode": "0644",
"owner": "root",
"size": 33,
"src": "/root/.ansible/tmp/ansible-tmp-1556158261.88-98867568897388/source",
"state": "file",
"uid": 0
}
192.168.73.135 | CHANGED => {
"changed": true,
"checksum": "89b51930dc2793a1ea796637d25b982d1c93aa90",
"dest": "/data/test1",
"gid": 0,
"group": "root",
"md5sum": "b16c04a75e320a9862568401301b6b02",
"mode": "0644",
"owner": "root",
"size": 33,
"src": "/root/.ansible/tmp/ansible-tmp-1556158261.89-218330298518724/source",
"state": "file",
"uid": 0
}

#验证
[root@ansible ~]# ansible webserver -a 'cat /data/test1'
192.168.73.135 | CHANGED | rc=0 >>
hello word
welcome to mylinuxops

192.168.73.134 | CHANGED | rc=0 >>
hello word
welcome to mylinuxops

fetch模块

fetch 从远程主机提取文件至主控端,只能提取文件,若要提取目录可以将目录先打包

参数 说明
dest 在主控端存放文件的位置
src 远程主机所要提取的文件

示例1:

将远程主机的/etc/fstab,抓取至本地的/data

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@ansible ~]# ansible webserver -m fetch -a 'dest=/data src=/etc/fstab'
192.168.73.135 | CHANGED => {
"changed": true,
"checksum": "e18dfdc22b5e67945358018dfcca8f1c8b25722c",
"dest": "/data/192.168.73.135/etc/fstab",
"md5sum": "4c98128827229df5554dee614d84d607",
"remote_checksum": "e18dfdc22b5e67945358018dfcca8f1c8b25722c",
"remote_md5sum": null
}
192.168.73.134 | CHANGED => {
"changed": true,
"checksum": "e18dfdc22b5e67945358018dfcca8f1c8b25722c",
"dest": "/data/192.168.73.134/etc/fstab",
"md5sum": "4c98128827229df5554dee614d84d607",
"remote_checksum": "e18dfdc22b5e67945358018dfcca8f1c8b25722c",
"remote_md5sum": null
}

示例2:

将远程/etc/目录抓取至本地的/data

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#抓取目录分两步走,先打包
[root@ansible ~]# ansible webserver -a 'tar Jcf /data/etc.tar.xz /etc'
[WARNING]: Consider using the unarchive module rather than running 'tar'. If you need to
use command because unarchive is insufficient you can add 'warn: false' to this command
task or set 'command_warnings=False' in ansible.cfg to get rid of this message.

192.168.73.135 | CHANGED | rc=0 >>
tar: Removing leading `/' from member names

192.168.73.134 | CHANGED | rc=0 >>
tar: Removing leading `/' from member names

#提取打包文件
[root@ansible ~]# ansible webserver -m fetch -a 'dest=/data src=/data/etc.tar.xz'
192.168.73.135 | CHANGED => {
"changed": true,
"checksum": "2c7d756eff60249623f58d2ebec290848c4dea89",
"dest": "/data/192.168.73.135/data/etc.tar.xz",
"md5sum": "b20b3a78bcfd25d09d9ce2c9b7beeba3",
"remote_checksum": "2c7d756eff60249623f58d2ebec290848c4dea89",
"remote_md5sum": null
}
192.168.73.134 | CHANGED => {
"changed": true,
"checksum": "c95913f7a079f6c1fb31016105b524685a21cb2d",
"dest": "/data/192.168.73.134/data/etc.tar.xz",
"md5sum": "e075e6d2681d7dbedaf070ad81ebd3e3",
"remote_checksum": "c95913f7a079f6c1fb31016105b524685a21cb2d",
"remote_md5sum": null
}

File模块

File模块可以设置文件的属性

参数 说明
access_time 访问时间
access_time_format 时间格式
attributes attr格式
force 当软连接的源文件不存在时使用
group 设置文件的属组
mode 设置文件的权限
modification_time 文件修改时间
modification_time_format 文件修改时间格式
owner 设置文件的属主
path 被管理的文件路径
src 指定软硬链接的源文件位置
state 设置文件的类型,file:文件不存在时不会被创建,link:创建软连接,hard:创建硬连接,absent:删除文件,touch:创建空文件

示例1:

修改文件的属主,权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[root@ansible data]# ansible webserver -m file -a 'path=/data/test1 owner=masuri mode=777'
192.168.73.134 | CHANGED => {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "masuri",
"path": "/data/test1",
"size": 33,
"state": "file",
"uid": 1000
}
192.168.73.135 | CHANGED => {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "masuri",
"path": "/data/test1",
"size": 33,
"state": "file",
"uid": 1000
}

#查看属性
[root@ansible data]# ansible webserver -a 'ls -l /data/test1'
192.168.73.135 | CHANGED | rc=0 >>
-rwxrwxrwx 1 masuri root 33 Apr 25 10:11 /data/test1

192.168.73.134 | CHANGED | rc=0 >>
-rwxrwxrwx 1 masuri root 33 Apr 25 10:11 /data/test1

示例2:

创建硬连接,state=hard

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
[root@ansible data]# ansible webserver -m file -a 'src=/data/test1 name=/data/test1.log state=hard'
192.168.73.134 | CHANGED => {
"changed": true,
"dest": "/data/test1.log",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "masuri",
"size": 33,
"src": "/data/test1",
"state": "hard",
"uid": 1000
}
192.168.73.135 | CHANGED => {
"changed": true,
"dest": "/data/test1.log",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "masuri",
"size": 33,
"src": "/data/test1",
"state": "hard",
"uid": 1000
}
#查看文件
[root@ansible data]# ansible webserver -a 'ls -l /data/test1.log'
192.168.73.134 | CHANGED | rc=0 >>
-rwxrwxrwx 2 masuri root 33 Apr 25 10:11 /data/test1.log

192.168.73.135 | CHANGED | rc=0 >>
-rwxrwxrwx 2 masuri root 33 Apr 25 10:11 /data/test1.log

示例3:

创建软连接,state=link

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
[root@ansible data]# ansible webserver -m file -a 'src=/data/test1 name=/data/123 state=link'
192.168.73.135 | CHANGED => {
"changed": true,
"dest": "/data/123",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"size": 11,
"src": "/data/test1",
"state": "link",
"uid": 0
}
192.168.73.134 | CHANGED => {
"changed": true,
"dest": "/data/123",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"size": 11,
"src": "/data/test1",
"state": "link",
"uid": 0
}
#验证
[root@ansible data]# ansible webserver -a 'ls -l /data/123'
192.168.73.135 | CHANGED | rc=0 >>
lrwxrwxrwx 1 root root 11 Apr 25 10:56 /data/123 -> /data/test1

192.168.73.134 | CHANGED | rc=0 >>
lrwxrwxrwx 1 root root 11 Apr 25 10:56 /data/123 -> /data/test1

示例4:

创建空文件,state=touch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[root@ansible data]# ansible webserver -m file -a 'path=/data/test2 state=touch'
192.168.73.134 | CHANGED => {
"changed": true,
"dest": "/data/test2",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"size": 0,
"state": "file",
"uid": 0
}
192.168.73.135 | CHANGED => {
"changed": true,
"dest": "/data/test2",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"size": 0,
"state": "file",
"uid": 0
}
#验证
[root@ansible data]# ansible webserver -a 'ls -l /data/test2'
192.168.73.135 | CHANGED | rc=0 >>
-rw-r--r-- 1 root root 0 Apr 25 10:59 /data/test2

192.168.73.134 | CHANGED | rc=0 >>
-rw-r--r-- 1 root root 0 Apr 25 10:59 /data/test2

示例5:

删除文件,state=absent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@ansible data]# ansible webserver -m file -a 'path=/data/test2 state=absent'
192.168.73.134 | CHANGED => {
"changed": true,
"path": "/data/test2",
"state": "absent"
}
192.168.73.135 | CHANGED => {
"changed": true,
"path": "/data/test2",
"state": "absent"
}
#验证
[root@ansible data]# ansible webserver -a 'ls -l /data/test2'
192.168.73.135 | FAILED | rc=2 >>
ls: cannot access /data/test2: No such file or directorynon-zero return code

192.168.73.134 | FAILED | rc=2 >>
ls: cannot access /data/test2: No such file or directorynon-zero return code

hostname 模块

hostname 管理主机名

参数 说明
name 设置主机名

示例:

1
2
3
4
5
6
7
8
9
10
11
[root@ansible data]# ansible 192.168.73.134 -m hostname -a 'name=mylinuxops.com'
192.168.73.134 | CHANGED => {
"ansible_facts": {
"ansible_domain": "com",
"ansible_fqdn": "mylinuxops.com",
"ansible_hostname": "mylinuxops",
"ansible_nodename": "mylinuxops.com"
},
"changed": true,
"name": "mylinuxops.com"
}

cron 模块

corn 计划任务模块

参数 说明
backup 在计划任务创建前先备份
day
hour 小时
minute 分钟
month
weekday 星期
name 计划任务的名称
reboot 重启后执行
state absent:删除
job 计划任务的内容
disabled 启用和禁用

示例1:

创建计划任务,每天1点备份/etc/目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@ansible data]# ansible webserver -m cron -a 'name=backupetc hour=1 job="/usr/bin/cp -a /etc /data/`date +%F`"'
192.168.73.135 | CHANGED => {
"changed": true,
"envs": [],
"jobs": [
"backupetc"
]
}
192.168.73.134 | CHANGED => {
"changed": true,
"envs": [],
"jobs": [
"backupetc"
]
}
#验证
[root@ansible data]# ansible webserver -a 'crontab -l'
192.168.73.134 | CHANGED | rc=0 >>
#Ansible: backupetc
* 1 * * * /usr/bin/cp -a /etc /data/`date +%F`

192.168.73.135 | CHANGED | rc=0 >>
#Ansible: backupetc
* 1 * * * /usr/bin/cp -a /etc /data/`date +%F`

示例2:

计划任务的禁用,disabled=true

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@ansible data]# ansible webserver -m cron -a 'name=backupetc day=* hour=1 job="/usr/bin/cp -a /etc /data/`date +%F`" disabled=true'
192.168.73.135 | CHANGED => {
"changed": true,
"envs": [],
"jobs": [
"backupetc"
]
}
192.168.73.134 | CHANGED => {
"changed": true,
"envs": [],
"jobs": [
"backupetc"
]
}
#验证
[root@ansible data]# ansible webserver -a 'crontab -l'
192.168.73.135 | CHANGED | rc=0 >>
#Ansible: backupetc
#* 1 * * * /usr/bin/cp -a /etc /data/`date +%F`

192.168.73.134 | CHANGED | rc=0 >>
#Ansible: backupetc
#* 1 * * * /usr/bin/cp -a /etc /data/`date +%F`

示例3:

计划任务的启用,disabled=false

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@ansible data]# ansible webserver -m cron -a 'name=backupetc day=* hour=1 job="/usr/bin/cp -a /etc /data/`date +%F`" disabled=false'
192.168.73.135 | CHANGED => {
"changed": true,
"envs": [],
"jobs": [
"backupetc"
]
}
192.168.73.134 | CHANGED => {
"changed": true,
"envs": [],
"jobs": [
"backupetc"
]
}
#验证:
[root@ansible data]# ansible webserver -a 'crontab -l'
192.168.73.135 | CHANGED | rc=0 >>
#Ansible: backupetc
* 1 * * * /usr/bin/cp -a /etc /data/`date +%F`

192.168.73.134 | CHANGED | rc=0 >>
#Ansible: backupetc
* 1 * * * /usr/bin/cp -a /etc /data/`date +%F

示例4:

删除计划任务,state=absent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@ansible data]# ansible webserver -m cron -a 'name=backupetc day=* hour=1 job="/usr/bin/cp -a /etc /data/`date +%F`" state=absent'
192.168.73.134 | CHANGED => {
"changed": true,
"envs": [],
"jobs": []
}
192.168.73.135 | CHANGED => {
"changed": true,
"envs": [],
"jobs": []
}
[root@ansible data]# ansible webserver -a 'crontab -l'
192.168.73.135 | CHANGED | rc=0 >>


192.168.73.134 | CHANGED | rc=0 >>

yum 模块

yum 包管理

参数 说明
name 包的名字
state present:安装(可缺省),absent:卸载

示例:

按装httpd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@ansible data]# ansible webserver -m yum -a 'name=httpd'
192.168.73.135 | CHANGED => {
"ansible_facts": {
...省略...
}

#验证
[root@ansible data]# ansible webserver -a 'rpm -q httpd'
[WARNING]: Consider using the yum, dnf or zypper module rather than running 'rpm'. If you need to use command
because yum, dnf or zypper is insufficient you can add 'warn: false' to this command task or set
'command_warnings=False' in ansible.cfg to get rid of this message.

192.168.73.134 | CHANGED | rc=0 >>
httpd-2.4.6-88.el7.centos.x86_64

192.168.73.135 | CHANGED | rc=0 >>
httpd-2.4.6-88.el7.centos.x86_64

示例2:

卸载httpd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@ansible data]# ansible webserver -m yum -a 'name=httpd state=absent'
192.168.73.134 | CHANGED => {
"ansible_facts": {
"pkg_mgr": "yum"
},
"changed": true,
"msg": "",
....省略

#验证
[root@ansible data]# ansible webserver -a 'rpm -q httpd'
[WARNING]: Consider using the yum, dnf or zypper module rather than running 'rpm'. If you need to use command
because yum, dnf or zypper is insufficient you can add 'warn: false' to this command task or set
'command_warnings=False' in ansible.cfg to get rid of this message.

192.168.73.134 | FAILED | rc=1 >>
package httpd is not installednon-zero return code

192.168.73.135 | FAILED | rc=1 >>
package httpd is not installednon-zero return code

service 模块

service 用来管理服务

参数 说明
enabled 是否开机启动
name 服务名称
runlevel 运行在哪个级别上
state started:启动,stopped:停止,reloaded:重读配置文件,restarted:重启服务

示例1:

启动httpd服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@ansible ~]# ansible webserver -m service -a 'name=httpd state=started'
;^H192.168.73.135 | CHANGED => {
"changed": true,
"name": "httpd",
"state": "started",
"status": {
"ActiveEnterTimestampMonotonic": "0",
"ActiveExitTimestampMonotonic": "0",
...省略
#验证
[root@ansible ~]# ansible webserver -a 'ss -tnl | grep 80 '
192.168.73.134 | CHANGED | rc=0 >>
LISTEN 0 128 :::80 :::*

192.168.73.135 | CHANGED | rc=0 >>
LISTEN 0 128 :::80 :::*

user 模块

user 用户管理模块

参数 说明
name 指定用户名
system 系统用户
create_home 创建家目录
shell 指定shell类型
group 指定主组
groups 指定附加组
remove 删除用户是删除家目录
state absent:删除用户
uid 指定Uid号

示例:

创建mysql用户,为系统用户,shell类型为/sbin/nologin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[root@ansible ~]# ansible webserver -m user -a 'name=mysql system=yes shell=/sbin/nologin'
192.168.73.135 | CHANGED => {
"changed": true,
"comment": "",
"create_home": true,
"group": 996,
"home": "/home/mysql",
"name": "mysql",
"shell": "/sbin/nologin",
"state": "present",
"system": true,
"uid": 998
}
192.168.73.134 | CHANGED => {
"changed": true,
"comment": "",
"create_home": true,
"group": 996,
"home": "/home/mysql",
"name": "mysql",
"shell": "/sbin/nologin",
"state": "present",
"system": true,
"uid": 998
#验证
[root@ansible ~]# ansible webserver -a 'getent passwd mysql'
192.168.73.135 | CHANGED | rc=0 >>
mysql:x:998:996::/home/mysql:/sbin/nologin

192.168.73.134 | CHANGED | rc=0 >>
mysql:x:998:996::/home/mysql:/sbin/nologin

示例2

删除账号,删除账号时需要带上remove参数,默认不会删除用户的家目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@ansible ~]# ansible webserver -m user -a 'name=mysql remove=yes state=absent'
192.168.73.135 | CHANGED => {
"changed": true,
"force": false,
"name": "mysql",
"remove": true,
"state": "absent",
"stderr": "userdel: mysql mail spool (/var/spool/mail/mysql) not found\n",
"stderr_lines": [
"userdel: mysql mail spool (/var/spool/mail/mysql) not found"
]
}
192.168.73.134 | CHANGED => {
"changed": true,
"force": false,
"name": "mysql",
"remove": true,
"state": "absent",
"stderr": "userdel: mysql mail spool (/var/spool/mail/mysql) not found\n",
"stderr_lines": [
"userdel: mysql mail spool (/var/spool/mail/mysql) not found"
]
}

ansible-console

ansible-console为可交互的ansible工具,使用交互的模式对主机列表中的主机进行操作。

1
2
3
4
5
6
7
8
[root@ansible ~]# ansible-console
Welcome to the ansible console.
Type help or ? to list commands.

root@all (2)[f:5]$
#all:为当前的所有主机,切换组可以使用cd + 组名 的方式
#2:主机数
#f:5 并行执行数,设置并发数 fork + NUM