通过容器解决 Ansible 版本兼容性问题

通过容器解决 Ansible 版本兼容性问题

Ansible 和 Python 之前存储版本依赖,不同版本的 Python 支持的 Ansible 版本不一样。

https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-control-node-python-support

https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-target-node-python-support

AnsiblePython 版本不兼容导致执行失败的问题,比方说 Ansible 版本为 3.18.2,被控节点 Python 分别为 3.12.03.6.8,对 3.6.8 Python 版本的被控节点执行任务时会有 Python 报错导致任务执行失败,为了解决这个问题,Ansible 提出了通过容器执行 Ansible 任务的方式。

Ansible container environments

Ansible 执行环境演示

假设有两台服务器:

[root@study ansible]# ansible all --list-hosts
  hosts (2):
    servera
    serverb

这两台服务器的 python 版本不一致,其中 servera 为当前 Ansible 控制节点:

[root@study ansible]# ansible --version
ansible [core 2.18.2]
  config file = /root/ansible1/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/python/lib/python3.12/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/python/bin/ansible
  python version = 3.12.0 (main, Oct  8 2023, 15:41:59) [GCC 8.5.0 20210514 (Red Hat 8.5.0-18)] (/usr/local/python/bin/python3.12)
  jinja version = 3.1.2
  libyaml = True
[root@study ansible]# ssh servera
root@servera's password:
Activate the web console with: systemctl enable --now cockpit.socket

Last login: Sun Feb  9 16:52:29 2025 from 10.0.164.64
[root@localhost ~]# python3 --version
Python 3.6.8
[root@localhost ~]# python
python3                                       python3.6m                                    python-argcomplete-tcsh
python3.6                                     python-argcomplete-check-easy-install-script
  • Ansible 的 版本为 2.18.2
  • servera 的 Python 版本为 3.12.0
  • serverb 的 Python 版本为 3.6.8

执行 ansible 命令测试:

[root@study ansible]# ansible servera -m ping
[WARNING]: Platform linux on host servera is using the discovered Python interpreter at /usr/local/python/bin/python3.12, but future installation of another Python
interpreter could change the meaning of that path. See https://docs.ansible.com/ansible-core/2.18/reference_appendices/interpreter_discovery.html for more
information.
servera | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/local/python/bin/python3.12"
    },
    "changed": false,
    "ping": "pong"
}
[root@study ansible]# ansible serverb -m ping
[WARNING]: Unhandled error in Python interpreter discovery for host serverb: Expecting value: line 1 column 1 (char 0)
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: SyntaxError: future feature annotations is not defined
[WARNING]: Platform linux on host serverb is using the discovered Python interpreter at /usr/bin/python3, but future installation of another Python interpreter could
change the meaning of that path. See https://docs.ansible.com/ansible-core/2.18/reference_appendices/interpreter_discovery.html for more information.
serverb | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "module_stderr": "Shared connection to serverb closed.\r\n",
    "module_stdout": "Traceback (most recent call last):\r\n  File \"/root/.ansible/tmp/ansible-tmp-1739091843.7380877-172497-249791526669330/AnsiballZ_ping.py\", line 107, in <module>\r\n    _ansiballz_main()\r\n  File \"/root/.ansible/tmp/ansible-tmp-1739091843.7380877-172497-249791526669330/AnsiballZ_ping.py\", line 99, in _ansiballz_main\r\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\r\n  File \"/root/.ansible/tmp/ansible-tmp-1739091843.7380877-172497-249791526669330/AnsiballZ_ping.py\", line 44, in invoke_module\r\n    from ansible.module_utils import basic\r\n  File \"<frozen importlib._bootstrap>\", line 971, in _find_and_load\r\n  File \"<frozen importlib._bootstrap>\", line 951, in _find_and_load_unlocked\r\n  File \"<frozen importlib._bootstrap>\", line 894, in _find_spec\r\n  File \"<frozen importlib._bootstrap_external>\", line 1157, in find_spec\r\n  File \"<frozen importlib._bootstrap_external>\", line 1131, in _get_spec\r\n  File \"<frozen importlib._bootstrap_external>\", line 1112, in _legacy_get_spec\r\n  File \"<frozen importlib._bootstrap>\", line 441, in spec_from_loader\r\n  File \"<frozen importlib._bootstrap_external>\", line 544, in spec_from_file_location\r\n  File \"/tmp/ansible_ping_payload_3__qh04p/ansible_ping_payload.zip/ansible/module_utils/basic.py\", line 5\r\nSyntaxError: future feature annotations is not defined\r\n",
    "msg": "MODULE FAILURE: No start of json char found\nSee stdout/stderr for the exact error",
    "rc": 1
}

