ansible常用模块及实验

ansible工具概述


一、ansible常用模块

ping 模块检查被管理机状态

范例:简述ping模块,及实验模块基于key验证

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
列出某个模块的说明 

ping模块:测试主机清单中的ip的主机是否于堡垒机知否可以正常通讯
查看ping模块的说明

[root@ansible ~]# ansible-doc ping
[root@ansible ~]# ansible 192.168.131.129 -m ping(第一次登陆基于ssh验证)

想要使得主机取消ssh连接的账户密码验证修改ansible的配置文件

[root@ansible ~]# vim /etc/ansible/ansible.cfg
#uncomment this to disable SSH key host checking
71 host_key_checking = False

再次执行ping模块(错误原为为ansible默认为key验证)

[root@ansible ~]# ansible 192.168.131.129 -m ping
192.168.131.129 | UNREACHABLE! => {
"changed": false,


想要解决错误可是使用-k选项 提示ssh连接输入连接用户的密码
[root@ansible ~]# ansible 192.168.131.129 -m ping -k
SSH password: root口令
192.168.131.129 | SUCCESS => {
"changed": false,
"ping": "pong"
}

-----------

脚本实现基于key验证,避免每次输口令,决绝对端主机口令不一致的现象

主机清单:
[root@ansible ~]# cat iplist.sh
192.168.131.129
192.168.131.173
192.168.131.185

安装expect
[root@ansible ~]# yum install expect -y

脚本:(前提是各主机密码统一设置为123456)
[root@ansible ~]# cat keyssh.sh
#!/bin/bash
user=root
ssh-keygen -t rsa -P "" -f /root/.ssh/id_rsa
while read line ;do
ip=$line
password=123456
expect << EOF
set timeout 10
spawn ssh-copy-id -i /root/.ssh/id_rsa.pub $user@$ip
expect {
"yes/no" { send "yes\n";exp_continue }
"password" { send "$password\n" }
}
expect eof
EOF
done < iplist.sh

[root@ansible ~]# bash keyssh.sh

ping模块基于key验证验证堡垒机是否与被控制端是否正常通讯

[root@ansible ~]# ansible all -m ping
192.168.131.129 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.131.173 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.131.185 | SUCCESS => {
"changed": false,
"ping": "pong"
}

Command:在远程主机执行命令,默认模块,可忽略-m选项

  • ansible srvs -m command -a ‘service vsftpd start’
  • ansible srvs -m command -a ‘echo magedu |passwd –stdin wang’ 不成功
  • 此命令不支持 $VARNAME < > | ; & 等,用shell模块实现

范例:ansible常用模块Command :在远程主机执行linux命令(默认模块)

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
在centos6被控制主机上有一个文件

[root@centos6 ~]# ls
a.txt

在控制机上使用command模块删除centos6上的文件 (系统模块名称可省略)

[root@ansible ~]# ansible 192.168.131.129 -m command -a 'rm -f /root/a.txt'
[WARNING]: Consider using file module with state=absent rather than running rm

192.168.131.129 | SUCCESS | rc=0 >>

查看所有被控制机上的主机列表

[root@ansible ~]# ansible all -m command -a 'getent passwd'
模块名称可省略
[root@ansible ~]# ansible 192.168.131.129 -a 'getent passwd'

在centos6被控制机上创建用户

[root@ansible ~]# ansible 192.168.131.129 -a 'useradd user11'
192.168.131.129 | SUCCESS | rc=0 >>
[root@ansible ~]# ansible 192.168.131.129 -a 'getent passwd user11'
192.168.131.129 | SUCCESS | rc=0 >>
user11:x:501:501::/home/user11:/bin/bash

Shell:和command相似,用shell执行命令

  • ansible srv -m shell -a ‘echo magedu |passwd –stdin wang’
  • 调用bash执行命令 类似 cat /tmp/stanley.md | awk -F‘|’ ‘{print $1,$2}’ &> /tmp/example.txt 这些复杂命令,即使使用shell也可能会失败,解决办 法:写到脚本时,copy到远程,执行,再把需要的结果拉回执行命令的机器

范例:ansible常用模块shell :在远程主机执行linux命令

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
查看shell模块帮助

[root@ansible ~]# ansible-doc -s shell

在centos6上使用shell模块改用户的口令

[root@ansible ~]# ansible 192.168.131.129 -m shell -a 'echo daizhe | passwd --stdin daizhe'
192.168.131.129 | SUCCESS | rc=0 >>
Changing password for user daizhe.
passwd: all authentication tokens updated successfully.

显示所有被控制端的主机名

[root@ansible ~]# ansible all -m shell -a 'echo $HOSTNAME'
192.168.131.129 | SUCCESS | rc=0 >>
centos6.com
192.168.131.173 | SUCCESS | rc=0 >>
redhat.com
192.168.131.185 | SUCCESS | rc=0 >>
redhat7.com

将所有被控制机的/data目录下的所有文件删除 chdir(切换到指定的目录中在执行命令)

[root@ansible ~]# ansible all -m shell -a 'chdir=/data rm -rf *'
[WARNING]: Consider using file module with state=absent rather than running rm
192.168.131.129 | SUCCESS | rc=0 >>
192.168.131.173 | SUCCESS | rc=0 >>
192.168.131.185 | SUCCESS | rc=0 >>
[root@ansible ~]# ansible all -m shell -a 'chdir=/data ls'
192.168.131.129 | SUCCESS | rc=0 >>
192.168.131.173 | SUCCESS | rc=0 >>
192.168.131.185 | SUCCESS | rc=0 >>


ansible默认模块为command ,shell 模块比较好用我们可以将shell模块设置为默认模块,编辑ansible配置文件

[root@ansible ~]# vim /etc/ansible/ansible.cfg
114 module_name = shell

Script:运行脚本(将堡垒机上的脚本推送到被管理机上运行)

  • -a “/PATH/TO/SCRIPT_FILE“
  • snsible websrvs -m script -a f1.sh

范例:使用Script 脚本模块 实现将控制端的脚本在所有被控制端的主机上执行一下

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
查看帮助

[root@ansible ~]# ansible-doc -s script
- name: Runs a local script on a remote node after transferring it

脚本:将所有被控制的主机上将selinux修改为disabled

[root@ansible ~]# cat selinux.sh
#!/bin/bash
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config

[root@ansible ~]# chmod a+x selinux.sh

[root@ansible ~]# ansible all -m script -a "/root/selinux.sh"
192.168.131.173 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.131.173 closed.\r\n",
"stdout": "",
"stdout_lines": []
}
192.168.131.129 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.131.129 closed.\r\n",
"stdout": "",
"stdout_lines": []
}
192.168.131.185 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.131.185 closed.\r\n",
"stdout": "",
"stdout_lines": []
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
shell模块和script模块中都存在的模块用法
creates:如果已经存在此步骤不执行
removes:如果存在,此步骤执行

