Ansible copy模块和synchronize模块说明及比较

对文件的批量变更是运维自动化领域中很常见的需求之一.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通道因此会再次提示输入密码,在大规模文件下发场景中使用体验较差,可以考虑通过其它途径实现。