可以看到 serverb 执行失败了,因为 Python 版本太低了。

制作了一个 Ansible 的容器执行环境:

[root@study ansible]# podman images
REPOSITORY                     TAG         IMAGE ID      CREATED         SIZE
localhost/ansible_ee_rocky     8.10        516702fcfaf2  32 minutes ago  364 MB

检查容器执行环境的版本:

[root@study ansible]# ansible-navigator exec -- ansible --version
ansible [core 2.15.13]
  config file = /root/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.9/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.9.20 (main, Oct 23 2024, 13:02:27) [GCC 8.5.0 20210514 (Red Hat 8.5.0-22)] (/usr/bin/python3)
  jinja version = 3.1.5
  libyaml = True

可以看到容器内执行环境的 Ansible 版本为 2.15.13,Python 版本为 3.9.20。

使用容器执行环境执行命令测试:

[root@study ansible]# ansible-navigator exec -- ansible servera -m ping
servera | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
[root@study ansible]# ansible-navigator exec -- ansible serverb -m ping
serverb | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}

可以看到这样能够执行了,所以针对多种系统版本的环境时,可以通过容器执行环境来规避版本兼容性的问题,而且可以针对不同的 Ansible 集合制作容器执行环境,便于不同模式的管理,比方说一个容器执行环境用于系统初始化,安装系统初始化使用的模块,另一个容器执行环境安装 Ldap 集合,用于 Ldap 的管理。

配置 Ansible 容器执行环境

安装 Ansible 容器执行环境

配置 Ansible 执行环境需要安装 ansible-navigator 和容器环境,如果是 RHEL 系统且有 RHEL 订阅,都会有相应的 RPM 包,如果是开源环境,ansible-navigator 可以用 pip 安装,容器环境可以使用 podmandocker

因为是通过容器执行,所以需要容器镜像,开源的 ansible-navigator 默认使用的镜像是 ghcr.io/ansible/community-ansible-dev-tools:latest

# 安装 ansible-navigator
[root@ansible-controller ~]# python3 -m pip install ansible-navigator

# 安装容器环境
[root@ansible-controller ~]# dnf install podman

# 测试
[root@ansible-controller ~]# cd ansible-navigator/
[root@ansible-controller ansible-navigator]# ansible-navigator welcome
-------------------------------------------------------------------------------------
Execution environment image and pull policy overview
-------------------------------------------------------------------------------------
Execution environment image name:     ghcr.io/ansible/community-ansible-dev-tools:latest
Execution environment image tag:      latest
Execution environment pull arguments: None
Execution environment pull policy:    tag
Execution environment pull needed:    True
-------------------------------------------------------------------------------------
Updating the execution environment
-------------------------------------------------------------------------------------
Running the command: podman pull ghcr.io/ansible/community-ansible-dev-tools:latest
Trying to pull ghcr.io/ansible/community-ansible-dev-tools:latest...