fstab文件存在,则后续命令则不执行
[root@ansible ~]# ansible all -a "creates=/etc/fstab rm -rf /data/*"
192.168.131.129 | SUCCESS | rc=0 >>
skipped, since /etc/fstab exists
192.168.131.173 | SUCCESS | rc=0 >>
skipped, since /etc/fstab exists
192.168.131.185 | SUCCESS | rc=0 >>
skipped, since /etc/fstab exists

[root@ansible ~]# ansible all -a "removes=/etc/fstab rm -rf /data/*"
[WARNING]: Consider using file module with state=absent rather than running rm
192.168.131.129 | SUCCESS | rc=0 >>
192.168.131.173 | SUCCESS | rc=0 >>
192.168.131.185 | SUCCESS | rc=0 >>

Copy:从服务器复制文件到客户端

  • ansible srv -m copy -a “src=/root/f1.sh dest=/tmp/f2.sh owner=wang mode=600 backup=yes”
    • 如目标存在,默认覆盖,此处指定先备份
  • ansible srv -m copy -a “content=‘test content\n’ dest=/tmp/f1.txt”
    • 利用内容,直接生成目标文件
1
2
3
4
5
6
7
8
9
[root@ansible ~]# ansible-doc -s copy
dest: 到目标文件
src: 本地源文件
源时文件夹,目标也是文件夹
mode: 设置权限
group: 修改所属组
backup: 如果目标主机存在了此文件,则先进行备份再覆盖
content: 可以代替src,本身含义为内容,src文件,content: 文件内容
owner: 修改所有者

范例:copy模块

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
40
41
42
43
44
45
46
47
48
49
50
将控制机上的fstab文件保留原名,发送到所有被控制端的主机上,并修改文件的所有者,并设置权限

[root@ansible ~]# ansible all -m copy -a "src=/etc/fstab dest=/root/ owner=daizhe mode=600"

确认是否成功

[root@ansible ~]# ansible all -m shell -a 'ls -l /root/fstab'
192.168.131.129 | SUCCESS | rc=0 >>
-rw-------. 1 daizhe root 595 Nov 22 07:38 /root/fstab
...

