本人playbook例子
https://github.com/aawuliliaa/ansible/tree/master/playbook
1.1批量管理服务知识介绍
a. ansible是一个基于Python开发的自动化运维工具
b. ansible是一个基于ssh协议实现远程管理的工具
c. ansible软件可以实现多种批量管理操作(批量系统配置、批量软件部署、批量文件拷贝、批量运行命令)
1.2批量管理服务特征介绍
a ansible软件服务端(管理端):不需要启动任何服务 默认服务端不需要任何的配置
b ansible软件客户端(受控端):没有客户端软件安装
1.3ansible软件安装部署
1.3.1 ansible软件自动化环境架构规划
管理主机1台:
10.0.0.61 m01
受控主机3台:
10.0.0.41 backup
10.0.0.31 nfs01
10.0.0.7 web01
Linux系统 6.9
1.3.2ansible软件自动化部署条件
1.ssh密钥对创建(管理主机)
ssh-keygen -t dsa
影响免交互创建密钥对创建因素:
1)需要指定私钥存放路径
-f /root/.ssh/id_dsa
2)需要进行私钥文件密码设定
-N/-P
-N ""/-P ""
2.免交互创建密钥对方法
ssh-keygen -t dsa -f /root/.ssh/id_dsa -N ""
3.分发公钥文件(管理主机进行分发)
ssh-copy-id -i /root/.ssh/id_dsa.pub 172.16.1.31
影响免交互批量分发密钥因素
1)需要有确认连接过程,需要输入yes/no
man ssh查找到下面的-o选项
-o StrictHostKeyChecking=no
sshpass -p123456 ssh-copy-id -i /root/.ssh/id_dsa.pub "-o StrictHostKeyChecking=no 172.16.1.31"
2)需要解决密码问题
sshpass -p123456 ssh-copy-id -i /root/.ssh/id_dsa.pub 172.16.1.31
Now try logging into the machine, with "ssh '172.16.1.31'", and check in:
.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.
3.免交互批量分发公钥脚本
#!/bin/bash
rm /root/.ssh/id_dsa
ssh-keygen -t dsa -f /root/.ssh/id_dsa -N ""
for ip in 31 41 7
do
sshpass -p123456 ssh-copy-id -i /root/.ssh/id_dsa.pub "-o StrictHostKeyChecking=no 172.16.1.$ip"
done
4.检查是否可以进行基于密钥远程管理
ssh 172.16.1.31 uptime
免交互批量检查测试脚本
#!/bin/bash
#description:back file to the directory of /backup
#author:vita
#time:2019-03-04
[ $# -ne 1 ]&&echo "you should use this script like sh fenfa_check.sh pwd"&&exit
for ip in 31 41 7
do
echo "start to excute 172.16.1.$ip"
ssh 172.16.1.$ip $1
echo "172.16.1.$ip end"
done
5.服务器端口默认不是22怎样执行ssh-copy-id
[root@m01 scripts]# which ssh-copy-id
/usr/bin/ssh-copy-id
[root@m01 scripts]# vim /usr/bin/ssh-copy-id
{ eval "$GET_ID" ; } | ssh $1 "exec sh -c 'cd; umask 077; test -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys && (test -x /sbin/restorecon && /sbin/restorecon .ssh .ssh/authorized_keys >/dev/null 2>&1 || true)'" || exit 1
方法一:
{ eval "$GET_ID" ; } | ssh -p52113 $1 "exec sh -c 'cd; umask 077; test -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys && (test -x /sbin/restorecon && /sbin/restorecon .ssh .ssh/authorized_keys >/dev/null 2>&1 || true)'" || exit 1
1.临时设置umask值
2.利用脚本创建.ssh目录 test -d ~/.ssh||mkdir ~/.ssh
3.将本地公钥文件中的信息重定向到远程主机的.ssh/authorized_keys文件中,并授权为600
说明:通过对ssh-copy-id命令文件信息改写,是可以实现被管理主机不同端口号情况,顺利分发公钥信息
上面方法不是最好,如果别人不了解这个知识,修改了端口后又要重新处理。
方法二:
最好的方法
ssh-copy-id -i /root/.ssh/id_sda.pub "172.16.1.31 -p52113"
详细解析如下:
shift要在脚本中应用时,会将传参的参数依次向前推进
#!/bin/bash
#description:back file to the directory of /backup
#author:vita
#time:2019-03-04
until [ $# -eq 0 ]
do
echo $*
shift
done
[root@m01 scripts]# sh shift.sh 1 2 3 4 5
1 2 3 4 5
2 3 4 5
3 4 5
4 5
5
由于/usr/bin/ssh-copy-id脚本中上面用了两个shift,
if [ "-i" = "$1" ]; then
shift
# check if we have 2 parameters left, if so the first is the new ID file
if [ -n "$2" ]; then
if expr "$1" : ".*\.pub" > /dev/null ; then
ID_FILE="$1"
else
ID_FILE="$1.pub"
fi
shift # and this should leave $1 as the target name
fi
所以
ssh-copy-id -i /root/.ssh/id_sda.pub "172.16.1.31 -p52113"中 "172.16.1.31 -p52113"就变成了$1,
所以{ eval "$GET_ID" ; } | ssh $1 "exec sh -c 'cd; umask 077; test -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys && (test -x /sbin/restorecon && /sbin/restorecon .ssh .ssh/authorized_keys >/dev/null 2>&1 || true)'" || exit 1这里的-p52113就给了这里的ssh命令
这也是上面脚本sshpass -p123456 ssh-copy-id -i /root/.ssh/id_dsa.pub "-o StrictHostKeyChecking=no 172.16.1.31"这样书写的原因
1.3.3ansible软件下载安装
ansible管理主机软件安装:
yum install -y ansible
ansible受控主机软件安装:(可选)
yum install -y libselinux-python
1.3.4ansible软件hosts配置文件
#这种是已经配置了互相的免密登录方式
cat /etc/ansible/hosts
[oldboy]
172.16.1.7
172.16.1.31
172.16.1.41
vim /etc/ansible/hosts
[oldboy]
172.16.1.7
172.16.1.31 ansible_user=root ansible_password=123456
#1.ssh用户+ssh秘码
#10.0.0.62 ansible_ssh_user=root ansible_ssh_pass=123456
#2.ssh用户+ssh秘钥,我配置了怎么都不好使呢。。。。。。。
#10.0.0.62 ansible_ssh_user=root ansible_ssh_private_key_file=/root/.ssh/id_dsa
#/root/.ssh/id_dsa我配置的是ansible服务端root用户的私钥地址
#3.别名+ssh用户+ssh秘钥
m02 ansible_ssh_host=10.0.0.62 ansible_ssh_user=root ansible_ssh_private_key_file=/root/.ssh/id_dsa
[root@m01 playbook]# ansible all --list-hosts
hosts (3):
10.0.0.61
10.0.0.62
172.16.1.61
ansible 172.16.1.31 -m command -a "hostname" -k --- 实现口令交互式远程管理
SSH password:
172.16.1.31 | SUCCESS | rc=0 >>
nfs01
#group组包含php和nginx
/etc/ansible/hosts
10.0.0.61
[db]
172.16.1.61
[php]
172.16.1.61
[nginx]
10.0.0.62 ansible_ssh_user=root ansible_ssh_pass=123456
[group:children]
php
nginx
# -f是5个并发,-l是只展示该主机的信息
[root@m01 playbook]# ansible group -m shell -a "ls -l /opt" -f 5 -l 10.0.0.62
10.0.0.62 | SUCCESS | rc=0 >>
total 8
-rw-r--r-- 1 root root 498 Aug 1 18:51 hosts
drwxr-xr-x 4 root root 33 Apr 3 10:46 script
drwxr-xr-x 2 root root 6 Aug 1 18:44 sd
-rw-r--r-- 1 root root 168 Aug 1 18:40 sum.sh
1.4ansible软件模块详解
ansible软件模块
ansible-doc -l|wc -l
1378
ansible 管理主机信息或者主机组信息 -m 模块名称 -a 相关模块参数
主机信息:远程主机IP地址 远程主机组名称 远程所有主机all
-m 指定相应模块
-a 利用模块中某些参数功能
1.4.1第一个模块:command
官方参考链接:http://docs.ansible.com/ansible/latest/modules/command_module.html
参数:chdir---在执行莫个命令前,先切换目录
[root@m01 ansible]# ansible 172.16.1.31 -m command -a "chdir=/tmp/ pwd"
172.16.1.31 | SUCCESS | rc=0 >>
/tmp
[root@m01 ansible]# ansible 172.16.1.31 -m command -a "chdir=/etc/ pwd"
172.16.1.31 | SUCCESS | rc=0 >>
/etc
参数:creates---判断一个文件是否存在,如果已经存在了,后面的命令就不会执行
[root@m01 ansible]# ansible 172.16.1.41 -m command -a "creates=/etc/rsyncd.conf hostname"
172.16.1.41 | SUCCESS | rc=0 >>
skipped, since /etc/rsyncd.conf exists
[root@m01 ansible]# ansible 172.16.1.41 -m command -a "creates=/etc/rsyncd.conf.bak hostname"
172.16.1.41 | SUCCESS | rc=0 >>
skipped, since /etc/rsyncd.conf.bak exists
[root@m01 ansible]# ansible 172.16.1.41 -m command -a "creates=/etc/rsyncd.123456 hostname"
172.16.1.41 | SUCCESS | rc=0 >>
backup
参数:removes---判断一个文件是否存在,如果不存在,后面的命令就不会执行
[root@m01 ansible]# ansible 172.16.1.41 -m command -a "removes=/etc/rsyncd.conf hostname"
172.16.1.41 | SUCCESS | rc=0 >>
backup
[root@m01 ansible]# ansible 172.16.1.41 -m command -a "removes=/etc/rsyncd.1212213123 hostname"
172.16.1.41 | SUCCESS | rc=0 >>
skipped, since /etc/rsyncd.1212213123 does not exist
参数(必须要有的):free_form---表示执行command模块时,必须要有linux合法命令信息
ansible 172.16.1.41 -m command -a "ls"
172.16.1.41 | SUCCESS | rc=0 >>
1
anaconda-ks.cfg
dead.letter
heqing
1.4.2第二个模块:shell模块(万能模块)
参数:chdir---在执行莫个命令前,先切换目录
参数:creates---判断一个文件是否存在,如果已经存在了,后面的命令就不会执行
参数:removes---判断一个文件是否存在,如果不存在,后面的命令就不会执行
参数(必须要有的):free_form---表示执行command模块时,必须要有linux合法命令信息
[root@m01 ansible]# ansible 172.16.1.41 -m shell -a "ls;pwd"
172.16.1.41 | SUCCESS | rc=0 >>
1
anaconda-ks.cfg
dead.letter
/root
说明:shell模块可以满足command模块所有功能,并且可以支持识别特殊字符信息 < > | ;
[root@m01 ~]# ansible oldboy -m shell -a "cd /oldboy;ls -l"
172.16.1.41 | SUCCESS | rc=0 >>
total 4
drwxr-xr-x 2 root root 4096 Mar 11 17:58 sftp
172.16.1.31 | SUCCESS | rc=0 >>
total 12
-rw-r--r-- 1 root root 285 Mar 11 17:59 back.sh
-rw-r--r-- 1 root root 0 Mar 12 09:14 sftp
-rw-r--r-- 1 oldboy oldboy 20 Mar 11 17:39 test.log
drwxr-xr-x 3 root root 4096 Mar 7 17:11 tmp
1.4.3第三个模块:script---在远程服务器上运行ansible服务端的脚本,远端不需要有该脚本
参数:chdir---在执行莫个命令前,先切换目录
参数:creates---判断一个文件是否存在,如果已经存在了,后面的命令就不会执行
参数:removes---判断一个文件是否存在,如果不存在,后面的命令就不会执行
参数(必须要有的):free_form---表示执行command模块时,必须要有linux合法命令信息
script模块与shell模块执行脚本的区别:
script模块只需要在管理主机本地有一个脚本,脚本中的命令就会在远程主机中执行
shell模块执行脚本,需要每个远程主机都有相同的脚本,否则无法执行
shell模块
[root@m01 ~]# ansible oldboy -m shell -a "cd /server/scripts;mv sum.sh sum.sh.bak"
172.16.1.31 | SUCCESS | rc=0 >>
172.16.1.41 | SUCCESS | rc=0 >>
[root@m01 ~]# ansible oldboy -m shell -a "cd /server/scripts;ls -l"
172.16.1.31 | SUCCESS | rc=0 >>
total 40
-rw-r--r-- 1 root root 168 Mar 21 2019 sum.sh.bak
drwxr-xr-x 3 root root 4096 Mar 20 2019 var
172.16.1.41 | SUCCESS | rc=0 >>
total 36
-rw-r--r-- 1 root root 168 Mar 21 2019 sum.sh.bak
drwxr-xr-x 3 root root 4096 Mar 20 2019 var
[root@m01 ~]# ansible oldboy -m shell -a "cd /server/scripts;sh sum.sh"
172.16.1.41 | FAILED | rc=127 >>
sh: sum.sh: No such file or directorynon-zero return code
172.16.1.31 | FAILED | rc=127 >>
sh: sum.sh: No such file or directorynon-zero return code
script模块
[root@m01 ~]# ansible oldboy -m script -a "/server/scripts/sum.sh"
172.16.1.31 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 172.16.1.31 closed.\r\n",
"stderr_lines": [
"Shared connection to 172.16.1.31 closed."
],
"stdout": "5050\r\n",
"stdout_lines": [
"5050"
]
}
172.16.1.41 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 172.16.1.41 closed.\r\n",
"stderr_lines": [
"Shared connection to 172.16.1.41 closed."
],
"stdout": "5050\r\n",
"stdout_lines": [
"5050"
]
}
[root@m01 ~]# ll /server/scripts/sum.sh
-rw-r--r-- 1 root root 168 Mar 21 2019 /server/scripts/sum.sh
1.4.4copy----复制模块
参数:src---定义要推送数据信息
参数:dest---定义将数据推送到远程主机什么目录中
[root@m01 ansible]# touch /tmp/file01.txt
[root@m01 ansible]# ansible 172.16.1.41 -m copy -a "src=/tmp/file01.txt dest=/tmp/"
172.16.1.41 | SUCCESS => {
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/tmp/file01.txt",
"gid": 0,
"group": "root",
"md5sum": "d41d8cd98f00b204e9800998ecf8427e",
"mode": "0644",
"owner": "root",
"size": 0,
"src": "/root/.ansible/tmp/ansible-tmp-1522682948.27-60532389065095/source",
"state": "file",
"uid": 0
}
参数:backup---对数据信息进行备份
[root@m01 ansible]# ansible 172.16.1.41 -m copy -a "src=/tmp/file01.txt dest=/tmp/ backup=yes"
172.16.1.41 | SUCCESS => {
"backup_file": "/tmp/file01.txt.71887.2018-04-02@23:33:19~",
"changed": true,
"checksum": "029b054db136cc36d5605e3818305825ff4b8ffb",
"dest": "/tmp/file01.txt",
"gid": 0,
"group": "root",
"md5sum": "434660b5ad7deeba8815349f71409405",
"mode": "0644",
"owner": "root",
"size": 6,
"src": "/root/.ansible/tmp/ansible-tmp-1522683197.05-52744169892601/source",
"state": "file",
"uid": 0
}
[root@m01 ansible]# ansible 172.16.1.41 -m shell -a "ls -l /tmp/"
172.16.1.41 | SUCCESS | rc=0 >>
total 24
-rw-r--r-- 1 root root 0 Apr 2 23:29 file01.txt
-rw-r--r-- 1 root root 0 Apr 2 23:29 /tmp/file01.txt.71887.2018-04-02@23:33:19~
参数:owner---设置复制后的文件属主权限
参数:group---设置复制后的文件属组权限
参数:mode---设置复制后的文件权限(600 755)
1.4.5file----文件属性修改/目录创建/文件创建
参数:owner---设置复制后的文件属主权限
参数:group---设置复制后的文件属组权限
参数:mode---设置复制后的文件权限(600 755)
ansible 172.16.1.41 -m file -a "dest=/tmp/file01.txt owner=oldboy group=oldboy mode=600"
172.16.1.41 | SUCCESS => {
"changed": true,
"gid": 500,
"group": "oldboy",
"mode": "0600",
"owner": "oldboy",
"path": "/tmp/file01.txt",
"size": 6,
"state": "file",
"uid": 500
}
参数:state---用于指定创建目录或文件
创建文件
ansible 172.16.1.41 -m file -a "dest=/tmp/file01.txt state=touch"
172.16.1.41 | SUCCESS => {
"changed": true,
"dest": "/tmp/file01.txt",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"size": 0,
"state": "file",
"uid": 0
}
创建目录:
ansible 172.16.1.41 -m file -a "dest=/tmp/dir01 state=directory"
172.16.1.41 | SUCCESS => {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/tmp/dir01",
"size": 4096,
"state": "directory",
"uid": 0
}
1.4.6包管理模块yum---安装软件包模块
name:执行要安装软件的名称,以及软件的版本
state:installed安装 absent(卸载)
ansible 172.16.1.41 -m yum -a "name=iftop state=installed"
ansible 172.16.1.41 -m yum -a "name=iftop state=absent"
list:指定软件名称,查看软件是否可以安装,以及是否已经安装过了
ansible 172.16.1.41 -m yum -a "list=iftop"
[root@m01 ~]# ansible 172.16.1.41 -m yum -a "name=iftop state=installed"
172.16.1.41 | SUCCESS => {
"changed": false,
"msg": "",
"rc": 0,
"results": [
"iftop-1.0-0.14.pre4.el6.x86_64 providing iftop is already installed"
]
}
[root@m01 ~]# ansible 172.16.1.41 -m yum -a "name=iftop state=absent"
172.16.1.41 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Loaded plugins: fastestmirror, security\nSetting up Remove Process\nResolving Dependencies\n--> Running transaction check\n---> Package iftop.x86_64 0:1.0-0.14.pre4.el6 will be erased\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nRemoving:\n iftop x86_64 1.0-0.14.pre4.el6 @epel 89 k\n\nTransaction Summary\n================================================================================\nRemove 1 Package(s)\n\nInstalled size: 89 k\nDownloading Packages:\nRunning rpm_check_debug\nRunning Transaction Test\nTransaction Test Succeeded\nRunning Transaction\n\r Erasing : iftop-1.0-0.14.pre4.el6.x86_64 1/1 \n\r Verifying : iftop-1.0-0.14.pre4.el6.x86_64 1/1 \n\nRemoved:\n iftop.x86_64 0:1.0-0.14.pre4.el6 \n\nComplete!\n"
]
}
[root@m01 ~]# ansible 172.16.1.41 -m yum -a "name=iftop state=installed"
172.16.1.41 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Loaded plugins: fastestmirror, security\nSetting up Install Process\nLoading mirror speeds from cached hostfile\n * base: mirrors.aliyun.com\n * extras: mirrors.aliyun.com\n * updates: mirrors.aliyun.com\nResolving Dependencies\n--> Running transaction check\n---> Package iftop.x86_64 0:1.0-0.14.pre4.el6 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n iftop x86_64 1.0-0.14.pre4.el6 epel 49 k\n\nTransaction Summary\n================================================================================\nInstall 1 Package(s)\n\nTotal download size: 49 k\nInstalled size: 89 k\nDownloading Packages:\nRunning rpm_check_debug\nRunning Transaction Test\nTransaction Test Succeeded\nRunning Transaction\n\r Installing : iftop-1.0-0.14.pre4.el6.x86_64 1/1 \n\r Verifying : iftop-1.0-0.14.pre4.el6.x86_64 1/1 \n\nInstalled:\n iftop.x86_64 0:1.0-0.14.pre4.el6 \n\nComplete!\n"
]
}
[root@m01 ~]# ansible 172.16.1.41 -m yum -a "list=iftop"
172.16.1.41 | SUCCESS => {
"changed": false,
"results": [
{
"arch": "x86_64",
"envra": "0:iftop-1.0-0.14.pre4.el6.x86_64",
"epoch": "0",
"name": "iftop",
"release": "0.14.pre4.el6",
"repo": "epel",
"version": "1.0",
"yumstate": "available"
},
{
"arch": "x86_64",
"envra": "0:iftop-1.0-0.14.pre4.el6.x86_64",
"epoch": "0",
"name": "iftop",
"release": "0.14.pre4.el6",
"repo": "installed",
"version": "1.0",
"yumstate": "installed"
}
]
}
[root@m01 ~]# ansible 172.16.1.41 -m yum -a "list=ift"
172.16.1.41 | SUCCESS => {
"changed": false,
"results": []
}
[root@m01 ~]#
1.4.7系统模块service---管理服务状态模块
name: 指定要管理的服务名称(管理的服务一定在chkconfig中可以看到)
state:stopped started restarted reloaded
enabled:yes表示服务开机自启动 no表示服务开机不要自动启动
ansible 172.16.1.41 -m service -a "name=crond state=started enabled=yes"
[root@m01 ~]# ansible 172.16.1.41 -m service -a "name=crond state=stopped enabled=no"
172.16.1.41 | SUCCESS => {
"changed": true,
"enabled": false,
"name": "crond",
"state": "stopped"
}
[root@m01 ~]# ansible 172.16.1.41 -m shell -a "chkconfig --list|grep crond"
172.16.1.41 | SUCCESS | rc=0 >>
crond 0:off 1:off 2:off 3:off 4:off 5:off 6:off
[root@m01 ~]# ansible 172.16.1.41 -m shell -a "service crond status"
172.16.1.41 | FAILED | rc=3 >>
crond is stoppednon-zero return code
[root@m01 ~]# ansible 172.16.1.41 -m service -a "name=crond state=started enabled=yes"
172.16.1.41 | SUCCESS => {
"changed": true,
"enabled": true,
"name": "crond",
"state": "started"
}
[root@m01 ~]# ansible 172.16.1.41 -m shell -a "service crond status"
172.16.1.41 | SUCCESS | rc=0 >>
crond (pid 8420) is running...
[root@m01 ~]# ansible 172.16.1.41 -m shell -a "chkconfig --list|grep crond"
172.16.1.41 | SUCCESS | rc=0 >>
crond 0:off 1:off 2:on 3:on 4:on 5:on 6:off
[root@m01 ~]#
1.4.8cron---定时任务模块
minute=0-59 * */n , - hour day month weekday job='/bin/sh /server/scripts/test.sh &>/dev/null'
添加定时任务
ansible 172.16.1.41 -m cron -a "minute=0 hour=0 job='/bin/sh /server/scripts/test.sh &>/dev/null'"
ansible 172.16.1.41 -m cron -a "name=oldboy02 minute=0 hour=0 job='/bin/sh /server/scripts/test.sh &>/dev/null'"
删除定时任务
ansible 172.16.1.41 -m cron -a "name=oldboy02 minute=0 hour=0 job='/bin/sh /server/scripts/test.sh &>/dev/null' state=absent"
ansible 172.16.1.41 -m cron -a "name=oldboy01 state=absent"
注释定时任务
ansible 172.16.1.41 -m cron -a "name=oldboy01 minute=0 hour=0 job='/bin/sh /server/scripts/test.sh &>/dev/null' disabled=yes"
ansible 172.16.1.41 -m cron -a "name=oldboy01 job='/bin/sh /server/scripts/test.sh &>/dev/null' disabled=no"
[root@m01 ~]# ansible 172.16.1.41 -m cron -a "name=oldboy01 minute=*/1 hour=* day=* month=* weekday=* job='/bin/sh /server/scripts/sum.sh >dev/null 2>&1'"
172.16.1.41 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"oldboy01"
]
}
[root@m01 ~]# ansible 172.16.1.41 -m shell -a "crontab -l"
172.16.1.41 | SUCCESS | rc=0 >>
#Ansible: oldboy01
*/1 * * * * /bin/sh /server/scripts/sum.sh >dev/null 2>&1
[root@m01 ~]# ansible 172.16.1.41 -m cron -a "name=oldboy01 state=absent"
172.16.1.41 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": []
}
[root@m01 ~]# ansible 172.16.1.41 -m shell -a "crontab -l"
172.16.1.41 | SUCCESS | rc=0 >>
[root@m01 ~]# ansible 172.16.1.41 -m cron -a "name=oldboy01 minute=*/1 hour=* day=* month=* weekday=* job='/bin/sh /server/scripts/sum.sh >dev/null 2>&1'"
172.16.1.41 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"oldboy01"
]
}
[root@m01 ~]# ansible 172.16.1.41 -m shell -a "crontab -l"
172.16.1.41 | SUCCESS | rc=0 >>
#Ansible: oldboy01
*/1 * * * * /bin/sh /server/scripts/sum.sh >dev/null 2>&1
[root@m01 ~]# ansible 172.16.1.41 -m cron -a "name=oldboy01 disabled=yes"
172.16.1.41 | FAILED! => {
"changed": false,
"msg": "You must specify 'job' to install a new cron job or variable"
}
[root@m01 ~]# ansible 172.16.1.41 -m cron -a "name=oldboy01 minute=*/1 hour=* day=* month=* weekday=* job='/bin/sh /server/scripts/sum.sh >dev/null 2>&1' disabled=yes"
172.16.1.41 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"oldboy01"
]
}
[root@m01 ~]# ansible 172.16.1.41 -m shell -a "crontab -l"
172.16.1.41 | SUCCESS | rc=0 >>
#Ansible: oldboy01
#*/1 * * * * /bin/sh /server/scripts/sum.sh >dev/null 2>&1
[root@m01 ~]# ansible 172.16.1.41 -m cron -a "name=oldboy01 minute=*/1 hour=* day=* month=* weekday=* job='/bin/sh /server/scripts/sum.sh >dev/null 2>&1' disabled=no"
172.16.1.41 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"oldboy01"
]
}
[root@m01 ~]# ansible 172.16.1.41 -m shell -a "crontab -l"
172.16.1.41 | SUCCESS | rc=0 >>
#Ansible: oldboy01
*/1 * * * * /bin/sh /server/scripts/sum.sh >dev/null 2>&1
[root@m01 ~]#
1.5command play-book
- hosts: 172.16.1.41
tasks:
- name: step01:install rsync
yum: name=rsync state=installed
- name: step02:edit rsync conf file
copy: src=/etc/ansible/conf/rsync_conf/rsyncd.conf dest=/etc/
- name: step03:create rsync user
user: name=rsync state=present createhome=no shell=/sbin/nologin
- name: step04:create auth file
copy: src=/etc/ansible/conf/rsync_conf/rsync.password dest=/etc/ mode=600
- name: step05:create backup dir
file: dest=/backup state=directory owner=rsync group=rsync
- name: step06:boot rsync server
shell: rsync --daemon creates=/var/run/rsyncd.pid
- hosts: 172.16.1.31
tasks:
- name: step01:create auth file
copy: src=/etc/ansible/conf/rsync_conf/rsync_client.password dest=/etc/rsync.password mode=600
执行脚本方法:
ansible-playbook /etc/ansible/ansible-playbook/test.yaml
模拟执行yaml
ansible-playbook -C /etc/ansible/ansible-playbook/test.yaml
1.5.1playbook的优势
首先,上面的操作也有自己的名字,叫adhoc
1.playbook比adhoc功能更全
2.控制好依赖
3.展示直观
4.持久使用
[root@m01 playbook]# ansible-playbook --list-hosts test.yml
playbook: test.yml
play #1 (nginx): nginx TAGS: []
pattern: [u'nginx']
hosts (1):
10.0.0.62
[root@m01 playbook]# ansible-playbook -i /etc/ansible/hosts test.yml
PLAY [nginx] **********************************************************************************************
TASK [Gathering Facts] ************************************************************************************
ok: [10.0.0.62]
TASK [mkdir -p /tomcat] ***********************************************************************************
changed: [10.0.0.62]
PLAY RECAP ************************************************************************************************
10.0.0.62
1.5.2yaml语法
大小写敏感
使用缩进表示层级关系(只能使用空格,不能使用tab)
yaml文件以"---"作为文档的开始
1.5.3支持的数据结构
纯数字,布尔,字符串
字典:{name:vita}
列表:
-apple
-orange
1.5.4playbook中的变量
1.5.4.1playbook的yaml文件中定义变量
[root@m01 playbook]# cat test,y
cat: test,y: No such file or directory
[root@m01 playbook]# cat test.yml
- hosts: nginx
vars:
tl_dir: /server/tools
ap_dir: /application
an_conf: /etc/ansible/conf
tasks:
- name: mkdir -p /tomcat
shell: echo {{tl_dir}}
[root@m01 playbook]# ansible-playbook test.yml
PLAY [nginx] **********************************************************************************************
TASK [Gathering Facts] ************************************************************************************
ok: [10.0.0.62]
TASK [mkdir -p /tomcat] ***********************************************************************************
changed: [10.0.0.62]
PLAY RECAP ************************************************************************************************
10.0.0.62 : ok=2 changed=1 unreachable=0 failed=0
1.5.4.2--extra-vars执行参数赋给变量
[root@m01 playbook]# cat test.yml
- hosts: nginx
vars:
tl_dir: /server/tools
ap_dir: /application
an_conf: /etc/ansible/conf
tasks:
- name: mkdir -p /tomcat
shell: echo {{extra_var}}
[root@m01 playbook]# ansible-playbook test.yml --extra-vars "extra_var=hhhh"
PLAY [nginx] **********************************************************************************************
TASK [Gathering Facts] ************************************************************************************
ok: [10.0.0.62]
TASK [mkdir -p /tomcat] ***********************************************************************************
changed: [10.0.0.62]
PLAY RECAP ************************************************************************************************
10.0.0.62 : ok=2 changed=1 unreachable=0 failed=0
1.5.4.3hosts中定义变量
[root@m01 playbook]# cat /etc/ansible/hosts
10.0.0.61
[db]
172.16.1.61
[php]
172.16.1.61
[nginx]
10.0.0.62 ansible_ssh_user=root ansible_ssh_pass=123456
[nginx:vars]
extra_var=hhhh
[root@m01 playbook]#
[root@m01 playbook]# cat test.yml
- hosts: nginx
vars:
tl_dir: /server/tools
ap_dir: /application
an_conf: /etc/ansible/conf
tasks:
- name: mkdir -p /tomcat
shell: echo {{extra_var}}
[root@m01 playbook]# ansible-playbook test.yml
PLAY [nginx] **********************************************************************************************
TASK [Gathering Facts] ************************************************************************************
ok: [10.0.0.62]
TASK [mkdir -p /tomcat] ***********************************************************************************
changed: [10.0.0.62]
PLAY RECAP ************************************************************************************************
10.0.0.62 : ok=2 changed=1 unreachable=0 failed=0
1.5.4.4注册变量
[root@m01 playbook]# cat test.yml
- hosts: nginx
vars:
tl_dir: /server/tools
ap_dir: /application
an_conf: /etc/ansible/conf
tasks:
- name: mkdir -p /tomcat
command: date
register: date_output
- name: echo
shell: echo {{date_output}}
[root@m01 playbook]# ansible-playbook test.yml
PLAY [nginx] **********************************************************************************************
TASK [Gathering Facts] ************************************************************************************
ok: [10.0.0.62]
TASK [mkdir -p /tomcat] ***********************************************************************************
changed: [10.0.0.62]
TASK [echo] ***********************************************************************************************
changed: [10.0.0.62]
PLAY RECAP ************************************************************************************************
10.0.0.62 : ok=3 changed=2 unreachable=0 failed=0
1.5.5基本语句
1.5.5.1条件语句
[root@m01 playbook]# cat test.yml
- hosts: nginx
vars:
tl_dir: /server/tools
ap_dir: /application
an_conf: /etc/ansible/conf
tasks:
- name: mkdir -p /tomcat
command: touch /opt/{{ansible_distribution}}_system
when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "7") or (ansible_distribution == "Debian" and ansible_distribution_major_version == "6")
[root@m01 playbook]#
[root@m01 playbook]# ansible-playbook test.yml
PLAY [nginx] **********************************************************************************************
TASK [Gathering Facts] ************************************************************************************
ok: [10.0.0.62]
TASK [mkdir -p /tomcat] ***********************************************************************************
[WARNING]: Consider using the file module with state=touch rather than running touch. If you need to use
command because file 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.
changed: [10.0.0.62]
PLAY RECAP ************************************************************************************************
10.0.0.62 : ok=2 changed=1 unreachable=0 failed=0
10.0.0.62是centos7,查看
[root@m02 opt]# ll
total 8
-rw-r--r-- 1 root root 0 Aug 1 21:50 CentOS_system
1.5.5.2循环语句
1.字典循环--with_dict
[root@m01 playbook]# cat test.yml
- hosts: nginx
vars:
tl_dir: /server/tools
ap_dir: /application
an_conf: /etc/ansible/conf
tasks:
- name: mkdir -p /tomcat
debug: msg={{ item.key }}---{{item.value}}
with_dict:
{'name':'wheel', 'val':'wheel'}
[root@m01 playbook]#
[root@m01 playbook]# ansible-playbook test.yml
PLAY [nginx] **********************************************************************************************
TASK [Gathering Facts] ************************************************************************************
ok: [10.0.0.62]
TASK [mkdir -p /tomcat] ***********************************************************************************
ok: [10.0.0.62] => (item={'value': u'wheel', 'key': u'name'}) => {
"msg": "name---wheel"
}
ok: [10.0.0.62] => (item={'value': u'wheel', 'key': u'val'}) => {
"msg": "val---wheel"
}
PLAY RECAP ************************************************************************************************
10.0.0.62 : ok=2 changed=0 unreachable=0 failed=0
[root@m01 playbook]# cat test.yml
- hosts: nginx
vars:
tl_dir: /server/tools
ap_dir: /application
an_conf: /etc/ansible/conf
tasks:
- name: mkdir -p /tomcat
debug: msg={{ item.key }}---{{item.value}}
with_dict:
{'vita':{'english':60,'chinese':80}, 'lili':{'english':90,'chinese':80}}
when: item.value.english>60
[root@m01 playbook]# ansible-playbook test.yml
PLAY [nginx] **********************************************************************************************
TASK [Gathering Facts] ************************************************************************************
ok: [10.0.0.62]
TASK [mkdir -p /tomcat] ***********************************************************************************
skipping: [10.0.0.62] => (item={'value': {u'chinese': 80, u'english': 60}, 'key': u'vita'})
ok: [10.0.0.62] => (item={'value': {u'chinese': 80, u'english': 90}, 'key': u'lili'}) => {
"msg": "lili---{u'chinese': 80, u'english': 90}"
}
PLAY RECAP ************************************************************************************************
10.0.0.62 : ok=2 changed=0 unreachable=0 failed=0
2、with_items
[root@m01 playbook]# cat test.yml
- hosts: nginx
vars:
tl_dir: /server/tools
ap_dir: /application
an_conf: /etc/ansible/conf
tasks:
- name: mkdir -p /tomcat
debug: msg={{ item.name }}---{{item.val}}
with_items:
- {'name':'wheel', 'val':'wheel'}
- {'name':'wheel2', 'val':'wheel2'}
[root@m01 playbook]#
[root@m01 playbook]# ansible-playbook test.yml
PLAY [nginx] **********************************************************************************************
TASK [Gathering Facts] ************************************************************************************
ok: [10.0.0.62]
TASK [mkdir -p /tomcat] ***********************************************************************************
ok: [10.0.0.62] => (item={u'name': u'wheel', u'val': u'wheel'}) => {
"msg": "wheel---wheel"
}
ok: [10.0.0.62] => (item={u'name': u'wheel2', u'val': u'wheel2'}) => {
"msg": "wheel2---wheel2"
}
PLAY RECAP ************************************************************************************************
10.0.0.62 : ok=2 changed=0 unreachable=0 failed=0
3.文件循环
[root@m01 playbook]# cat test.yml
- hosts: nginx
vars:
tl_dir: /server/tools
ap_dir: /application
an_conf: /etc/ansible/conf
tasks:
- name: mkdir -p /tomcat
debug: msg={{ item }}
with_fileglob:
- /etc/ansible/*
[root@m01 playbook]# ansible-playbook test.yml
PLAY [nginx] **********************************************************************************************
TASK [Gathering Facts] ************************************************************************************
ok: [10.0.0.62]
TASK [mkdir -p /tomcat] ***********************************************************************************
ok: [10.0.0.62] => (item=/etc/ansible/hosts) => {
"msg": "/etc/ansible/hosts"
}
ok: [10.0.0.62] => (item=/etc/ansible/hosts.rpmsave) => {
"msg": "/etc/ansible/hosts.rpmsave"
}
ok: [10.0.0.62] => (item=/etc/ansible/ansible.cfg) => {
"msg": "/etc/ansible/ansible.cfg"
}
PLAY RECAP ************************************************************************************************
10.0.0.62 : ok=2 changed=0 unreachable=0 failed=0
1.5.6异常处理
1.5.6.1忽略错误
默认会检查命令和模块的返回状态,遇到错误就中断playbook的执行
加入参数:ignore_errors:yes
上面即使报错了,下面的任务也会进行
[root@m01 playbook]# cat test.yml
- hosts: nginx
vars:
tl_dir: /server/tools
ap_dir: /application
an_conf: /etc/ansible/conf
tasks:
- name: mkdir -p /tomcat
command: /bin/false
ignore_errors: yes
- name: debug
debug: msg=
[root@m01 playbook]#
[root@m01 playbook]# ansible-playbook test.yml
PLAY [nginx] **********************************************************************************************
TASK [Gathering Facts] ************************************************************************************
ok: [10.0.0.62]
TASK [mkdir -p /tomcat] ***********************************************************************************
fatal: [10.0.0.62]: FAILED! => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.002755", "end": "2019-08-01 22:26:32.949887", "msg": "non-zero return code", "rc": 1, "start": "2019-08-01 22:26:32.947132", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
...ignoring
TASK [debug] **********************************************************************************************
ok: [10.0.0.62] => {
"msg": "" #仍然输出了msg
}
PLAY RECAP ************************************************************************************************
10.0.0.62 : ok=3 changed=1 unreachable=0 failed=0
#注释掉ignore_errors
#msg就没有输出了
[root@m01 playbook]# ansible-playbook test.yml
PLAY [nginx] **********************************************************************************************
TASK [Gathering Facts] ************************************************************************************
ok: [10.0.0.62]
TASK [mkdir -p /tomcat] ***********************************************************************************
fatal: [10.0.0.62]: FAILED! => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.001739", "end": "2019-08-01 22:27:48.758480", "msg": "non-zero return code", "rc": 1, "start": "2019-08-01 22:27:48.756741", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
to retry, use: --limit @/etc/ansible/playbook/test.retry
PLAY RECAP ************************************************************************************************
10.0.0.62 : ok=1 changed=0 unreachable=0 failed=1
[root@m01 playbook]#
1.5.6.2faild_when
#当进程数大于3的时候,后面的命令就不执行了
[root@m01 playbook]# cat test.yml
- hosts: nginx
vars:
tl_dir: /server/tools
ap_dir: /application
an_conf: /etc/ansible/conf
tasks:
- name: mkdir -p /tomcat
shell: ps -ef|wc -l
register: process_count
failed_when: process_count > 3
- name: debug
debug: msg=
[root@m01 playbook]# ansible-playbook test.yml
PLAY [nginx] **********************************************************************************************
TASK [Gathering Facts] ************************************************************************************
ok: [10.0.0.62]
TASK [mkdir -p /tomcat] ***********************************************************************************
fatal: [10.0.0.62]: FAILED! => {"changed": true, "cmd": "ps -ef|wc -l", "delta": "0:00:00.017159", "end": "2019-08-01 22:33:52.220817", "failed_when_result": true, "rc": 0, "start": "2019-08-01 22:33:52.203658", "stderr": "", "stderr_lines": [], "stdout": "116", "stdout_lines": ["116"]}
to retry, use: --limit @/etc/ansible/playbook/test.retry
PLAY RECAP ************************************************************************************************
10.0.0.62 : ok=1 changed=0 unreachable=0 failed=1
1.5.7标签
通过tags和任务对象进行捆绑,控制部分或指定的task执行
-t:执行指定的tag标签任务
--skip-tags:执行指定的标签之外的任务
[root@m01 playbook]# cat test.yml
- hosts: nginx
vars:
tl_dir: /server/tools
ap_dir: /application
an_conf: /etc/ansible/conf
tasks:
- name: msg = "cfile1-cfile3"
shell: echo "cfile1-cfile3">/opt/cfile1
tags:
- cfile1
- cfile3
- name: msg = "cfile2"
shell: echo "cfile2">/opt/cfile2
tags:
- cfile2
[root@m01 playbook]#
[root@m01 playbook]# ansible-playbook test.yml -t cfile1
PLAY [nginx] **********************************************************************************************
TASK [Gathering Facts] ************************************************************************************
ok: [10.0.0.62]
TASK [msg = "cfile1-cfile3"] ******************************************************************************
changed: [10.0.0.62]
PLAY RECAP ************************************************************************************************
10.0.0.62 : ok=2 changed=1 unreachable=0 failed=0
[root@m02 opt]# cat cfile1
cfile1-cfile3
62上吧刚刚创建的文件删除
[root@m02 opt]# rm -rf cfile1
[root@m02 opt]# ll
[root@m02 opt]#
[root@m01 playbook]# ansible-playbook test.yml --skip-tags cfile2
PLAY [nginx] **********************************************************************************************
TASK [Gathering Facts] ************************************************************************************
ok: [10.0.0.62]
TASK [msg = "cfile1-cfile3"] ******************************************************************************
changed: [10.0.0.62]
PLAY RECAP ************************************************************************************************
10.0.0.62 : ok=2 changed=1 unreachable=0 failed=0
[root@m01 playbook]#
62上再次查看
[root@m02 opt]# cat cfile1
cfile1-cfile3
1.6ansible实现互相的免密码
**管理机:**
172.16.1.61
**被管理机:**
172.16.1.31
172.16.1.41
172.16.1.7
***下面是在管理机61上进行操作***
**管理机和被管理机都要安装sshpass**
[root@m01 ansible]#yum install -y sshpass
[root@m01 ansible]# ansible oldboy -m yum -a "name=sshpass"
**管理机上首先执行fenfa_key.sh实现管理机对其他主机的免密码登录,并执行fenfa_chek.sh进行验证:**
[root@m01 scripts]# cat fenfa_key.sh
#!/bin/bash
#description:back file to the directory of /backup
#author:vita
#time:2019-03-04
rm -rf /root/.ssh/id_dsa
ssh-keygen -f /root/.ssh/id_dsa -N ""
for ip in 31 41 7 61
do
sshpass -p123456 ssh-copy-id -i /root/.ssh/id_dsa.pub "-o StrictHostKeyChecking=no 172.16.1.$ip"
done
[root@m01 scripts]#
[root@m01 scripts]# cat fenfa_check.sh
#!/bin/bash
#description:back file to the directory of /backup
#author:vita
#time:2019-03-04
[ $# -ne 1 ]&&echo "you should use this script like sh fenfa_check.sh pwd"&&exit
for ip in 31 41 7 61
do
echo "start to excute 172.16.1.$ip"
ssh 172.16.1.$ip $1
echo "172.16.1.$ip end"
done
**管理机上执行上面脚本**
[root@m01 ansible]#sh /server/scripts/fenfa_key.sh
[root@m01 ansible]#sh /server/scripts/fenfa_check.sh pwd
**被管理机上执行脚本**
[root@m01 ansible]# ansible oldboy -m script -a "/server/scripts/fenfa_key.sh"
[root@m01 scripts]# ansible oldboy -m script -a "/server/scripts/fenfa_check.sh pwd"
验证成功,即可互相通信