问题描述

在尝试使用Ansible的k8s模块创建一个名为“example”的命名空间时,可能会遇到“401 Unauthorized”错误。这种错误通常发生在尝试对Kubernetes (K8s) 或 OpenShift (OCP) 集群执行操作时,但未提供有效的认证令牌。此问题通常与Kubernetes或OpenShift的认证机制有关,而非Ansible Playbook或Ansible配置。

错误复现

以下是一个Ansible Playbook示例,用于复现“401 Unauthorized”错误:

文件:namespace.yml

---
- name: k8s demo
  hosts: localhost
  gather_facts: false
  connection: local
  vars:
    myproject: "example"
  tasks:
    - name: create {{ myproject }} namespace
      kubernetes.core.k8s:
        api_version: v1
        kind: Namespace
        name: "{{ myproject }}"
        state: present

错误执行

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

$ ansible-playbook kubernetes/namespace.yml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [k8s demo] **************************************************

TASK [create example namespace] **********************************
fatal: [localhost]: FAILED! => {"changed": false, "error": 401, "msg": "Namespace example: Failed to retrieve requested object: b'{\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Unauthorized\",\"reason\":\"Unauthorized\",\"code\":401}'", "reason": "Unauthorized", "status": 401}
PLAY RECAP ********************************************************
localhost                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

排查与修复

  1. 检查集群认证状态: 运行以下命令检查是否已登录到集群:

bash $ oc get namespace error: You must be logged in to the server (Unauthorized)

  1. 启动并登录集群: 如果使用CodeReady Containers (CRC),确保集群已启动并登录:

```bash $ crc status CRC VM: Running OpenShift: Running (v4.9.15) Disk Usage: 18.27GB of 32.74GB (Inside the CRC VM) Cache Usage: 12.79GB Cache Directory: /Users/lberton/.crc/cache

$ crc start INFO A CodeReady Containers VM for OpenShift 4.9.15 is already running Started the OpenShift cluster. ```

  1. 登录集群: 使用管理员或开发人员账户登录集群:

bash $ eval $(crc oc-env) $ oc login -u kubeadmin https://api.crc.testing:6443 Logged into "https://api.crc.testing:6443" as "kubeadmin" using existing credentials.

  1. 检查当前上下文: 确保当前上下文已切换到正确的命名空间:

```bash $ oc get namespace | grep example example Active 63d

$ cat ~/.kube/config # 确保配置文件中有正确的上下文和认证信息 ```

修复执行

重新运行Playbook,验证是否成功创建命名空间:

$ ansible-playbook kubernetes/namespace.yml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [k8s demo] **************************************************

TASK [create example namespace] **********************************
ok: [localhost]

PLAY RECAP ********************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

总结

  1. 确保集群已启动:使用crc status和crc start命令确保集群正在运行。
  2. 登录集群:使用oc login命令登录集群,并确保使用正确的用户名和URL。
  3. 检查Kube配置文件:确保~/.kube/config文件包含正确的认证信息和上下文。
  4. 重新运行Playbook:在完成上述步骤后,重新运行Playbook以验证问题是否解决。

通过以上步骤,您可以快速解决Ansible在Kubernetes或OpenShift集群中遇到的“401 Unauthorized”错误,并确保Playbook顺利执行。