Ansible - kubernetes 插件不会更改集群上下文

Ron*_*tel 3 ansible kubernetes ansible-inventory azure-aks

库存文件(inventory/k8s.yaml):

plugin: kubernetes.core.k8s
connections:
  - kubeconfig: ~/.kube/config
    context: 'cluster-2'
Run Code Online (Sandbox Code Playgroud)

任务文件(roles/common/tasks/main.yaml):

# Method 1: Using `kubernetes.core` plugin to list the pod names:
- name: Get a list of all pods from any namespace
  kubernetes.core.k8s_info:
    kind: Pod
  register: pod_list
- name: Print pod names
  debug:
    msg: "pod_list: {{ pod_list | json_query('resources[*].metadata.name') }} "

# Method 2: Using `shell` command to list the pod names:
- name: Get node names
  shell: kubectl get pods
  register: pod_list2
- name: Print pod names
  debug:
    msg: "{{ pod_list2.stdout }}"
Run Code Online (Sandbox Code Playgroud)

Ansible 配置(ansible.cfg):

[inventory]
enable_plugins = host_list, auto, yaml, ini, kubernetes.core.k8s
Run Code Online (Sandbox Code Playgroud)

主文件(main.yaml):

---
- hosts: localhost
  gather_facts: false
  collections:
    - azure.azcollection
    - kubernetes.core
  roles:
    - "common"
Run Code Online (Sandbox Code Playgroud)

运行命令来执行任务:ansible-playbook main.yaml -i cluster-2/k8s.yaml -e role=common -e cluster_name=cluster-2

问题:我正在运行上述配置来从清单文件中提到的远程集群获取 Pod。但是,问题是,我仍然从本地集群获取 Pod 名称,而不是方法 1 和 2 中的 cluster-2。

k8s 插件应该从 cluster-2 获取 pod 列表,如清单文件中所述。如何连接远程 kubernetes 集群?

我还用以下命令检查了输出-vvvv

