Ansible以指定用户远程执行命令失败问题排查
你遇到的这个错误是Ansible在切换到非特权用户(goldy)时,无法修改临时文件权限导致的。咱们一步步拆解问题和解决办法:
1. 命令行参数的错误混用
你在执行命令时同时用了已废弃的--sudo和-U参数,又搭配了playbook里的become配置,这会导致参数冲突。Ansible 2.4+已经推荐用become系列参数替代旧的sudo参数,先把命令行改成统一的become格式:
david@machineA:~$ ansible-playbook -e 'host_key_checking=False' -e 'num_serial=1' start_box.yml -u david --ask-pass --become --become-user goldy --ask-become-pass
这样既符合新版本规范,也避免了参数冲突。
2. 核心问题:临时文件权限无法修改
当你从david切换到goldy(普通用户)时,Ansible默认会在远程服务器的/tmp目录下创建临时文件,然后尝试把这些文件的所有权改成goldy。但goldy作为普通用户,没有权限修改不属于自己的文件所有权(这些临时文件由david或root创建),所以抛出了权限错误。
针对这个问题,有几个可行的解决办法:
方法一:配置Ansible使用goldy有权限的临时目录
在playbook里添加remote_tmp变量,指定goldy能读写的目录,比如其家目录下的临时文件夹:
--- - name: start server hosts: one_box serial: "{{ num_serial }}" vars: remote_tmp: /home/goldy/.ansible/tmp tasks: - name: start server command: /tek/ghy/bin/ss.sh start become: true become_user: goldy
记得先确保/home/goldy/.ansible/tmp目录存在,且goldy有读写权限(可提前用Ansible任务创建,或手动在远程服务器上创建)。
方法二:调整sudoers配置(推荐长期使用)
如果环境允许,修改远程服务器的sudoers文件,让david可以无密码切换到goldy,并且允许设置SETENV(帮助Ansible正确处理临时文件)。在远程服务器执行sudo visudo,添加一行:
david ALL=(goldy) NOPASSWD: SETENV: ALL
然后修改playbook,添加become_flags参数:
--- - name: start server hosts: one_box serial: "{{ num_serial }}" tasks: - name: start server command: /tek/ghy/bin/ss.sh start become: true become_user: goldy become_flags: '-H -S -n'
这样Ansible切换用户时会使用正确的sudo flags,避免权限问题。
方法三:临时启用世界可读的临时文件(不推荐,有安全风险)
如果只是临时测试,可以在ansible.cfg里添加或修改:
[defaults] allow_world_readable_tmpfiles = True
这个选项会让Ansible创建的临时文件变为世界可读,goldy无需修改所有权就能访问,但会带来安全隐患,仅适合临时调试使用。
总结
先把命令行参数改成become的规范格式,再根据你的环境选择上述一种方法解决临时文件权限问题,推荐使用方法二(sudoers配置),既安全又能长期稳定运行。
内容的提问来源于stack exchange,提问作者flash

