Ansible常见模块及使用方法
1.command模块
command模块为ansible默认模块,不指定-m参数时,使用的就是command模块;comand模块比较简单,常见的命令都可以使用,但其命令的执行不是通过shell执行的。缺点:不支持管道, “<”, “>”, “|”, and "&"这些命令都无法执行,也没法批量执行命令。
[root@ansible ~]# ansible -m command -a uptime node-servers #检查ansible节点的运行时间
192.168.3.154 | CHANGED | rc=0 >>
00:16:56 up 1:34, 3 users, load average: 0.00, 0.01, 0.05
192.168.3.155 | CHANGED | rc=0 >>
00:16:55 up 1:34, 3 users, load average: 0.00, 0.03, 0.07
[root@ansible ~]# ansible -m command -a "df -hT" node-servers > a.txtx
[root@ansible ~]# cat a.txtx
192.168.3.154 | CHANGED | rc=0 >>
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/centos-root xfs 17G 2.3G 15G 13% /
devtmpfs devtmpfs 475M 0 475M 0% /dev
tmpfs tmpfs 487M 0 487M 0% /dev/shm
tmpfs tmpfs 487M 7.7M 479M 2% /run
tmpfs tmpfs 487M 0 487M 0% /sys/fs/cgroup
/dev/sr0 iso9660 3.3G 3.3G 0 100% /mnt
/dev/sda1 xfs 1014M 146M 869M 15% /boot
tmpfs tmpfs 98M 0 98M 0% /run/user/0
192.168.3.155 | CHANGED | rc=0 >>
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/centos-root xfs 17G 2.2G 15G 13% /
devtmpfs devtmpfs 475M 0 475M 0% /dev
tmpfs tmpfs 487M 0 487M 0% /dev/shm
tmpfs tmpfs 487M 7.7M 479M 2% /run
tmpfs tmpfs 487M 0 487M 0% /sys/fs/cgroup
/dev/sr0 iso9660 4.3G 4.3G 0 100% /mnt
/dev/sda1 xfs 1014M 146M 869M 15% /boot
tmpfs tmpfs 98M 0 98M 0% /run/user/0
[root@ansible ~]#
2.shell模块
在远程主机通过/bin/sh来执行命令,也可以执行远程主机脚本。
[root@ansible ~]# ansible -i /etc/ansible/hosts node-servers -m shell -a "free -m"
192.168.3.154 | CHANGED | rc=0 >>
total used free shared buff/cache available
Mem: 972 280 532 7 159 527
Swap: 2047 0 2047
192.168.3.155 | CHANGED | rc=0 >>
total used free shared buff/cache available
Mem: 972 279 516 7 177 517
Swap: 2047 0 2047
[root@ansible ~]#
注意:我们自己定义在~/.bashrc或/.bash_profile中的环境变量shell模块由于没有加载,所以无法识别;如果需要使用自定义的环境变量,就需要在最开始,执行加载自定义脚本的语句。
[root@ansible ~]# ansible -i /etc/ansible/hosts node-servers -m shell -a "source ~/.bash_profile&&ls"
192.168.3.154 | CHANGED | rc=0 >>
afei.sql
mha4mysql-node-0.54-0.el6.noarch.rpm
192.168.3.155 | CHANGED | rc=0 >>
afei2.sql
test.sh
[root@ansible ~]# ansible -i /etc/ansible/hosts node-servers -m shell -a "/root/test.sh" #远程主机脚本需添加执行权限
192.168.3.154 | FAILED | rc=127 >>
/bin/sh: /root/test.sh: No such file or directorynon-zero return code
192.168.3.155 | CHANGED | rc=0 >>
afei2.sql
test.sh
00:50:19 up 2:07, 3 users, load average: 0.00, 0.01, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.3.1 22:55 1:54m 0.01s 0.01s -bash
root pts/1 192.168.3.1 00:12 11.00s 0.01s 0.01s -bash
root pts/2 192.168.3.156 00:50 0.00s 0.11s 0.00s /bin/bash /root/test.sh
[root@ansible ~]#
使用异步执行功能:
参数:
-P 0 #直接返回job_id;
-P 1 #当-P的参数大于0时,会根据job_id去轮询查询;
-f #指定并行进程数量,默认为5个并行进程;
-B #指定异步运行时间。
[root@ansible ~]# ansible group1 -B 60 -P 0 -m shell -a 'sleep 5;hostname' -f 5 -o
192.168.3.155 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "ansible_job_id": "43147287103.39056", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/43147287103.39056", "started": 1}
192.168.3.156 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "ansible_job_id": "653990043951.40753", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/653990043951.40753", "started": 1}
192.168.3.154 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "ansible_job_id": "986411836435.2136", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/986411836435.2136", "started": 1}
[root@ansible ~]# ansible 192.168.3.154 -m async_status -a 'jid=986411836435.2136' #使用async_status模块指定主机jid
192.168.3.154 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"ansible_job_id": "986411836435.2136",
"changed": true,
"cmd": "sleep 5;hostname",
"delta": "0:00:05.007004",
"end": "2020-05-20 06:14:36.236484",
"finished": 1,
"rc": 0,
"start": "2020-05-20 06:14:31.229480",
"stderr": "",
"stderr_lines": [],
"stdout": "node2",
"stdout_lines": [
"node2"
]
}
[root@ansible ~]# ansible group1 -B 10 -P 1 -m shell -a 'sleep 10;hostname' -f 5 -o #轮询查询
192.168.3.154 | CHANGED => {"ansible_job_id": "728879409622.2536", "changed": true, "cmd": "sleep 10;hostname", "delta": "0:00:10.003717", "end": "2020-05-20 06:19:12.994710", "finished": 1, "rc": 0, "start": "2020-05-20 06:19:02.990993", "stderr": "", "stderr_lines": [], "stdout": "node2", "stdout_lines": ["node2"]}
192.168.3.155 | CHANGED => {"ansible_job_id": "352639944485.40698", "changed": true, "cmd": "sleep 10;hostname", "delta": "0:00:10.009015", "end": "2020-05-19 22:26:19.986939", "finished": 1, "rc": 0, "start": "2020-05-19 22:26:09.977924", "stderr": "", "stderr_lines": [], "stdout": "node1", "stdout_lines": ["node1"]}
192.168.3.156 | CHANGED => {"ansible_job_id": "669103457065.42742", "changed": true, "cmd": "sleep 10;hostname", "delta": "0:00:10.004482", "end": "2020-05-19 22:26:10.606689", "finished": 1, "rc": 0, "start": "2020-05-19 22:26:00.602207", "stderr": "", "stderr_lines": [], "stdout": "ansible", "stdout_lines": ["ansible"]}
[root@ansible ~]#
3.script模块
在远程主机上执行主控端的脚本,相当于scp+shell组合。
[root@ansible ~]# ls
test1.sh
[root@ansible ~]# chmod +x test1.sh
[root@ansible ~]# ansible -i /etc/ansible/hosts node-servers -m script -a "test1.sh"
192.168.3.154 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.3.154 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.3.154 closed."
],
"stdout": "afei.sql mha4mysql-node-0.54-0.el6.noarch.rpm\r\n",
"stdout_lines": [
"afei.sql mha4mysql-node-0.54-0.el6.noarch.rpm"
]
}
192.168.3.155 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.3.155 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.3.155 closed."
],
"stdout": "afei2.sql test.sh\r\n",
"stdout_lines": [
"afei2.sql test.sh"
]
}
[root@ansible ~]#
4.copy模块
实现主控端向目标主机拷贝文件,类似scp功能。
[root@ansible ~]# ansible node-servers -m copy -a "src=/root/test1.sh dest=/opt/ owner=root group=root mode=0644"
192.168.3.155 | SUCCESS => {
"changed": false,
"checksum": "8d4f8520af439912f67cc2b2ea56aec45045e403",
"dest": "/opt/test1.sh",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"path": "/opt/test1.sh",
"secontext": "system_u:object_r:usr_t:s0",
"size": 16,
"state": "file",
"uid": 0
}
192.168.3.154 | CHANGED => {
"changed": true,
"checksum": "8d4f8520af439912f67cc2b2ea56aec45045e403",
"dest": "/opt/test1.sh",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"path": "/opt/test1.sh",
"size": 16,
"state": "file",
"uid": 0
}
[root@ansible ~]#
参数解析:
src #主控端文件位置;
dest #被控端目标位置;
owner #文件复制过去后的所有者;
group #文件复制过去后的所属组;
mode #文件的权限设定。
查看验证:
[root@ansible ~]# ansible node-servers -m shell -a "ls -la /opt/test1.sh" -f 5 -o
192.168.3.154 | CHANGED | rc=0 | (stdout) -rw-r--r--. 1 root root 50 May 20 12:03 /opt/test1.sh
192.168.3.156 | CHANGED | rc=0 | (stdout) -rw-r--r-- 1 root root 50 May 21 22:26 /opt/test1.sh
192.168.3.155 | CHANGED | rc=0 | (stdout) -rw-r--r-- 1 root root 50 May 20 04:09 /opt/test1.sh
[root@ansible ~]#
5.stat模块
获取远程主机文件的状态信息,包括atime,ctime,mtime,md5,uid,gid等信息。
[root@ansible ~]# ansible node-servers -m stat -a "path=/etc/selinux"
192.168.3.154 | SUCCESS => {
"changed": false,
"stat": {
"atime": 1540943072.0,
"attr_flags": "",
"attributes": [],
"block_size": 4096,
"blocks": 0,
"charset": "binary",
"ctime": 1555028929.9959326,
"dev": 64768,
"device_type": 0,
"executable": true,
"exists": true,
"gid": 0,
"gr_name": "root",
...
6.yum模块
主要功能是安装软件包
[root@ansible ~]# ansible node-servers -m yum -a "name=httpd state=installed disable_gpg_check=no"
192.168.3.155 | SUCCESS => {
"ansible_facts": {
"pkg_mgr": "yum"
},
"changed": false,
"msg": "",
"rc": 0,
"results": [
"httpd-2.4.6-88.el7.centos.x86_64 providing httpd is already installed"
]
}
...
参数详解:
name #包名 ;
state #状态(选项: present, installed, latest, absent,removed)默认是:present ;
disable_gpg_check #禁止gpg检查 ;
enablerepo #只启动指定的repo。
查看服务:
[root@ansible ~]# ansible node-servers -m shell -a "netstat -nltup|grep httpd" -f 5 -o
192.168.3.156 | CHANGED | rc=0 | (stdout) tcp6 0 0 :::80 :::* LISTEN 861/httpd
192.168.3.155 | CHANGED | rc=0 | (stdout) tcp6 0 0 :::80 :::* LISTEN 894/httpd
192.168.3.154 | CHANGED | rc=0 | (stdout) tcp6 0 0 :::80 :::* LISTEN 969/httpd
7.cron模块
配置远程主机crontab(计划任务)
[root@ansible ~]# ansible node-servers -m cron -a "name='test' minute='*/10' hour='2' day='1' month='*' weekday='1-5' job='ls -l' user='root'"
192.168.3.154 | CHANGED => {
"changed": true,
"envs": [],
"jobs": [
"test"
]
}
192.168.3.155 | CHANGED => {
"changed": true,
"envs": [],
"jobs": [
"test"
]
}
[root@ansible ~]#
在节点上查看:
[root@node1 ~]# crontab -l
#Ansible: test
*/10 2 1 * 1-5 ls -l
[root@node1 ~]#
[root@node2 ~]# crontab -l
#Ansible: test
*/10 2 1 * 1-5 ls -l
[root@node2 ~]#
删除指定的计划任务:
[root@ansible ~]# ansible node-servers -m cron -a "name='test' state=absent"
192.168.3.154 | CHANGED => {
"changed": true,
"envs": [],
"jobs": []
}
192.168.3.155 | CHANGED => {
"changed": true,
"envs": [],
"jobs": []
}
[root@ansible ~]#
8.mount模块
功能:挂载文件系统
[root@ansible ~]# ansible 192.168.3.155 -m mount -a "src=/dev/cdrom path=/mnt/ fstype=iso9660 state=present"
192.168.3.155 | CHANGED => {
"changed": true,
"dump": "0",
"fstab": "/etc/fstab",
"fstype": "iso9660",
"name": "/mnt/",
"opts": "defaults",
"passno": "0",
"src": "/dev/cdrom"
}
[root@ansible ~]#
9.service模块
功能:远程主机系统服务管理。
[root@ansible ~]# ansible node-servers -m service -a "name=httpd state=started"
192.168.3.155 | CHANGED => {
"changed": true,
"name": "httpd",
"state": "started",
...
参数详解:
name #指定服务名称
state #指定服务的状态(started | stoped | restarted | reloaded)
enable #指定是否将服务设为开机自启(yes | no)
10.synchronize模块
功能:使用rsync同步文件,将ansible服务端目录推送到指定节点的目录下。
[root@ansible ~]# ansible node-servers -m synchronize -a "src=/root/test1.sh dest=/root/"
192.168.3.154 | CHANGED => {
"changed": true,
"cmd": "/usr/bin/rsync --delay-updates -F --compress --archive --rsh=/usr/bin/ssh -S none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null --out-format=<<CHANGED>>%i %n%L /root/test1.sh 192.168.3.154:/root/",
"msg": "<f+++++++++ test1.sh\n",
"rc": 0,
"stdout_lines": [
"<f+++++++++ test1.sh"
]
}
参数详解:
src #需要同步的目录路径,路径可以是绝对的或相对的。如果路径使用”/”来结尾,则只复制目录里的内容,如果没有使用”/”来结尾,则包含目录在内的整个内容全部复制;
dest #节点主机指定路径,将会同步到该目录下,路径可以是绝对的或相对的;
delete #删除不存在的文件,delete=yes 使两边的内容一样(以ansible服务端为主),默认no;
dest_port #默认目录主机上的端口 ,默认是22,走的ssh协议;
mode #push或pull,默认push,一般用于从本机向远程主机上传文件,pull 模式用于从远程主机上取文件;
rsync_opts #通过传递数组来指定其他rsync选项。
11.template模块
功能:基于模板方式生成一个文件复制到远程主机(template使用Jinjia2格式作为文件模版,进行文档内变量的替换的模块。它的每次使用都会被ansible标记为”changed”状态。)
[root@ansible ~]# ansible node-servers -m template -a "src=/root/test1.sh dest=/root/ owner=root group=root mode=0644"
192.168.3.154 | CHANGED => {
"changed": true,
"checksum": "8d4f8520af439912f67cc2b2ea56aec45045e403",
"dest": "/root/test1.sh",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"path": "/root/test1.sh",
"size": 16,
"state": "file",
"uid": 0
}
...
参数详解:
src #在ansible控制器上的Jinja2格式化模板的路径,可以是相对路径或绝对路径;
dest #指定复制到远程主机的路径;
force #是否强制覆盖,默认为yes ;
owner #目标文件属主 ;
group #目标文件属组 ;
mode #目标文件的权限模式;
backup #如果原目标文件存在,则先备份目标文件 。
12.get_url模块
功能:主要用于从http、ftp、https服务器上下载文件(类似于wget)。
[root@ansible ~]# ansible node-servers -m get_url -a "url=https://docs.ansible.com/ansible/latest/index.html dest=/root mode=0644"
192.168.3.154 | CHANGED => {
"changed": true,
"checksum_dest": null,
"checksum_src": "260e2063ae1ebb25e0d56776e7a33bde337a4af1",
"dest": "/root/index.html",
"gid": 0,
"group": "root",
"md5sum": "a90741cc0198bb8566a96fa3bc03b05b",
"mode": "0644",
"msg": "OK (unknown bytes)",
"owner": "root",
"size": 285548,
"src": "/root/.ansible/tmp/ansible-tmp-1555370473.99-183840949465812/tmpF_kWjq",
"state": "file",
"status_code": 200,
"uid": 0,
"url": "https://docs.ansible.com/ansible/latest/index.html"
}
...
参数详解:
url #下载的URL ;
dest #远程主机的绝对路径。如果dest是目录,则使用服务器提供的文件名,或者如果没有提供,将使用远程服务器上的URL的基本名称;
sha256sum #下载完成后进行sha256 check;
timeout #下载超时时间,默认10s ;
url_password、url_username #主要用于需要用户名密码进行验证的情况 ;
headers #以键值对形式(key:value),“key:value”为请求添加自定义HTTP标头。
13.file模块
功能:主要用于远程主机上的文件操作。
[root@ansible ~]# ansible node-servers -m file -a "path=a.txt owner=root group=root state=touch"
192.168.3.154 | CHANGED => {
"changed": true,
"dest": "a.txt",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"size": 0,
"state": "file",
"uid": 0
}
...
参数详解:
path #必选项,定义文件/目录的路径;
group #定义文件/目录的属组;
mode #定义文件/目录的权限;
owner #定义文件/目录的属主;
force #需要在两种情况下强制创建软链接,一种是源文件不存在但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes|no;
recurse #递归的设置文件的属性,只对目录有效;
src #要被链接的源文件的路径,只应用于state=link的情况;
dest #被链接到的路径,只应用于state=link的情况;
state选项:
directory:如果目录不存在,创建目录;
file:即使文件不存在,也不会被创建;
link:创建软链接; hard:创建硬链接;
touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间;
absent:删除目录、文件或者取消链接文件。
14.user模块
首先通过openssl生成一个密码, 因为ansible的user模块的password参数需要接受加密后的值。
[root@ansible ~]# echo afei | openssl passwd -1 -stdin #将明文密码afei生成openssl密文
$1$T0NsxOdw$4MrpM5IWH65dE0HGsEu/g1
[root@ansible ~]# ansible node-servers -m user -a "name=test password='$1$T0NsxOdw$4MrpM5IWH65dE0HGsEu/g1'" -f 5 -o
192.168.3.155 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "comment": "", "create_home": true, "group": 1001, "home": "/home/test", "name": "test", "password": "NOT_LOGGING_PASSWORD", "shell": "/bin/bash", "state": "present", "system": false, "uid": 1001, "warnings": ["The input password appears not to have been hashed. The 'password' argument must be encrypted for this module to work properly."]}
192.168.3.156 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "comment": "", "create_home": true, "group": 1001, "home": "/home/test", "name": "test", "password": "NOT_LOGGING_PASSWORD", "shell": "/bin/bash", "state": "present", "system": false, "uid": 1001, "warnings": ["The input password appears not to have been hashed. The 'password' argument must be encrypted for this module to work properly."]}
192.168.3.154 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "comment": "", "create_home": true, "group": 1000, "home": "/home/test", "name": "test", "password": "NOT_LOGGING_PASSWORD", "shell": "/bin/bash", "state": "present", "system": false, "uid": 1000, "warnings": ["The input password appears not to have been hashed. The 'password' argument must be encrypted for this module to work properly."]}
[root@ansible ~]# ansible node-servers -m shell -a "id test" -f 5 -o
192.168.3.155 | CHANGED | rc=0 | (stdout) uid=1001(test) gid=1001(test) groups=1001(test)
192.168.3.154 | CHANGED | rc=0 | (stdout) uid=1000(test) gid=1000(test) groups=1000(test)
192.168.3.156 | CHANGED | rc=0 | (stdout) uid=1001(test) gid=1001(test) groups=1001(test)
[root@ansible ~]#