root@centos6 ~]# ll /root/fstab
-rw-------. 1 daizhe root 595 Nov 22 07:38 /root/fstab
....

将控制机上的fstab文件保留原名,发送到所有被控制端的主机上,并修改文件的所有者,并设置权限,如果对方有此文件,则先备份再进行修改

[root@ansible ~]# ansible all -m copy -a "src=/etc/fstab dest=/root/ owner=daizhe mode=600 backup=yes"

拷贝主机上的文件夹到所有的控制端

[root@ansible ~]# ansible all -m copy -a "src=/data dest=/root/"

使用copy模块中的content 生成所有被控制端的yum配置文件

[root@ansible ~]# ansible 192.168.131.173 -m copy -a 'content="[haha]\nbaseurl=https://mirrors.aliyun.com/epel/7/x86_64/\ngpgcheck=0\nenabled=1" dest=/etc/yum.repos.d/haha.repo'
192.168.131.173 | SUCCESS => {
"changed": true,
"checksum": "0d7ffdd1ba1b53d2b4f3540fc8e77a1ba40b4232",
"dest": "/etc/yum.repos.d/haha.repo",
"gid": 0,
"group": "root",
"md5sum": "e74dc0b9c50a24d884dc8e8d5d71438b",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:system_conf_t:s0",
"size": 77,
"src": "/root/.ansible/tmp/ansible-tmp-1542855358.21-118898081082202/source",
"state": "file",
"uid": 0
}

确认是否生成

[root@ansible ~]# ansible 192.168.131.173 -a 'cat /etc/yum.repos.d/haha.repo'
192.168.131.173 | SUCCESS | rc=0 >>
[haha]
baseurl=https://mirrors.aliyun.com/epel/7/x86_64/
gpgcheck=0
enabled=1

Fetch:从客户端取文件至服务器端,copy相反,目前fetch仅可以抓取文件,目录可先tar

  • ansible srv -m fetch -a ‘src=/root/a.sh dest=/data/scripts’

范例:fetch模块

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
40
41
42
43
44
45
46
47
从被控的主机上抓取主机名文件到本地

[root@ansible ~]# ansible all -m fetch -a 'src=/etc/hosts dest=/data/'
192.168.131.129 | SUCCESS => {
"changed": true,
"checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa",
"dest": "/data/192.168.131.129/etc/hosts",
"md5sum": "54fb6627dbaa37721048e4549db3224d",
"remote_checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa",
"remote_md5sum": null
}
192.168.131.173 | SUCCESS => {
"changed": true,
"checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa",
"dest": "/data/192.168.131.173/etc/hosts",
"md5sum": "54fb6627dbaa37721048e4549db3224d",
"remote_checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa",
"remote_md5sum": null
}
192.168.131.185 | SUCCESS => {
"changed": true,
"checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa",
"dest": "/data/192.168.131.185/etc/hosts",
"md5sum": "54fb6627dbaa37721048e4549db3224d",
"remote_checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa",
"remote_md5sum": null
}
[root@ansible ~]# cd /data
[root@ansible data]# ls
192.168.131.129 192.168.131.173 192.168.131.185

fetch 模板不支持抓取目录
想要实现将被控制端的/data目录抓取到本机
打包

