问题描述

在使用Ansible时,可能会遇到“Permission denied Errno 13”错误,这通常是因为当前用户没有足够的权限对目标文件或目录进行操作。本文将介绍如何复现、排查和修复该错误,并通过Ansible Playbook中的特权提升(Privilege Escalation)解决权限问题。

错误复现

以下是一个Ansible Playbook示例,用于复现“Permission denied Errno 13”错误:

文件:permissiondenied_error.yml

---
- name: 设置环境变量
  hosts: all
  gather_facts: false
  vars:
    os_environment:
      - key: EDITOR
        value: vi
  tasks:
    - name: 自定义 /etc/environment
      ansible.builtin.lineinfile:
        dest: "/etc/environment"
        state: present
        regexp: "^{{ item.key }}="
        line: "{{ item.key }}={{ item.value }}"
      with_items: "{{ os_environment }}"

错误执行

运行Playbook时,可能会出现以下错误:

$ ansible-playbook -i inventory troubleshooting/permissiondenied_error.yml
PLAY [设置环境变量] ******************************************************
TASK [自定义 /etc/environment] ********************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: PermissionError: [Errno 13] Permission denied: b'/home/devops/.ansible/tmp/ansible-tmp-1645543127.772594-89712-144540003805636/tmpvhoh4q83' -> b'/etc/environment'
failed: [demo.example.com] (item={'key': 'EDITOR', 'value': 'vi'}) => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "ansible_loop_var": "item", "changed": false, "item": {"key": "EDITOR", "value": "vi"}, "msg": "目标目录 (/etc) 当前用户无写权限。错误为:[Errno 13] Permission denied: b'/etc/.ansible_tmp_hwdwg3denvironment'"}
PLAY RECAP ****************************************************************
demo.example.com           : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

解决方案

通过在Playbook中启用特权提升(Privilege Escalation),可以解决权限不足的问题。在Playbook中添加become: true,以确保任务以更高权限执行。

文件:permissiondenied_fix.yml

---
- name: 设置环境变量
  hosts: all
  gather_facts: false
  become: true  # 启用特权提升
  vars:
    os_environment:
      - key: EDITOR
        value: vi
  tasks:
    - name: 自定义 /etc/environment
      ansible.builtin.lineinfile:
        dest: "/etc/environment"
        state: present
        regexp: "^{{ item.key }}="
        line: "{{ item.key }}={{ item.value }}"
      with_items: "{{ os_environment }}"

修复执行

运行修复后的Playbook:

$ ansible-playbook -i inventory troubleshooting/permissiondenied_fix.yml
PLAY [设置环境变量] ******************************************************
TASK [自定义 /etc/environment] ********************************************
changed: [demo.example.com] => (item={'key': 'EDITOR', 'value': 'vi'})
PLAY RECAP ****************************************************************
demo.example.com           : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

总结

  1. 启用特权提升:通过在Playbook中添加become: true,可以解决因权限不足导致的“Permission denied Errno 13”错误。
  2. 检查目标文件权限:确保目标文件或目录的权限允许当前用户或特权用户进行操作。
  3. 验证SSH连接:如果问题与SSH连接有关,确保SSH密钥正确配置,并且目标主机的known_hosts文件中包含正确的主机信息。