# 执行 ansible-navigator welcome 会出现一个交互页面,页面如下
 0│Welcome
 1│————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
 2│
 3│Some things you can try from here:
 4│- :collections                                    Explore available collections
 5│- :config                                         Explore the current ansible configuration
 6│- :doc <plugin>                                   Review documentation for a module or plugin
 7│- :help                                           Show the main help page
 8│- :images                                         Explore execution environment images
 9│- :inventory -i <inventory>                       Explore an inventory
10│- :log                                            Review the application log
11│- :lint <file or directory>                       Lint Ansible/YAML files (experimental)
12│- :open                                           Open current page in the editor
13│- :replay                                         Explore a previous run using a playbook artifact
14│- :run <playbook> -i <inventory>                  Run a playbook in interactive mode
15│- :settings                                       Review the current ansible-navigator settings
16│- :quit                                           Quit the application
17│
18│happy automating,
19│
20│-winston

在上边这个交互页面下,输入 :collections 可以查看可使用的集合(就像 VIM 时输入 :wq 保存文件一样)。

ansible-navigator 更详细的使用后边再写。

通过容器来执行 Ansible 任务

  • --pp 设置镜像拉取策略
  • --eei 设置使用什么容器镜像
[root@ansible-controller ~]# mkdir ansible-navigator/
[root@ansible-controller ~]# cd ansible-navigator/
[root@ansible-controller ansible-navigator]# ansible-navigator exec --pp missing --eei quay.io/ansible/awx-ee:24.6.1 -- ansible --version
ansible [core 2.15.12]
  config file = /root/ansible-navigator/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.9/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.9.19 (main, Jun 11 2024, 00:00:00) [GCC 11.4.1 20231218 (Red Hat 11.4.1-3)] (/usr/bin/python3)
  jinja version = 3.1.4
  libyaml = True

# 准备配置文件和主机清单用于测试
[root@ansible-controller ansible-navigator]# cat ansible.cfg
[defaults]
inventory=./inventory
host_key_checking=False
[root@ansible-controller ansible-navigator]# cat inventory
master1 ansible_ssh_host=192.168.221.142 HOSTNAME=master1.example.com
worker1 ansible_ssh_host=192.168.221.143 HOSTNAME=worker1.example.com

[all:vars]
ansible_ssh_user=ansible
ansible_ssh_password=redhat

被控节点系统为 Rocky 8.10Python 版本为 3.6.8

ansible-navigator 执行任务有两种方式:

  • 通过 exec 选项执行 Ansible Ad-Hoc
  • 通过 run 选项执行 Ansible Playbook

通过容器执行 Ansible Ad-Hoc

  • -m stdout 设置输出模式为非交互模式
[root@ansible-controller ansible-navigator]# ansible-navigator exec --pp missing --eei quay.io/ansible/awx-ee:24.6.1 -- 'ansible all -m command -a "python3 --version"'
worker1 | CHANGED | rc=0 >>
Python 3.6.8
master1 | CHANGED | rc=0 >>
Python 3.6.8

通过容器执行 Playbook

  • -m stdout 设置输出模式为非交互模式
[root@ansible-controller ansible-navigator]# ansible-navigator --pp missing --eei quay.io/ansible/awx-ee:24.6.1 -m stdout run test.yml

PLAY [Ansible-navigator test!] *************************************************

TASK [Gathering Facts] *********************************************************
ok: [master1]
ok: [worker1]

TASK [Print Hello World!] ******************************************************
ok: [master1] => {
    "msg": "Hello World!"
}
ok: [worker1] => {
    "msg": "Hello World!"
}

PLAY RECAP *********************************************************************
master1                    : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
worker1                    : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
通过容器解决 Ansible 版本兼容性问题
https://www.linuxstudynotes.com/2025/05/25/ansible/%e9%80%9a%e8%bf%87%e5%ae%b9%e5%99%a8%e8%a7%a3%e5%86%b3-ansible-%e7%89%88%e6%9c%ac%e5%85%bc%e5%ae%b9%e6%80%a7%e9%97%ae%e9%a2%98/
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