[root@ansible ~]# ansible all -m shell -a 'tar cf /root/data.tar /data'
[WARNING]: Consider using unarchive module rather than running tar
192.168.131.129 | SUCCESS | rc=0 >>
tar: Removing leading `/' from member names
192.168.131.173 | SUCCESS | rc=0 >>
tar: Removing leading `/' from member names
192.168.131.185 | SUCCESS | rc=0 >>
tar: Removing leading `/' from member names

抓取

[root@ansible ~]# ansible all -m fetch -a 'src=/root/data.tar dest=/root'

File:设置文件属性 管路目标主机的文件

  • ansible srv -m file -a “path=/root/a.sh owner=wang mode=755“
  • ansible web -m file -a ‘src=/app/testfile dest=/app/testfile-link state=link’

范例:file模块

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
40
41
42
43
44
45
46
47
48
49
50
51
path:指定创建文件的路径
state:指定对文件进行的操作
touch:对文件进行创建操作
absent:删除操作
link:创建连接文件、软连接
hard:创建硬链接
dest=path=name 意义相同,目标创建的文件
再所有被管理的终端上的/data目录上创建文件

[root@ansible ~]# ansible all -m file -a 'path=/data/file state=touch'

删除上面创建的文件

[root@ansible ~]# ansible all -m file -a 'path=/data/file state=absent'

再被管理终端上创建连接文件

[root@ansible ~]# ansible all -a 'ls /data'
192.168.131.129 | SUCCESS | rc=0 >>
fstab
192.168.131.173 | SUCCESS | rc=0 >>
fstab
192.168.131.185 | SUCCESS | rc=0 >>
fstab

对所有终端上的/data/fstab文件创建连接(软连接)

[root@ansible ~]# ansible all -m file -a 'src=/data/fstab path=/data/fstab.link state=link'
[root@ansible ~]# ansible all -a 'ls -l /data'
192.168.131.129 | SUCCESS | rc=0 >>
total 4
-rw-r--r--. 1 root root 595 Nov 22 08:02 fstab
lrwxrwxrwx. 1 root root 11 Nov 22 08:20 fstab.link -> /data/fstab
....

[root@ansible ~]# ansible all -a 'ls -l /data'
192.168.131.129 | SUCCESS | rc=0 >>
total 8
-rw-r--r--. 2 root root 595 Nov 22 08:02 fstab
-rw-r--r--. 2 root root 595 Nov 22 08:02 fstab2.link

在被控制端创建文件夹路径为/data/datadir

[root@ansible ~]# ansible all -m file -a 'dest=/data/datadir state=directory'
[root@ansible ~]# ansible all -a 'ls -l /data/'
192.168.131.129 | SUCCESS | rc=0 >>
drwxr-xr-x. 2 root root 4096 Nov 22 08:26 datadir

删除被控制的目录/文件

[root@ansible ~]# ansible all -m file -a 'dest=/data/datadir state=absent'

Hostname:管理主机名

  • ansible node1 -m hostname -a “name=websrv”

范例:Hostname模块

1
2
3
4
5
6
7
8
9
10
修改单独被控制端的主机名

[root@ansible ~]# ansible 192.168.131.173 -m hostname -a 'name=redhat6'

查看 立即生效
hosts文件未进行更改

[root@ansible ~]# ansible 192.168.131.173 -a 'hostname'
192.168.131.173 | SUCCESS | rc=0 >>
redhat6

Cron:计划任务

  • 支持时间:minute,hour,day,month,weekday
  • ansible srv -m cron -a “minute=*/5 job=‘/usr/sbin/ntpdate 172.16.0.1 &>/dev/null’ name=Synctime” 创建任务
  • ansible srv -m cron -a ‘state=absent name=Synctime’ 删除任务

范例:Cron模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
设定计划任务,周六日,每五分钟执行一次,执行同步时间操作

[root@ansible ~]# ansible 192.168.131.173 -m cron -a 'minute=*/5 weekday=0,6 job="/usr/sbin/ntpdate 172.18.0.1 &> /dev/null" name=tongbu'

[root@redhat ~]# crontab -l
#Ansible: tongbu
*/5 * * * 0,6 /usr/sbin/ntpdate 172.18.0.1 &> /dev/null

禁用被控制端的计划任务

[root@ansible ~]# ansible 192.168.131.173 -m cron -a 'minute=*/5 weekday=0,6 job="/usr/sbin/ntpdate 172.18.0.1 &> /dev/null" name=tongbu disbaled=ture'

再次启用

[root@ansible ~]# ansible 192.168.131.173 -m cron -a 'minute=*/5 weekday=0,6 job="/usr/sbin/ntpdate 172.18.0.1 &> /dev/null" name=tongbu disbaled=false'

彻底铲除此计划任务

[root@ansible ~]# ansible 192.168.131.173 -m cron -a 'name=tongbu state=sbsent'

Yum:管理包

  • ansible srv -m yum -a ‘name=httpd state=latest’ 安装
  • ansible srv -m yum -a ‘name=httpd state=absent’ 删除

范例:Yum模块,前提被控制机上 yum 是已经配置好的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
name=  指定包的名称

使用yum模板在被管理终端上安装htop包

[root@ansible ~]# ansible 192.168.131.173 -m yum -a 'name=htop'

一次安装多个包,前提是,在原来本机上未安装

[root@ansible ~]# ansible all -a 'rpm -q http,vsftpd,memcached'
[root@ansible ~]# ansible all -m yum -a 'name=httpd,vsftpd,memcached'

卸载被管理机上的应用程序

[root@ansible ~]# ansible all -m yum -a 'name=httpd state=absent'

更新被管理机yum缓存,同时安装 httpd包

[root@ansible ~]# ansible all -m yum -a 'name=httpd update_cache=yes'

Service:管理服务

  • 停止服务
    • ansible srv -m service -a ‘name=httpd state=stopped’
  • 启动服务
    • ansible srv -m service -a ‘name=httpd state=started’
  • 加入启动项/关闭启动项
    • ansible srv -m service -a ‘name=httpd state=startes enabled=yes’
    • ansible srv –m service –a ‘name=httpd state=reloaded’
  • 重新启动
    • ansible srv -m service -a ‘name=httpd state=restarted’

范例:service模块

1
2
3
4
5
6
7
8
9
10
11
启动被管理端的http服务
[root@ansible ~]# ansible 192.168.131.173 -m service -a 'name=httpd state=started'

关闭服务
[root@ansible ~]# ansible 192.168.131.173 -m service -a 'name=httpd state=stopped

设置为开机启动
[root@ansible ~]# ansible 192.168.131.173 -m service -a 'name=httpd state=started enabled=yes'

systemctl is-enabled httpd
chkconfig --list httpd

User:管理用户

  • ansible srv -m user -a ‘name=user1 comment=“test user” uid=2048 home=/app/user1 group=root‘
  • ansible srv -m user -a ‘name=sysuser1 system=yes home=/app/sysuser1 ’
  • ansible srv -m user -a ‘name=user1 state=absent remove=yes‘ 删除用户 及家目录等数据

范例:user模块

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
name= 指定用户名
comment= 描述信息
uid= 设定uid
home= 设定家目录
group= 制定主组
groups= 设定附加组
shell=指定shell类型
remove=yes 删除家目录文件
system=yes 设置系统用户、系统组



在被管理终端上创建用户,并指定属性

[root@ansible ~]# ansible all -m user -a 'name=haha comment="test user" uid=2000 home=/data/ group=root groups=bin shell=/sbin/nologin'

确定用户是否创建

[root@ansible ~]# ansible all -a 'getent passwd haha'
192.168.131.129 | SUCCESS | rc=0 >>
haha:x:2000:0:test user:/data/:/sbin/nologin
.....

删除被管理终端的用户haha,删除家目录,但是不删除家目录的文件

[root@ansible ~]# ansible all -m user -a 'name=haha state=absent'
192.168.131.173 | SUCCESS => {
"changed": true,
"force": false,
"name": "haha",
"remove": false,
"state": "absent"
}
.....

实现删除用户,也将用户的家目录和相关文件删除

[root@ansible ~]# ansible all -m user -a 'name=hahahaha state=absent remove=yes'

Group:管理组

  • ansible srv -m group -a “name=testgroup system=yes“
  • ansible srv -m group -a “name=testgroup state=absent”

ansible-galaxy

  • 连接 https://galaxy.ansible.com 下载相应的roles
  • 列出所有已安装的galaxy

    • ansible-galaxy list
  • 安装galaxy

    • ansible-galaxy install geerlingguy.redis
  • 删除galaxy
    • ansible-galaxy remove geerlingguy.redis

ansible-pull

  • 推送命令至远程,效率无限提升,对运维要求较高

Ansible-playbook

  • 范例:
  • 执行
    • ansible-playbook hello.yml
  • yml文件脚本内容
    cat hello.yml

Ansible-vault

功能:管理加密解密yml文件

  ansible-vault [create|decrypt|edit|encrypt|rekey|view]

  ansible-vault encrypt hello.yml 加密

  ansible-vault decrypt hello.yml 解密

  ansible-vault view hello.yml 查看加密文件内容

  ansible-vault edit hello.yml 编辑加密文件

  ansible-vault rekey hello.yml 修改口令

  ansible-vault create new.yml 创建新文件

Ansible-console:2.0+新增,可交互执行命令,支持tab

  root@test (2)[f:10] $

执行用户@当前操作的主机组 (当前组的主机数量)[f:并发数]$

  设置并发数: forks n 例如: forks 10

  切换组: cd 主机组 例如: cd web

  列出当前组主机列表: list

  列出所有的内置命令: ?或help

  示例:

    root@all (2)[f:5]$ list

    root@all (2)[f:5]$ cd appsrvs

    root@appsrvs (2)[f:5]$ list

    root@appsrvs (2)[f:5]$ yum name=httpd state=present

    root@appsrvs (2)[f:5]$ service name=httpd state=started

-------------------码字不易尊重原创转载标注不胜感激-------------------
Yes or no?
0%