1.安装:sudo apt install ansible
2.配置要控制的机群
baron@L171:~$ cat /etc/ansible/hosts
[test]
192.168.0.2 ansible_ssh_port=22 ansible_ssh_user=baron ansible_ssh_pass="xxx"
192.168.0.3 ansible_ssh_port=22 ansible_ssh_user=baron ansible_ssh_pass="xxx"
[win]
192.168.0.3 ansible_ssh_port=22 ansible_ssh_user=baron ansible_ssh_pass="xxx"
[deb]
192.168.0.2 ansible_ssh_port=22 ansible_ssh_user=baron ansible_ssh_pass="xxx"
上述方式不推荐,因为有泄露密码的风险,推荐密钥的方式:
1.创建秘钥对
[root@m01 ~]# ssh-keygen
2.推送公钥
[root@m01 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@10.0.0.5
3.测试是否能连通
baron@L171:~$ ansible test -m ping
192.168.1.103 | FAILED! => {
"msg": "to use the 'ssh' connection type with passwords or pkcs11_provider, you must install the sshpass program"
}
192.168.1.102 | FAILED! => {
"msg": "to use the 'ssh' connection type with passwords or pkcs11_provider, you must install the sshpass program"
}
报错,需要安装sshpass: sudo apt install sshpass
baron@L171:~$ ansible test -m ping
192.168.1.102 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
192.168.1.103 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
baron@L171:~$ ansible all -m ping
192.168.1.102 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
192.168.1.103 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
4.ansible的ad-hoc 即临时命令
ansible的常用模块
command # 执行shell命令(不支持管道等特殊字符)
shell # 执行shell命令(支持管道等特殊字符)
scripts # 执行shell脚本
yum_repository # 配置yum仓库
yum # 安装软件
copy # 变更配置文件
file # 建立目录或文件
service # 启动与停止服务
mount # 挂载设备
cron # 定时任务
get_url #下载软件
firewalld #防火墙
selinux #selinux
a.command
chdir # 在执行命令之前,先切换到该目录
executable # 切换shell来执行命令,需要使用命令的绝对路径
free_form # 要执行的Linux指令,一般使用Ansible的-a参数代替。
creates # 一个文件名,当这个文件存在,则该命令不执行
removes # 一个文件名,当这个文件不存在,则该命令不执行
baron@L171:~$ ansible all -m command -a "whoami"
192.168.1.103 | CHANGED | rc=0 >>
baron
192.168.1.102 | CHANGED | rc=0 >>
baron
baron@L171:~$ ansible all -a "whoami"
192.168.1.103 | CHANGED | rc=0 >>
baron
192.168.1.102 | CHANGED | rc=0 >>
baron
#上述的两个命令的输出结果一致,因为ansible的command模块为默认模块
baron@L171:~/ansible_debug$ ansible all -m command -a "chdir=/dds/build ls -al"
192.168.1.102 | CHANGED | rc=0 >>
total 357
drwxrwsr-x. 8 dvp dds 10 8月 4 10:12 .
drwxrwsr-x. 14 robert dds 17 8月 18 15:21 ..
drwxr-sr-x. 24 root dds 25 8月 19 05:00 daily
drwxrwsr-x. 103 dvp dds 111 8月 3 16:52 debug
-rw-rw-r--. 1 baron dds 770 7月 28 15:50 delete_old.py
drwxrwsr-x. 2 dvp dds 1981 7月 15 2021 manifest
drwxr-sr-x. 5 dvp dds 5 8月 4 16:24 prebuilt
-rw-rw-r--. 1 dvp dds 658 3月 11 2021 README.md
drwxrwsr-x. 1041 dvp dds 1041 8月 18 11:53 release
drwxr-sr-x. 7 dvp dds 8 8月 4 10:47 v5
192.168.1.103 | CHANGED | rc=0 >>
total 357
drwxrwsr-x. 8 dvp dds 10 8月 4 10:12 .
drwxrwsr-x. 14 robert dds 17 8月 18 15:21 ..
drwxr-sr-x. 24 root dds 25 8月 19 05:00 daily
drwxrwsr-x. 103 dvp dds 111 8月 3 16:52 debug
-rw-rw-r--. 1 baron dds 770 7月 28 15:50 delete_old.py
drwxrwsr-x. 2 dvp dds 1981 7月 15 2021 manifest
drwxr-sr-x. 5 dvp dds 5 8月 4 16:24 prebuilt
-rw-rw-r--. 1 dvp dds 658 3月 11 2021 README.md
drwxrwsr-x. 1041 dvp dds 1041 8月 18 11:53 release
drwxr-sr-x. 7 dvp dds 8 8月 4 10:47 v5
b.shell
baron@L171:~$ ansible all -m shell -a "df -h |grep tmpfs"
192.168.1.102 | CHANGED | rc=0 >>
devtmpfs 7.6G 0 7.6G 0% /dev
tmpfs 7.7G 0 7.7G 0% /dev/shm
tmpfs 7.7G 68M 7.6G 1% /run
tmpfs 7.7G 0 7.7G 0% /sys/fs/cgroup
tmpfs 1.6G 0 1.6G 0% /run/user/1007
tmpfs 1.6G 0 1.6G 0% /run/user/1008
192.168.1.103 | CHANGED | rc=0 >>
devtmpfs 16G 0 16G 0% /dev
tmpfs 16G 0 16G 0% /dev/shm
tmpfs 16G 1.7G 14G 11% /run
tmpfs 16G 0 16G 0% /sys/fs/cgroup
tmpfs 3.2G 0 3.2G 0% /run/user/1007
c.script 执行shell脚本
baron@L171:~/ansible_debug$ cat touch_flie.sh
#!/bin/bash
touch ansible_test.txt
baron@L171:~/ansible_debug$ ansible all -m script -a "./touch_flie.sh"
192.168.1.102 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.1.102 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.1.102 closed."
],
"stdout": "",
"stdout_lines": []
}
192.168.1.103 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.1.103 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.1.103 closed."
],
"stdout": "",
"stdout_lines": []
}
[baron@s123 ~]$ ll
total 2767
-rw-rw-r--. 1 baron baron 0 Aug 19 14:13 ansible_test.txt
[baron@s111 ~]$ ll |grep ansible
-rw-rw-r--. 1 baron baron 0 Aug 19 14:13 ansible_test.txt
d.copy 文件复制,同时支持指定内容生成文件及设定权限
可用选项:
src #被复制到远程主机的本地文件。可以是绝对路径,也可以是相对路径。如果路径是一个目录,则会递归复制,用法类似于"rsync"
content #用于替换"src",可以直接指定文件的值
dest #必选项,将源文件复制到的远程主机的绝对路径
backup #当文件内容发生改变后,在覆盖之前把源文件备份,备份文件包含时间信息
directory_mode #递归设定目录的权限,默认为系统默认权限
force #当目标主机包含该文件,但内容不同时,设为"yes",表示强制覆盖;设为"no",表示目标主机的目标位置不存在该文件才复制。默认为"yes"
others #所有的 file 模块中的选项可以在这里使用
#普通的复制文件
baron@L171:~/ansible_debug$ ansible all -m copy -a "src=./copy1.txt dest=/home/baron/ansible_client/copy1.txt"
192.168.1.102 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum": "5f9fe411fa092c1fefd1ac80df6614a93b0d5025",
"dest": "/home/baron/ansible_client/copy1.txt",
"gid": 1007,
"group": "baron",
"md5sum": "cae2a388322cca8fce79974f5bcf4826",
"mode": "0664",
"owner": "baron",
"secontext": "system_u:object_r:nfs_t:s0",
"size": 18,
"src": "/home/baron/.ansible/tmp/ansible-tmp-1660894714.113341-324708-179327859620948/source",
"state": "file",
"uid": 1007
}
192.168.1.103 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum": "5f9fe411fa092c1fefd1ac80df6614a93b0d5025",
"dest": "/home/baron/ansible_client/copy1.txt",
"gid": 1007,
"group": "baron",
"md5sum": "cae2a388322cca8fce79974f5bcf4826",
"mode": "0664",
"owner": "baron",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 18,
"src": "/home/baron/.ansible/tmp/ansible-tmp-1660894714.1439934-324706-278491818990206/source",
"state": "file",
"uid": 1007
}
#指定内容复制文件并设置文件权限
baron@L171:~/ansible_debug$ ansible all -m copy -a "content='hello world\n hello baron' dest=/home/baron/ansible_client/content.txt mode=755"
192.168.1.102 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum": "dec8bae8c459fc9291bf2a60aa04310d175c9d45",
"dest": "/home/baron/ansible_client/content.txt",
"gid": 1007,
"group": "baron",
"md5sum": "b61fd86f0963e2f3ff7fd64b31219e5f",
"mode": "0755",
"owner": "baron",
"secontext": "system_u:object_r:nfs_t:s0",
"size": 24,
"src": "/home/baron/.ansible/tmp/ansible-tmp-1660895404.616967-324826-195055200187250/source",
"state": "file",
"uid": 1007
}
192.168.1.103 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum": "dec8bae8c459fc9291bf2a60aa04310d175c9d45",
"dest": "/home/baron/ansible_client/content.txt",
"gid": 1007,
"group": "baron",
"md5sum": "b61fd86f0963e2f3ff7fd64b31219e5f",
"mode": "0755",
"owner": "baron",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 24,
"src": "/home/baron/.ansible/tmp/ansible-tmp-1660895404.6171656-324824-228610653957837/source",
"state": "file",
"uid": 1007
}
#修改指定的内容复制文件并备份
baron@L171:~/ansible_debug$ ansible all -m copy -a "content='hello world\nhello baron' backup=yes dest=/home/baron/ansible_client/content.txt"
192.168.1.102 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"backup_file": "/home/baron/ansible_client/content.txt.2860283.2022-08-19@15:53:59~",
"changed": true,
"checksum": "d5ab78f52e3ad8f76179620c603c4bbafa70e858",
"dest": "/home/baron/ansible_client/content.txt",
"gid": 1007,
"group": "baron",
"md5sum": "20dfff70fd0e7aa7563f20b4111b79f8",
"mode": "0755",
"owner": "baron",
"secontext": "system_u:object_r:nfs_t:s0",
"size": 23,
"src": "/home/baron/.ansible/tmp/ansible-tmp-1660895638.3247252-324914-130231137596010/source",
"state": "file",
"uid": 1007
}
192.168.1.103 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"backup_file": "/home/baron/ansible_client/content.txt.2903654.2022-08-19@15:53:59~",
"changed": true,
"checksum": "d5ab78f52e3ad8f76179620c603c4bbafa70e858",
"dest": "/home/baron/ansible_client/content.txt",
"gid": 1007,
"group": "baron",
"md5sum": "20dfff70fd0e7aa7563f20b4111b79f8",
"mode": "0755",
"owner": "baron",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 23,
"src": "/home/baron/.ansible/tmp/ansible-tmp-1660895638.4328911-324912-209549545817277/source",
"state": "file",
"uid": 1007
}
#注意到本次的命令没有mode设置权限,在被控机上源文件生成了一个包含了时间的备份文件,新文件的权限仍然是755
baron@L171:~/ansible_debug$ ansible all -a "ls -al /home/baron/ansible_client"
192.168.1.103 | CHANGED | rc=0 >>
total 16
drwxrwxr-x. 2 baron baron 106 8月 19 15:53 .
drwx------. 44 baron baron 4096 8月 19 15:34 ..
-rwxr-xr-x. 1 baron baron 23 8月 19 15:53 content.txt
-rwxr-xr-x. 1 baron baron 24 8月 19 15:50 content.txt.2903654.2022-08-19@15:53:59~
-rw-rw-r--. 1 baron baron 18 8月 19 15:38 copy1.txt
192.168.1.102 | CHANGED | rc=0 >>
total 31
drwxrwxr-x. 2 baron baron 5 8月 19 15:53 .
drwx------. 14 baron baron 27 8月 19 15:50 ..
-rwxr-xr-x. 1 baron baron 23 8月 19 15:53 content.txt
-rwxr-xr-x. 1 baron baron 24 8月 19 15:50 content.txt.2860283.2022-08-19@15:53:59~
-rw-rw-r--. 1 baron baron 18 8月 19 15:38 copy1.txt
#修改指定内容,不加备份
baron@L171:~/ansible_debug$ ansible all -m copy -a "content='hello baron\nhello world' dest=/home/baron/ansible_client/content.txt"
192.168.1.102 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum": "8d1e26bd9af77fa749d177855703d5bb77602eac",
"dest": "/home/baron/ansible_client/content.txt",
"gid": 1007,
"group": "baron",
"md5sum": "5b979456032ea64776133e29cb0c985e",
"mode": "0755",
"owner": "baron",
"secontext": "system_u:object_r:nfs_t:s0",
"size": 23,
"src": "/home/baron/.ansible/tmp/ansible-tmp-1660896209.076703-325081-156928659517920/source",
"state": "file",
"uid": 1007
}
192.168.1.103 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum": "8d1e26bd9af77fa749d177855703d5bb77602eac",
"dest": "/home/baron/ansible_client/content.txt",
"gid": 1007,
"group": "baron",
"md5sum": "5b979456032ea64776133e29cb0c985e",
"mode": "0755",
"owner": "baron",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 23,
"src": "/home/baron/.ansible/tmp/ansible-tmp-1660896209.186335-325079-237978906279332/source",
"state": "file",
"uid": 1007
}
baron@L171:~/ansible_debug$ ansible all -a "ls -al /home/baron/ansible_client"
192.168.1.102 | CHANGED | rc=0 >>
total 31
drwxrwxr-x. 2 baron baron 5 8月 19 16:03 .
drwx------. 14 baron baron 27 8月 19 15:50 ..
-rwxr-xr-x. 1 baron baron 23 8月 19 16:03 content.txt
-rwxr-xr-x. 1 baron baron 24 8月 19 15:50 content.txt.2860283.2022-08-19@15:53:59~
-rw-rw-r--. 1 baron baron 18 8月 19 15:38 copy1.txt
192.168.1.103 | CHANGED | rc=0 >>
total 16
drwxrwxr-x. 2 baron baron 106 8月 19 16:03 .
drwx------. 44 baron baron 4096 8月 19 15:34 ..
-rwxr-xr-x. 1 baron baron 23 8月 19 16:03 content.txt
-rwxr-xr-x. 1 baron baron 24 8月 19 15:50 content.txt.2903654.2022-08-19@15:53:59~
-rw-rw-r--. 1 baron baron 18 8月 19 15:38 copy1.txt
baron@L171:~/ansible_debug$ ansible all -a "cat /home/baron/ansible_client/content.txt"
192.168.1.102 | CHANGED | rc=0 >>
hello baron
hello world
192.168.1.103 | CHANGED | rc=0 >>
hello baron
hello world
#发现是直接覆盖了原文件
e. file
该模块主要用于设置文件的属性,比如创建文件、创建链接文件、删除文件等。下面是一些常见的命令:
force #需要在两种情况下强制创建软链接,一种是源文件不存在,但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes | no
group #定义文件/目录的属组。后面可以加上 mode:定义文件/目录的权限
owner #定义文件/目录的属主。后面必须跟上 path:定义文件/目录的路径
recurse #递归设置文件的属性,只对目录有效,后面跟上src:被链接的源文件路径,只应用于state=link的情况
dest #被链接到的路径,只应用于state=link的情况
state #状态,有以下选项:
directory:如果目录不存在,就创建目录
file: 即使文件不存在,也不会被创建
link: 创建软链接
hard: 创建硬链接
touch: 如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
absent:删除目录、文件或者取消链接文件
#创建一个目录
ansible all -m file -a "state=directory path=/home/baron/ansible_client/autodir"
ansible all -a "ls -al /home/baron/ansible_client"
#创建链接文件
ansible all -m file -a "state=link path=/home/baron/ansible_client/autodir/touch.sh src=touch_file.sh"
ansible all -a "ls -al /home/baron/ansible_client/autodir"
注意:源文件在/home/baron/ansible_client/autodir下
#试一下用绝对路径的:
baron@L171:~/ansible_debug$ ansible all -m file -a "state=link path=/home/baron/ansible_client/autodir/touch1.sh src=/home/baron/touch_file.sh"
192.168.1.102 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"dest": "/home/baron/ansible_client/autodir/touch1.sh",
"gid": 1007,
"group": "baron",
"mode": "0777",
"owner": "baron",
"secontext": "system_u:object_r:nfs_t:s0",
"size": 25,
"src": "/home/baron/touch_file.sh",
"state": "link",
"uid": 1007
}
192.168.1.103 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"dest": "/home/baron/ansible_client/autodir/touch1.sh",
"gid": 1007,
"group": "baron",
"mode": "0777",
"owner": "baron",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 25,
"src": "/home/baron/touch_file.sh",
"state": "link",
"uid": 1007
}
baron@L171:~/ansible_debug$ ansible all -a "ls -al /home/baron/ansible_client/autodir"
192.168.1.102 | CHANGED | rc=0 >>
total 19
drwxrwxr-x. 2 baron baron 6 8月 23 12:19 .
drwxrwxr-x. 3 baron baron 6 8月 23 11:26 ..
-rw-rw-r--. 1 baron baron 18 8月 23 11:43 copy1.txt
lrwxrwxrwx. 1 baron baron 25 8月 23 12:19 touch1.sh -> /home/baron/touch_file.sh
-rw-rw-r--. 1 baron baron 36 8月 23 11:55 touch_file.sh
lrwxrwxrwx. 1 baron baron 13 8月 23 11:56 touch.sh -> touch_file.sh
192.168.1.103 | CHANGED | rc=0 >>
total 8
drwxrwxr-x. 2 baron baron 97 8月 23 12:19 .
drwxrwxr-x. 3 baron baron 125 8月 23 11:26 ..
-rw-rw-r--. 1 baron baron 18 8月 23 11:43 copy1.txt
lrwxrwxrwx. 1 baron baron 25 8月 23 12:19 touch1.sh -> /home/baron/touch_file.sh
-rw-rw-r--. 1 baron baron 36 8月 23 11:55 touch_file.sh
lrwxrwxrwx. 1 baron baron 13 8月 23 11:56 touch.sh -> touch_file.sh
#可以的
#删除文件
ansible all -m file -a "path=/home/baron/ansible_client/autodir/copy1.txt state=absent"
f. fetch 模块
该模块用于从远程某主机获取(复制)文件到本地。
有两个选项:
dest:用来存放文件的目录
src: 在远程拉取的文件,并且必须是一个file,不能是目录
baron@L171:~/ansible_debug$ ansible all -m fetch -a "src=/home/baron/ansible_client/autodir/touch_file.sh dest=./"
192.168.1.102 | CHANGED => {
"changed": true,
"checksum": "229b4c9a34e1d82ca4ba8e6353ef2edc4426c94a",
"dest": "/home/baron/ansible_debug/192.168.1.102/home/baron/ansible_client/autodir/touch_file.sh",
"md5sum": "f817fe172e525617e84abad3b3c95955",
"remote_checksum": "229b4c9a34e1d82ca4ba8e6353ef2edc4426c94a",
"remote_md5sum": null
}
192.168.1.103 | CHANGED => {
"changed": true,
"checksum": "229b4c9a34e1d82ca4ba8e6353ef2edc4426c94a",
"dest": "/home/baron/ansible_debug/192.168.1.103/home/baron/ansible_client/autodir/touch_file.sh",
"md5sum": "f817fe172e525617e84abad3b3c95955",
"remote_checksum": "229b4c9a34e1d82ca4ba8e6353ef2edc4426c94a",
"remote_md5sum": null
g. cron 模块
该模块适用于管理cron计划任务的
其使用的语法跟我们的crontab文件中的语法一致,同时,可以指定以下选项:
day= #日,应该运行的工作( 1-31, *, */2, )
hour= # 小时 ( 0-23, *, */2, )
minute= #分钟( 0-59, *, */2, )
month= # 月( 1-12, *, /2, )
weekday= # 周 ( 0-6 for Sunday-Saturday,, )
job= #指明运行的命令是什么
name= #定时任务描述
reboot # 任务在重启时运行,不建议使用,建议使用special_time
special_time #特殊的时间范围,参数:reboot(重启时),annually(每年),monthly(每月),weekly(每周),daily(每天),hourly(每小时)
state #指定状态,present表示添加定时任务,也是默认设置,absent表示删除定时任务
user # 以哪个用户的身份执行
#添加一个定时查看cpu使用情况的任务
baron@L171:~/ansible_debug$ ansible all -m cron -a 'name="log mechine cpu" minute=*/5 job="uptime >> /home/baron/ansible_client/cpulog.log"'
192.168.1.102 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"envs": [],
"jobs": [
"log mechine cpu"
]
}
192.168.1.103 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"envs": [],
"jobs": [
"log mechine cpu"
]
}
#查看被控机定时任务列表
baron@L171:~/ansible_debug$ ansible all -m shell -a "crontab -l"
192.168.1.102 | CHANGED | rc=0 >>
#Ansible: log mechine cpu
*/5 * * * * uptime >> /home/baron/ansible_client/cpulog.log
192.168.1.103 | CHANGED | rc=0 >>
#Ansible: log mechine cpu
*/5 * * * * uptime >> /home/baron/ansible_client/cpulog.log
baron@L171:~/ansible_debug$ ansible all -a "cat /home/baron/ansible_client/cpulog.log"
192.168.1.102 | CHANGED | rc=0 >>
13:55:01 up 40 days, 22:09, 2 users, load average: 0.13, 0.13, 0.13
14:00:01 up 40 days, 22:14, 2 users, load average: 0.15, 0.15, 0.13
192.168.1.103 | CHANGED | rc=0 >>
13:55:01 up 52 days, 3:19, 2 users, load average: 0.03, 0.03, 0.00
14:00:01 up 52 days, 3:24, 2 users, load average: 0.05, 0.05, 0.00
#删除计划任务
baron@L171:~/ansible_debug$ ansible all -m cron -a 'name="log mechine cpu" minute=*/5 job="uptime >>/home/baron/ansible_client/cpulog.log" state=absent'
192.168.1.102 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"envs": [],
"jobs": []
}
192.168.1.103 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"envs": [],
"jobs": []
}
baron@L171:~/ansible_debug$ ansible all -a "crontab -l"
192.168.1.102 | CHANGED | rc=0 >>
192.168.1.103 | CHANGED | rc=0 >>
5.ansible-playbook
首先看下被控机配置 /etc/ansible/hosts
baron@L171:~/ansible_debug/playbook$ cat /etc/ansible/hosts
[test]
192.168.1.103 ansible_ssh_port=22 ansible_ssh_user=baron ansible_ssh_pass=“xxxx”
192.168.1.102 ansible_ssh_port=22 ansible_ssh_user=baron ansible_ssh_pass=“xxxx”
[win]
192.168.1.102 ansible_ssh_port=22 ansible_ssh_user=baron ansible_ssh_pass=“xxxx”
a.先来一个最简单的,输出字符串 查看剧本
---
- hosts: all
vars:
word: Hello World
remote_user: baron
tasks:
-name: echo words
command: echo {{ word }}
baron@L171:~/ansible_debug/playbook$ ansible-playbook test.yml
PLAY [all] *****************************************************************************************************************************************************************************************
TASK [Gathering Facts] *****************************************************************************************************************************************************************************
ok: [192.168.1.102]
ok: [192.168.1.103]
TASK [echo words] **********************************************************************************************************************************************************************************
changed: [192.168.1.102]
changed: [192.168.1.103]
PLAY RECAP *****************************************************************************************************************************************************************************************
192.168.1.103 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.1.102 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
可在命令行中加上 -v 输出详细信息
baron@L171:~/ansible_debug/playbook$ ansible-playbook test.yml -v
No config file found; using defaults
PLAY [all] *****************************************************************************************************************************************************************************************
TASK [Gathering Facts] *****************************************************************************************************************************************************************************
ok: [192.168.1.102]
ok: [192.168.1.103]
TASK [echo words] **********************************************************************************************************************************************************************************
changed: [192.168.1.102] => {"changed": true, "cmd": ["echo", "Hello", "World"], "delta": "0:00:00.001423", "end": "2022-08-29 14:40:03.482488", "msg": "", "rc": 0, "start": "2022-08-29 14:40:03.481065", "stderr": "", "stderr_lines": [], "stdout": "Hello World", "stdout_lines": ["Hello World"]}
changed: [192.168.1.103] => {"changed": true, "cmd": ["echo", "Hello", "World"], "delta": "0:00:00.003572", "end": "2022-08-29 14:40:03.750679", "msg": "", "rc": 0, "start": "2022-08-29 14:40:03.747107", "stderr": "", "stderr_lines": [], "stdout": "Hello World", "stdout_lines": ["Hello World"]}
PLAY RECAP *****************************************************************************************************************************************************************************************
192.168.1.103 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.1.102 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
可在剧本中加入 gather_facts: no 增快执行速度
baron@L171:~/ansible_debug/playbook$ cat test.yml
---
- hosts: all
vars:
word: Hello World
remote_user: baron
gather_facts: no # 不收集对应主机的信息,这样运行会快点。
tasks:
- name: echo words
command: echo {{ word }}
可在执行命令中加参数 --limit win 只在某个组的机器上执行
baron@L171:~/ansible_debug/playbook$ ansible-playbook test.yml -v --limit win
No config file found; using defaults
PLAY [all] *****************************************************************************************************************************************************************************************
TASK [echo words] **********************************************************************************************************************************************************************************
changed: [192.168.1.102] => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": true, "cmd": ["echo", "Hello", "World"], "delta": "0:00:00.001400", "end": "2022-08-29 14:44:35.919901", "msg": "", "rc": 0, "start": "2022-08-29 14:44:35.918501", "stderr": "", "stderr_lines": [], "stdout": "Hello World", "stdout_lines": ["Hello World"]}
PLAY RECAP *****************************************************************************************************************************************************************************************
192.168.1.102 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
现在有这么一个需求,去执行某一台机器上的一个脚本,脚本内容如下:
baron@L171:~/ansible_debug/playbook$ ansible deb -m command -a "cat /home/baron/ansible_client/scriptdir/main.py"
192.168.1.103 | CHANGED | rc=0 >>
a=["this is a test\n","a ansible-playbook test!"]
with open("a.txt","w")as f:
f.writelines(a)
很显然这是个简单的python脚本,创建了一个txt文档写入了两行字符串,接下来在ansible服务器上编写剧本:
---
- hosts: deb
vars:
script: main.py
remote_user: baron
tasks:
- name: execute a python script
command: chdir=/home/baron/ansible_client/scriptdir python3 {{ script }}
执行剧本:
baron@L171:~/ansible_debug/playbook$ ansible-playbook ex_script.yml -v
No config file found; using defaults
PLAY [deb] *****************************************************************************************************************************************************************************************
TASK [Gathering Facts] *****************************************************************************************************************************************************************************
ok: [192.168.1.103]
TASK [execute a python script] *********************************************************************************************************************************************************************
changed: [192.168.1.103] => {"changed": true, "cmd": ["python3", "main.py"], "delta": "0:00:00.038016", "end": "2022-08-30 14:49:06.161975", "msg": "", "rc": 0, "start": "2022-08-30 14:49:06.123959", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
PLAY RECAP *****************************************************************************************************************************************************************************************
192.168.1.103 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
执行结束后查看目标目录,看a.txt是否生成:
baron@L171:~/ansible_debug/playbook$ ansible deb -a "ls -al /home/baron/ansible_client/scriptdir/"
192.168.1.103 | CHANGED | rc=0 >>
total 8
drwxrwxr-x. 2 baron baron 46 8月 30 14:49 .
drwxrwxr-x. 4 baron baron 168 8月 30 14:18 ..
-rw-rw-r--. 1 baron baron 39 8月 30 14:49 a.txt
-rw-rw-r--. 1 baron baron 98 8月 30 14:20 main.py
查看a.txt内容是否正确:
baron@L171:~/ansible_debug/playbook$ ansible deb -a "cat /home/baron/ansible_client/scriptdir/a.txt"
192.168.1.103 | CHANGED | rc=0 >>
this is a test
a ansible-playbook test!
b. 命令行中传递变量
baron@L171:~/ansible_debug/playbook$ cat vars.yml
---
- hosts: test
remote_user: baron
gather_facts: no
tasks:
- name: test vars from cmd line
command: echo "hello,{{ name }}"
baron@L171:~/ansible_debug/playbook$ ansible-playbook vars.yml -v -e name=baron
No config file found; using defaults
[WARNING]: Found variable using reserved name: name
PLAY [test] ****************************************************************************************************************************************************************************************
TASK [test vars from cmd line] *********************************************************************************************************************************************************************
changed: [192.168.0.103] => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": true, "cmd": ["echo", "hello,baron"], "delta": "0:00:00.001667", "end": "2022-09-01 13:45:42.960356", "msg": "", "rc": 0, "start": "2022-09-01 13:45:42.958689", "stderr": "", "stderr_lines": [], "stdout": "hello,baron", "stdout_lines": ["hello,baron"]}
changed: [192.168.0.102] => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": true, "cmd": ["echo", "hello,baron"], "delta": "0:00:00.003743", "end": "2022-09-01 13:45:43.043782", "msg": "", "rc": 0, "start": "2022-09-01 13:45:43.040039", "stderr": "", "stderr_lines": [], "stdout": "hello,baron", "stdout_lines": ["hello,baron"]}
PLAY RECAP *****************************************************************************************************************************************************************************************
192.168.0.102 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.0.103 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
c. 具有sudo权限的用户用sudo 执行剧本
1.修改需要在hosts中加入sudo密码:
ansible_become_pass="xxx"
2 在yml(playbook)中加入: become: true
baron@L171:~/ansible_debug/playbook/product$ cat reboot.yml
---
- hosts: all
remote_user: baron
become: true
gather_facts: no
tasks:
- name: reboot
command: reboot
注:也可以不在hosts中加入密码,采用每次执行的时候都输入: -K(–ask-become-pass):参数是问sudo密码, -k(–ask-pass): ask for connection password
6.配置被控机群的另外一种方法 ssh-copy-id
a. 以 192.168.0.1机器为例,先在这台机器上新建一个用户,为什么新建用户呢?因为这台机器上我用的用户已经配置了git的公钥密钥,我怕影响到代码下载
sudo useradd -d /home/baron -m baron -s /bin/bash 创建用户的时候指定家目录
sudo passwd baron 给新建的用户设置密码
sudo vim /etc/sudoers 我给了新用户sudo权限(以需设置)
切换到baron用户,家目录没啥文件
[baron@s111 ~]$ ls -al
total 12
drwx------. 2 baron baron 78 Sep 5 15:43 .
drwxr-xr-x. 11 root root 164 Sep 5 15:43 ..
-rw-r--r--. 1 baron baron 18 May 27 2021 .bash_logout
-rw-r--r--. 1 baron baron 141 May 27 2021 .bash_profile
-rw-r--r--. 1 baron baron 376 May 27 2021 .bashrc
b. 回到ansible_server机器上,新建一个hosts文件,内容如下
baron@L171:~/ansible_server$ cat hosts
[test]
192.168.0.1 ansible_ssh_port=22 ansible_ssh_user=baron
此时 试下ansible的ping
baron@L171:~/ansible_server$ ansible -i hosts test -m ping
192.168.0.1 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: baron@192.168.0.1: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).",
"unreachable": true
}
预料之中,ping不通
c.最关键的一步:
ssh-copy-id baron@192.168.0.1
baron@L171:~/ansible_server$ ssh-copy-id baron@192.168.0.1
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/baron/.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
baron@192.168.0.1's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'baron@192.168.0.1'"
and check to make sure that only the key(s) you wanted were added.
先看下被控机的目录变化
[baron@s111 ~]$ ls -al
total 12
drwx------. 3 baron baron 94 Sep 5 15:52 .
drwxr-xr-x. 11 root root 164 Sep 5 15:43 ..
-rw-r--r--. 1 baron baron 18 May 27 2021 .bash_logout
-rw-r--r--. 1 baron baron 141 May 27 2021 .bash_profile
-rw-r--r--. 1 baron baron 376 May 27 2021 .bashrc
drwx------. 2 baron baron 37 Sep 5 15:52 .ssh
[baron@s111 ~]$ ll .ssh
total 4
-rw-------. 1 baron baron 564 Sep 5 15:52 authorized_keys
可以看出多了个.ssh目录,这个目录下的文件名为authorized_keys 并不是id_rsa.pub 看来我之前的顾虑是多余的了
试下现在能不能ping的通
baron@L171:~/ansible_server$ ansible -i hosts test -m ping
192.168.0.1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
通了,接下来创建一个目录
baron@L171:~/ansible_server$ ansible -i hosts test -m file -a "state=directory path=/home/baron/ansible_client"
192.168.0.1 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"gid": 1009,
"group": "baron",
"mode": "0775",
"owner": "baron",
"path": "/home/baron/ansible_client",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 10,
"state": "directory",
"uid": 1009
}
baron@L171:~/ansible_server$ ansible -i hosts test -m command -a "ls -al /home/baron"
192.168.0.1 | CHANGED | rc=0 >>
total 12
drwx------. 5 baron baron 140 9月 5 15:58 .
drwxr-xr-x. 11 root root 164 9月 5 15:43 ..
drwx------. 3 baron baron 25 9月 5 15:56 .ansible
drwxrwxr-x. 2 baron baron 10 9月 5 15:58 ansible_client
-rw-r--r--. 1 baron baron 18 5月 27 2021 .bash_logout
-rw-r--r--. 1 baron baron 141 5月 27 2021 .bash_profile
-rw-r--r--. 1 baron baron 376 5月 27 2021 .bashrc
drwx------. 2 baron baron 37 9月 5 15:52 .ssh
d. 再试一下playbook:
baron@L171:~/ansible_server$ cat test.yml
---
- hosts: all
gather_facts: no
remote_user: baron
tasks:
- name: list file
command: ls -al /home/baron
baron@L171:~/ansible_server$ ansible-playbook -i hosts test.yml -v
No config file found; using defaults
PLAY [all] *****************************************************************************************************************************************************************************************
TASK [list file] ***********************************************************************************************************************************************************************************
changed: [192.168.0.1] => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": true, "cmd": ["ls", "-al", "/home/baron"], "delta": "0:00:00.005746", "end": "2022-09-05 16:02:33.702795", "rc": 0, "start": "2022-09-05 16:02:33.697049", "stderr": "", "stderr_lines": [], "stdout": "total 12\ndrwx------. 5 baron baron 140 9月 5 15:58 .\ndrwxr-xr-x. 11 root root 164 9月 5 15:43 ..\ndrwx------. 3 baron baron 25 9月 5 15:56 .ansible\ndrwxrwxr-x. 2 baron baron 10 9月 5 15:58 ansible_client\n-rw-r--r--. 1 baron baron 18 5月 27 2021 .bash_logout\n-rw-r--r--. 1 baron baron 141 5月 27 2021 .bash_profile\n-rw-r--r--. 1 baron baron 376 5月 27 2021 .bashrc\ndrwx------. 2 baron baron 37 9月 5 15:52 .ssh", "stdout_lines": ["total 12", "drwx------. 5 baron baron 140 9月 5 15:58 .", "drwxr-xr-x. 11 root root 164 9月 5 15:43 ..", "drwx------. 3 baron baron 25 9月 5 15:56 .ansible", "drwxrwxr-x. 2 baron baron 10 9月 5 15:58 ansible_client", "-rw-r--r--. 1 baron baron 18 5月 27 2021 .bash_logout", "-rw-r--r--. 1 baron baron 141 5月 27 2021 .bash_profile", "-rw-r--r--. 1 baron baron 376 5月 27 2021 .bashrc", "drwx------. 2 baron baron 37 9月 5 15:52 .ssh"]}
PLAY RECAP *****************************************************************************************************************************************************************************************
192.168.0.1 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
不是sudo执行是没问题的,接下来试下sudo执行的(同一个yml)
baron@L171:~/ansible_server$ ansible-playbook -i hosts test.yml -v -b
No config file found; using defaults
PLAY [all] *****************************************************************************************************************************************************************************************
TASK [list file] ***********************************************************************************************************************************************************************************
fatal: [192.168.0.1]: FAILED! => {"msg": "Missing sudo password"}
PLAY RECAP *****************************************************************************************************************************************************************************************
192.168.0.1 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
-b, --become run operations with become (does not imply password prompting) sudo执行
没有sudo的密码(Missing sudo password)
baron@L171:~/ansible_server$ ansible-playbook -i hosts test.yml -v -b -K
No config file found; using defaults
BECOME password:
PLAY [all] *****************************************************************************************************************************************************************************************
TASK [list file] ***********************************************************************************************************************************************************************************
changed: [192.168.0.1] => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": true, "cmd": ["ls", "-al", "/home/baron"], "delta": "0:00:00.005358", "end": "2022-09-05 17:44:50.982326", "rc": 0, "start": "2022-09-05 17:44:50.976968", "stderr": "", "stderr_lines": [], "stdout": "total 12\ndrwx------. 5 baron baron 140 9月 5 15:58 .\ndrwxr-xr-x. 11 root root 164 9月 5 15:43 ..\ndrwx------. 3 baron baron 25 9月 5 15:56 .ansible\ndrwxrwxr-x. 2 baron baron 10 9月 5 15:58 ansible_client\n-rw-r--r--. 1 baron baron 18 5月 27 2021 .bash_logout\n-rw-r--r--. 1 baron baron 141 5月 27 2021 .bash_profile\n-rw-r--r--. 1 baron baron 376 5月 27 2021 .bashrc\ndrwx------. 2 baron baron 37 9月 5 15:52 .ssh", "stdout_lines": ["total 12", "drwx------. 5 baron baron 140 9月 5 15:58 .", "drwxr-xr-x. 11 root root 164 9月 5 15:43 ..", "drwx------. 3 baron baron 25 9月 5 15:56 .ansible", "drwxrwxr-x. 2 baron baron 10 9月 5 15:58 ansible_client", "-rw-r--r--. 1 baron baron 18 5月 27 2021 .bash_logout", "-rw-r--r--. 1 baron baron 141 5月 27 2021 .bash_profile", "-rw-r--r--. 1 baron baron 376 5月 27 2021 .bashrc", "drwx------. 2 baron baron 37 9月 5 15:52 .ssh"]}
PLAY RECAP *****************************************************************************************************************************************************************************************
192.168.0.1 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
-K, --ask-become-pass ask for privilege escalation password 询问sudo密码
执行成功
持续更新,有不正之处望斧正,不胜感激