对文件的批量变更是运维自动化领域中很常见的需求之一.Ansible官方针对文件操作部分提供了很多模块 ,这里仅对最常用的copy和synchronize模块进行一个简单的比较。
copy模块 常用参数列表
参数
是否必选字段
默认值
可选值
说明
backup
no
no
yes/no
是否备份被修改的文件
src
no
本地路径;可以是绝对路径也可以是相对路径。如果是目录,则递归地复制。此种情况下,类似于rsync,如果路径以“/”结尾,则只有该目录下的文件或子目录被复制。如果不以“/”结尾,则同时复制该目录。
content
no
可使用content代替”SRC”,将文件的内容直接设置为指定的简单的值。对于任何复杂的或格式化的内容使用template模块。
dest
yes
文件被复制到的远端服务器上的绝对路径。说明:如果src给定的是目录,dest也必须是目录
follow
no
no
yes/no
保留软链属性(added in 1.8)
force
no
yes
yes/no
如果文件已存在,默认强制覆盖,如果设置为no,则只有当文件不存在时才会被传输 aliases: thirsty
group
no
文件或目录的所属用户组
mode
no
文件或目录权限,用八进制数字表示,如0644,如果没有前置0可能出现异常
owner
no
文件或目录的所属用户
remote_src
no
False
True/False
如果是true,将从远端往远端服务,相当于在远端服务器上执行copy操作。如果为false,则从本地复制到远程,默认是false。remote_src不支持递归复制。(added in 2.0)
使用场景举例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # ansible all -m copy -a "src=/tmp/test.txt dest=/tmp/ backup=yes" -i hosts 192.168.0.1 | SUCCESS => { "backup_file": "/tmp/test.txt.7587.2017-08-04@16:58:43~", "changed": true, "checksum": "d961c3de6d6c99429806ae3d6d03f316a1168ac6", "dest": "/tmp/test.txt", "gid": 0, "group": "root", "md5sum": "7494ab07987ba112bd5c4f9857ccfb3f", "mode": "0644", "owner": "root", "size": 5, "src": "/root/.ansible/tmp/ansible-tmp-1501837122.86-21046238098569/source", "state": "file", "uid": 0 }
synchronize模块 常用参数列表
参数
是否必选字段
默认值
可选值
说明
archive
no
yes
yes/no
递归保留源目录中的软链、权限、时间戳、所属用户等属性
recursive
no
选项archive的值
yes/no
目录递归
group
no
选项archive的值
yes/no
指定所属用户组
owner
no
选项archive的值
yes/no
指定所属用户
links
no
选项archive的值
yes/no
保留软链接
perms
no
选项archive的值
yes/no
保留权限设置
times
no
选项archive的值
yes/no
保留时间戳
compress
no
yes
yes/no
压缩传输,除非会导致异常,多数情况下建议开启(added in 1.7)
copy_links
no
no
yes/no
复制软链指向的内容而不是软链本身
delete
no
no
yes/no
传输完成后,删除目标路径下,源目录中不存在的文件This option requires recursive=yes.
src
yes
源主机上的路径,可以是绝对路径也可以是相对路径
dest
yes
目标主机上的存储路径。可以是绝对路径,也可以是相对路径。
dirs
no
no
yes/no
不递归传输
existing_only
no
no
yes/no
跳过目标端不存在的目录或文件(added in 1.5)
mode
no
push
push/pull
指定推送方式,拉取或者推送,默认是push模式,push模式下src是源,pull模式下dest是源
rsync_opts
no
通过数组指定额外的rsync选项(added in 1.6)
rsync_path
no
指定远程主机上的rsync命令
rsync_timeout
no
指定rsync的超时时间
set_remote_user
no
True
当远端服务器上自定义ssh配置文件中定义的remote user和inventory user不匹配的情况下,这个参数值设置为”no”
use_ssh_args
no
no
yes/no
使用ansible.cfg中指定的ssh_args参数(added in 2.0)
verify_host
no
验证目标主机的秘钥(added in 2.0)
使用场景举例
报错:”msg”: “Invalid shell type specified (bash), or the plugin for that shell type is missing.”1 2 3 4 5 # ansible all -m synchronize -a "src=/tmp/test.txt dest=/tmp/" -i hosts 192.168.0.1 | FAILED! => { "failed": true, "msg": "Invalid shell type specified (bash), or the plugin for that shell type is missing." }
解决方案:
将ansible.cfg
中的executable = /bin/bash
注释掉1 2 3 4 5 6 7 8 9 10 # ansible all -m synchronize -a "src=/tmp/test.txt dest=/tmp/" -i hosts 192.168.0.1 | SUCCESS => { "changed": true, "cmd": "/usr/bin/rsync --delay-updates -F --compress --archive --rsh 'ssh -S none -o StrictHostKeyChecking=no' --out-format='<<CHANGED>>%i %n%L' \"/tmp/test.txt\" \"192.168.0.1:/tmp/\"", "msg": "<f.st...... test.txt\n", "rc": 0, "stdout_lines": [ "<f.st...... test.txt" ] }
push模式拉取文件1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # ansible all -m synchronize -a "src=/tmp/test.txt dest=/tmp/ rsync_opts='-abvzP, --suffix=.bak-$(date "+%Y-%m-%d_%H")'" -ihosts 192.168.0.1 | SUCCESS => { "changed": true, "cmd": "/usr/bin/rsync --delay-updates -F --compress --archive --rsh 'ssh -S none -o StrictHostKeyChecking=no' -abvzP --suffix=.bak-2017-08-04_18 --out-format='<<CHANGED>>%i %n%L' \"/tmp/test.txt\" \"192.168.0.1:/tmp/\"", "msg": "building file list ... \n 0 files...\r1 file to consider\n<f..t...... test.txt\n 6 100% 0.00kB/s 0:00:00\r6 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/1)\n\nsent 79 bytes received 37 bytes 77.33 bytes/sec\ntotal size is 6 speedup is 0.05\n", "rc": 0, "stdout_lines": [ "building file list ... ", " 0 files...\r1 file to consider", "<f..t...... test.txt", " 6 100% 0.00kB/s 0:00:00\r 6 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/1)", "sent 79 bytes received 37 bytes 77.33 bytes/sec", "total size is 6 speedup is 0.05" ] }
pull模式拉取文件1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 # ansible all -m synchronize -a "mode=pull src=/tmp/tmp1 dest=/tmp/ rsync_opts='-abvzP, --suffix=.bak-$(date "+%Y-%m-%d_%H")'" -i hosts 192.168.0.1 | SUCCESS => { "changed": true, "cmd": "/usr/bin/rsync --delay-updates -F --compress --archive --rsh 'ssh -S none -o StrictHostKeyChecking=no' -abvzP --suffix=.bak-2017-08-05_13 --out-format='<<CHANGED>>%i %n%L' \"192.168.0.1:/tmp/tmp1\" \"/tmp/\"", "msg": "receiving file list ... \n4 files to consider\ncd+++++++++ tmp1/\ncd+++++++++ tmp1/tmp2/\ncd+++++++++ tmp1/tmp2/tmp3/\n>f+++++++++ tmp1/tmp2/tmp3/test.log\n 0 0% 0.00kB/s 0:00:00\r 13 100% 12.70kB/s 0:00:00 (xfer#1, to-check=0/4)\n\nsent 73 bytes received 145 bytes 436.00 bytes/sec\ntotal size is 13 speedup is 0.06\n", "rc": 0, "stdout_lines": [ "receiving file list ... ", "4 files to consider", "cd+++++++++ tmp1/", "cd+++++++++ tmp1/tmp2/", "cd+++++++++ tmp1/tmp2/tmp3/", ">f+++++++++ tmp1/tmp2/tmp3/test.log", " 0 0% 0.00kB/s 0:00:00\r 13 100% 12.70kB/s 0:00:00 (xfer#1, to-check=0/4)", "sent 73 bytes received 145 bytes 436.00 bytes/sec", "total size is 13 speedup is 0.06" ] }
copy模块和synchronize模块的简单比较
copy模块不支持从远端到本地的拉去操作,fetch模块支持,但是src参数不支持目录递归,只能回传具体文件;
copy模块的remote_src参数是指定从远端服务器上往远端服务器上复制,相当于在shell模块中执行copy命令;
synchronize则支持文件下发和回传,分别对应的push和pull模式。synchronize模块的功能依赖于rsync.x86_64,但是功能不依赖于rsync配置文件中定义的模块;
copy模块适用于小规模文件操作,synchronize支持大规模文件操作。
synchronize模块存在的缺陷
hosts文件(inventory)中中如果使用ansible_ssh_pass
通过用户名密码认证,则在使用synchronize模块时由于模块使用的是独立的ssh通道因此会再次提示输入密码,在大规模文件下发场景中使用体验较差,可以考虑通过其它途径实现。