问题描述

在Ansible中,urlopen错误通常是因为无法成功打开指定的URL。这可能是由于URL拼写错误、网络问题或目标服务器不可用等原因导致的。本文将介绍如何复现该错误、进行故障排除,并修复问题,以便成功在Ansible playbook中打开URL。

错误复现

以下是一个Ansible playbook示例,用于复现urlopen错误:

文件:urlopen_error.yml

---
- name: uri module demo
  hosts: all
  become: false
  vars:
    server: "https://reqres.it "  # 错误的URL
    endpoint: "/api/users?page=2"
  tasks:
    - name: list users
      ansible.builtin.uri:
        url: "{{ server }}{{ endpoint }}"
        method: GET
        status_code: 200
        timeout: 30
      register: result

    - name: debug
      ansible.builtin.debug:
        var: result.json.data

错误执行

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

$ ansible-playbook -i inventory urlopen_error.yml
PLAY [uri module demo] ******************************************
TASK [Gathering Facts] ******************************************
ok: [demo.example.com]
TASK [list users] ***********************************************
fatal: [demo.example.com]: FAILED! => {"changed": false, "elapsed": 15, "msg": "Status code was -1 and not [200]: Request failed: <urlopen error [Errno -2] Name or service not known>", "redirected": false, "status": -1, "url": "https://reqres.it/api/users?page=2"}
PLAY RECAP **********************************************
demo.example.com           : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

错误原因

  1. URL拼写错误:https://reqres.it 是一个拼写错误的URL,正确的URL应该是 https://reqres.in。
  2. 网络问题:目标服务器可能不可用,或者网络连接存在问题。
  3. DNS解析失败:可能是DNS解析失败导致无法访问目标URL。

解决方案

修复playbook中的URL拼写错误,并重新运行playbook。

文件:urlopen_fix.yml

---
- name: uri module demo
  hosts: all
  become: false
  vars:
    server: "https://reqres.in "  # 修复URL
    endpoint: "/api/users?page=2"
  tasks:
    - name: list users
      ansible.builtin.uri:
        url: "{{ server }}{{ endpoint }}"
        method: GET
        status_code: 200
        timeout: 30
      register: result

    - name: debug
      ansible.builtin.debug:
        var: result.json.data

修复执行

运行修复后的playbook:

$ ansible-playbook -i inventory urlopen_fix.yml
PLAY [uri module demo] ******************************************
TASK [Gathering Facts] ******************************************
ok: [demo.example.com]
TASK [list users] ***********************************************
ok: [demo.example.com]
TASK [debug] ********************************************
ok: [demo.example.com] => {
    "result.json.data": [
        {
            "avatar": "https://reqres.in/img/faces/7-image.jpg",
            "email": "michael.lawson@reqres.in",
            "first_name": "Michael",
            "id": 7,
            "last_name": "Lawson"
        },
        {
            "avatar": "https://reqres.in/img/faces/8-image.jpg",
            "email": "lindsay.ferguson@reqres.in",
            "first_name": "Lindsay",
            "id": 8,
            "last_name": "Ferguson"
        },
        {
            "avatar": "https://reqres.in/img/faces/9-image.jpg",
            "email": "tobias.funke@reqres.in",
            "first_name": "Tobias",
            "id": 9,
            "last_name": "Funke"
        },
        {
            "avatar": "https://reqres.in/img/faces/10-image.jpg",
            "email": "byron.fields@reqres.in",
            "first_name": "Byron",
            "id": 10,
            "last_name": "Fields"
        },
        {
            "avatar": "https://reqres.in/img/faces/11-image.jpg",
            "email": "george.edwards@reqres.in",
            "first_name": "George",
            "id": 11,
            "last_name": "Edwards"
        },
        {
            "avatar": "https://reqres.in/img/faces/12-image.jpg",
            "email": "rachel.howell@reqres.in",
            "first_name": "Rachel",
            "id": 12,
            "last_name": "Howell"
        }
    ]
}
PLAY RECAP **********************************************
demo.example.com           : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

总结

  1. 检查URL拼写:确保URL拼写正确,尤其是域名部分。
  2. 验证网络连接:确保目标服务器可访问,并且网络连接正常。
  3. 使用正确的状态码:确保目标API返回的HTTP状态码与playbook中指定的状态码一致。
  4. 调试日志:使用debug模块查看返回的数据,帮助定位问题。

通过以上步骤,您可以快速定位并解决urlopen错误,确保Ansible playbook能够成功执行。