白日依山尽,黄河入海流。欲穷千里目,更上一层楼。 -- 唐·王之涣

关于Python Ansible中 HOST_KEY_CHECKING不生效问题分析

今日赏花

背景

之前写过一个Python+Ansible 实现 程序执行 adhoc 和 playbook的功能,最近在开发运维平台的时候想直接把它拿过来复用,结果在新的环境执行的时候会因为主机没有添加到 know_hosts文件导致卡住,也就是说 Ansible的 constant 配置的 HOST_KEY_CHECKING=False 未生效

两个环境的的ansible版本是不一致的。所以问题出现在ansible或者ansible-core的版本上。

接下来通过试验来验证

Ansible版本说明

在试验之前,我们先对Ansible模块的版本进行说明

1、Ansible 版本 <= 2.9.9 时,只会安装一个模块

1
ansible                          2.9.9

2、Ansible 版本 >= 3.0.0 and <= 3.4.0 时,安装的时候,依赖 ansible-base 模块

1
2
ansible                          3.4.0
ansible-base 2.10.17

注意

3.4.0 再往上版本就是4.0.0了

3、Ansible 从 4.0.0 版本开始安装的时候,依赖 ansible-core 模块

1
2
ansible      4.0.0
ansible-core 2.11.12

具体的Ansible模块的版本列表详见 https://mirrors.aliyun.com/pypi/simple/ansible/

试验

试验用的脚本参考 test_ansible.py

1、这里对4.0.0以下版本版本,选择 2.9.9 和 3.4.0 两个版本为代表,进行试验,是没有问题的。可以证明 <= 3.4.0 版本的都没有问题

2、因为当前项目环境都是 ansible 4.0.0 以上的版本,所以重点验证

验证的方法是: 采用 Ansible 第二位 版本号升位,分别执行上述脚本。

这里需要说明的是:

如果当前版本验证成功的话,验证下一个版本,一定要换一个主机进行验证

原因:

1)验证成功的话肯定会在 know_hosts 文件添加对应的记录
2)这个时候即使手动删除 know_hosts 文件中对应的记录,假设下个版本本应该失败,但是也会成功, 应该是本身做了一些缓存(这里暂未研究缓存在哪里)

最终经过测试验证

key的检测是依赖于 ansible-core, 该模板的最高有效版本是 2.11.6, 而从下面获取的版本依赖记录 来看, ansible 4.10.0 最低支持 2.11.7, ansible 4.9.0 支持 2.11.6 到 2.12

版本依赖关系

1
2
3
4
5
ansible 4.10.0 requires ansible-core~=2.11.7, but you have ansible-core 2.12.7 which is incompatible.

ansible 4.9.0 requires ansible-core<2.12,>=2.11.6, but you have ansible-core 2.12.0 which is incompatible.

ansible 5.0.1 requires ansible-core<2.13,>=2.12.0, but you have ansible-core 2.11.6 which is incompatible.

所以正常安装之后默认的最高有效版本及依赖是 Ansible 4.9.0 + Ansible-core 2.11.6

扩展

根据上面的试验结论,最高有效版本是 Ansible 4.9.0 + Ansible-core 2.11.6, 难道就不能用最新的版本了吗?

当然不是 ~

我们通过ansible的源码分析(源码位置 site-packages/ansible/config/base.py)知道配置了很多的环境变量, ansible 常量 HOST_KEY_CHECKING 对应的envANSIBLE_HOST_KEY_CHECKING,对应的ini配置文件是 defaults section中的 host_key_checking

ansible-host-key-checking.png

那么我们就有一种更快速的解决该问题的办法,就是在执行 runner 之前通过os.environ.setdefault 来设置对应的环境变量

1
os.environ.setdefault('ANSIBLE_HOST_KEY_CHECKING', 'False')

再次验证,没有了要检测 know_hosts 文件的过程,程序顺利执行


如果觉得文章对你有所帮忙,欢迎点赞收藏,或者可以关注个人公众号 全栈运维

作者

Colin

发布于

2022-07-31

许可协议