ansible-playbook [core 2.14.0]
config file = /Users/test/u/apps/ansible.cfg
configured module search path = ['/Users/test/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /Users/test/Library/Python/3.9/lib/python/site-packages/ansible
ansible collection location = /Users/test/.ansible/collections:/usr/share/ansible/collections
executable location = /Users/test/Library/Python/3.9/bin/ansible-playbook
python version = 3.9.12 (main, Mar 26 2022, 15:52:10) [Clang 13.0.0 (clang-1300.0.29.30)] (/usr/local/opt/python@3.9/bin/python3.9)
jinja version = 3.1.2
libyaml = True
Using /Users/test/u/apps/ansible.cfg as config file
setting up inventory plugins
Loading collection kubernetes.core from /Users/test/.ansible/collections/ansible_collections/kubernetes/core
Run Code Online (Sandbox Code Playgroud)

lar*_*sks 6

您尝试同时使用 kubernetes inventory 插件模块k8s_info,因此您会得到相互冲突的结果。两者没有任何关系。

库存模块

我认为 kubernetes inventory 模块是一个奇怪的野兽;它会生成一个 ansible 清单,其中集群中的 pod 呈现为 Ansible 主机。要查看集群中所有 Pod 名称的列表,您可以编写如下剧本:

- hosts: all
  gather_facts: false
  tasks:
  - name: Print pod names
    debug:
      msg: "{{ inventory_hostname }}"
Run Code Online (Sandbox Code Playgroud)

这将尊重您在 kubernetes inventory 插件配置中配置的上下文。例如,如果我有inventory/k8s.yaml以下内容:

plugin: kubernetes.core.k8s
connections:
  - kubeconfig: ./kubeconfig
    context: 'kind-cluster2'
Run Code Online (Sandbox Code Playgroud)

kind-cluster2然后,无论current-context我的文件中的设置如何,上面的剧本都会列出来自 的 pod 名称kubeconfig。在我的测试环境中,这会产生:

PLAY [all] *********************************************************************

TASK [Print pod names] *********************************************************
ok: [kubernetes] => {
    "msg": "kubernetes"
}
ok: [coredns-565d847f94-2shl6_coredns] => {
    "msg": "coredns-565d847f94-2shl6_coredns"
}
ok: [coredns-565d847f94-md57c_coredns] => {
    "msg": "coredns-565d847f94-md57c_coredns"
}
ok: [kube-dns] => {
    "msg": "kube-dns"
}
ok: [etcd-cluster2-control-plane_etcd] => {
    "msg": "etcd-cluster2-control-plane_etcd"
}
ok: [kube-apiserver-cluster2-control-plane_kube-apiserver] => {
    "msg": "kube-apiserver-cluster2-control-plane_kube-apiserver"
}
ok: [kube-controller-manager-cluster2-control-plane_kube-controller-manager] => {
    "msg": "kube-controller-manager-cluster2-control-plane_kube-controller-manager"
}
ok: [kube-scheduler-cluster2-control-plane_kube-scheduler] => {
    "msg": "kube-scheduler-cluster2-control-plane_kube-scheduler"
}
ok: [kindnet-nc27b_kindnet-cni] => {
    "msg": "kindnet-nc27b_kindnet-cni"
}
ok: [kube-proxy-9chgt_kube-proxy] => {
    "msg": "kube-proxy-9chgt_kube-proxy"
}
ok: [local-path-provisioner-684f458cdd-925v5_local-path-provisioner] => {
    "msg": "local-path-provisioner-684f458cdd-925v5_local-path-provisioner"
}

PLAY RECAP *********************************************************************
coredns-565d847f94-2shl6_coredns : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
coredns-565d847f94-md57c_coredns : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
etcd-cluster2-control-plane_etcd : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
kindnet-nc27b_kindnet-cni  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
kube-apiserver-cluster2-control-plane_kube-apiserver : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
kube-controller-manager-cluster2-control-plane_kube-controller-manager : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
kube-dns                   : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
kube-proxy-9chgt_kube-proxy : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
kube-scheduler-cluster2-control-plane_kube-scheduler : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
kubernetes                 : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
local-path-provisioner-684f458cdd-925v5_local-path-provisioner : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Run Code Online (Sandbox Code Playgroud)

这里的关键点是您的库存将包含 Pod 列表。我从来没有发现这特别有用。

k8s_info模块

查询k8s_infokubernetes 集群中的对象列表。它不关心你的库存配置——它将在你为你的游戏定义的任何目标主机上运行(可能localhost),并执行大致相当于kubectl get <whatever>. 如果您想使用显式上下文,则需要将其设置为模块参数的一部分。例如,要查看 中的 pod 列表kind-cluster2,我可以使用以下 playbook:

- hosts: localhost
  gather_facts: false
  tasks:
    - kubernetes.core.k8s_info:
        kind: pod
        kubeconfig: ./kubeconfig
        context: kind-cluster2
      register: pods

    - debug:
        msg: "{{ pods.resources | json_query('[].metadata.name') }}"
Run Code Online (Sandbox Code Playgroud)

在我的测试环境中产生输出:

PLAY [localhost] ***************************************************************

TASK [kubernetes.core.k8s_info] ************************************************
ok: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": [
        "coredns-565d847f94-2shl6",
        "coredns-565d847f94-md57c",
        "etcd-cluster2-control-plane",
        "kindnet-nc27b",
        "kube-apiserver-cluster2-control-plane",
        "kube-controller-manager-cluster2-control-plane",
        "kube-proxy-9chgt",
        "kube-scheduler-cluster2-control-plane",
        "local-path-provisioner-684f458cdd-925v5"
    ]
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
Run Code Online (Sandbox Code Playgroud)

总之:您可能想要使用k8s_info而不是库存插件,并且您需要在调用模块时通过设置context(可能还有)参数来正确配置模块。kubeconfig


如果我使用 k8s_info 模块,有什么方法可以在任务之外(全局)定义上下文和 kubeconfig 吗?

根据文档,如果您想全局配置模块的设置,您可以设置K8S_AUTH_KUBECONFIG和环境变量。你也可以这样写你的任务:K8S_AUTH_CONTEXTk8s_info

    - kubernetes.core.k8s_info:
        kind: pod
        kubeconfig: "{{ k8s_kubeconfig }}"
        context: "{{ k8s_context }}"
      register: pods
Run Code Online (Sandbox Code Playgroud)

然后在 Ansible 配置中的其他位置定义k8s_kubeconfig和变量(例如,作为组变量)。k8s_context这使得只需进行一次更改就可以轻松地将事物重新定位到不同的集群。