Ansible基础 ansible入门 针对不同python3版本 - 含 Terraform 入门联动

Ansible 自动化多版本管理-针对不同python3版本(含 Terraform 入门联动)

这是一篇迟来的总结。在经历了与两台云服务器的艰苦"搏斗"后,我终于让 Ansible 成功问候了它们。本文记录了我踩过的坑、背后的原理,以及如何让 Ansible 与 Terraform 优雅配合,成为基础设施即代码(IaC)的黄金搭档。

目录

  1. 背景:混合环境下的自动化需求
  2. 环境描述与拓扑
  3. [Ansible 初安装:看似美好,实则暗礁](#Ansible 初安装:看似美好,实则暗礁)
  4. [主机清单配置与免密 SSH](#主机清单配置与免密 SSH)
  5. 第一道坎:ModuleNotFoundError
    • 表象与误导
    • 根本原因:控制节点 Ansible 版本过旧
    • 升级 Ansible 的正确姿势
  6. 第二道坎:SyntaxError
    • 版本升级后的新问题
    • Python 3 版本兼容性黑洞
    • 解决方案:统一解释器版本
  7. 生产环境其他常见故障速览
  8. [Ansible + Terraform:迈向真正的基础设施即代码](#Ansible + Terraform:迈向真正的基础设施即代码)
    • Terraform 创建资源,Ansible 配置系统
    • 动态清单实战:让 Terraform 输出直接驱动 Ansible
  9. 总结:一条稳定的自动化管理链路

一、背景:混合环境下的自动化需求

在实际工作中,我们常常需要同时管理不同操作系统、不同 Python 版本的云服务器。手工逐个登录配置不仅效率低下,还容易出错。Ansible 作为无代理(agentless)的自动化工具,只需 SSH 和 Python 就能完成批量管理,是我选择它的核心理由。

我的目标很简单:一台 Ubuntu 22.04 虚拟机作为控制节点,同时管理两台云服务器(一台旧版 CentOS 7,一台全新 Ubuntu 24.04),实现免密 SSH 并执行 ansible all -m ping 全部返回 pong

后续,我们还将引入 Terraform 来声明式创建基础设施,并与 Ansible 配合,形成完整的 IaC 工作流。

二、环境描述与拓扑

主机名 角色 公网IP(脱敏示例) 操作系统 Python 版本
control-node Ansible 控制节点 内网 VM,无公网 Ubuntu 22.04 Python 3.10
cloud-server-a 被管节点 1.2.3.4 CentOS 7 系统自带 Python 2.7 / Python 3.6.8
cloud-server-b 被管节点 5.6.7.8 Ubuntu 24.04 Python 3.12

所有被管节点已开启 SSH(端口 22),且控制节点能通过互联网访问它们的公网 IP。

三、Ansible 初安装:看似美好,实则暗礁

在 Ubuntu 22.04 上,我习惯性地使用 apt 安装 Ansible:

bash 复制代码
sudo apt update
sudo apt install ansible -y

安装结束后,验证版本:

bash 复制代码
ansible --version
# ansible [core 2.10.8]

此时版本为 2.10.8。我心里还想:官方源出来的,应该稳了吧?但后面的连环故障证明这个想法太天真了。

四、主机清单配置与免密 SSH

首先打通控制节点到两台服务器的 SSH 免密:

bash 复制代码
ssh-keygen -t rsa -b 4096
ssh-copy-id root@1.2.3.4
ssh-copy-id root@5.6.7.8

然后创建 Ansible 主机清单文件 /etc/ansible/hosts

ini 复制代码
[web_servers]
cloud-server-a ansible_host=1.2.3.4
cloud-server-b ansible_host=5.6.7.8

[web_servers:vars]
ansible_user=root

清单配置无误后,执行排查命令:

bash 复制代码
ansible all -m ping

结果立刻出现了报错。

五、第一道坎:ModuleNotFoundError

cloud-server-b 返回错误:

复制代码
ModuleNotFoundError: No module named 'ansible.module_utils.six.moves'

cloud-server-a 却 ping 成功了。一种常见的误导是:认为目标节点缺少 python3-six 包。于是我登录 cloud-server-b 手动安装:

bash 复制代码
apt install python3-six -y

却发现它已是最新版,错误依旧。

根本原因:控制节点 Ansible 版本过旧

深入分析错误栈:Ansible 在目标节点执行模块时,将控制节点的 module_utils 代码打包传输并运行。旧版 Ansible(2.10.x)的模块代码依赖 Python 3.5/3.6 时代的内部 six 路径机制,而 Ubuntu 24.04 自带的 Python 3.12 已不再兼容。

结论:问题不在目标节点,而在控制节点的 Ansible 版本。需要将 Ansible 升级到至少 2.16 以上版本,才能原生支持 Python 3.12。

升级 Ansible 的正确姿势

使用 Ansible 官方 PPA 源进行升级:

bash 复制代码
sudo apt-add-repository ppa:ansible/ansible -y
sudo apt update
sudo apt install ansible -y

过程中若遇到老版本文件冲突(如 ansible-core 覆盖 /usr/bin/ansible),可用 dpkg --force-overwrite 或彻底清理旧包解决。最终版本提升到 ansible-core 2.17.14

bash 复制代码
ansible --version
# ansible [core 2.17.14]

再次执行 ansible all -m pingcloud-server-b 终于成功:

json 复制代码
cloud-server-b | SUCCESS => {
    "ping": "pong"
}

cloud-server-a 却又爆出新错误。

六、第二道坎:SyntaxError

复制代码
cloud-server-a | FAILED! => {
    "module_stdout": "...SyntaxError: future feature annotations is not defined"
}

版本升级后的新问题

看起来是新版 Ansible 的模块代码里用了 from __future__ import annotations 语法,这要求 Python 3.7+,而 cloud-server-a 的默认 Python 3 解释器竟然是 Python 3.6.8(CentOS 7 自带)。

Python 3 版本兼容性黑洞

两个节点一个太新一个太旧,导致同一个控制端无法同时兼容:

主机 Python 版本 兼容 Ansible 2.17?
cloud-server-a (CentOS 7) 3.6.8 ❌ 需 Python ≥3.7
cloud-server-b (Ubuntu 24.04) 3.12

解决方案:统一解释器版本

方案A :让 cloud-server-a 使用 Python 2.7,因旧版 Ansible 模块在 Python 2 下可正常运行。

在主机清单中显式指定解释器:

ini 复制代码
cloud-server-a ansible_host=1.2.3.4 ansible_python_interpreter=/usr/bin/python2

一试即通。但 Python 2 已退休,不适合长期维护。

方案B (推荐):在 cloud-server-a 上安装更高版本的 Python 3,并更新软链接。实际操作:

bash 复制代码
# 在 cloud-server-a 上安装 Python 3.8(来自 SCL 源)
yum install -y centos-release-scl
yum install -y rh-python38
# 将旧 python3 移走,创建新软链接指向 3.8
mv /usr/bin/python3 /usr/bin/python36_backup
ln -s /opt/rh/rh-python38/root/usr/bin/python3.8 /usr/bin/python3

之后无需在清单中指定解释器,让 Ansible 自动发现即可。双节点最终全部 ping 通。

七、生产环境其他常见故障速览

  1. SSH 密钥权限错误
    ~/.ssh/id_rsa 权限要 600,~/.ssh目录要 700,否则 Ansible 会拒绝读取。

  2. 目标节点 Python 未安装或路径不一致

    可通过 ansible_python_interpreter 在清单中统一路径,或提前通过 raw 模块安装 Python。

  3. 云安全组/防火墙未开放 22 端口

    导致连接受阻,表现为 Connection refused 或超时。

  4. SELinux 或 AppArmor 限制

    可能阻止 Ansible 在目标节点创建临时目录,可通过 semanage 或修改策略解决。

  5. Ansible 控制节点 DNS 解析异常

    在虚拟化 NAT 模式下尤其常见,需正确配置 /etc/resolv.confsystemd-resolved

八、Ansible + Terraform:迈向真正的基础设施即代码

仅用 Ansible 管理现有机器是"配置管理",要形成完整的 IaC ,还需要 Terraform 负责资源的创建与销毁,Ansible 负责系统配置。

Terraform 创建资源,Ansible 配置系统

以腾讯云为例,Terraform 可以声明两台云服务器:

复制代码
resource "tencentcloud_instance" "web" {
  count = 2
  image_id    = "img-..."
  instance_type = "S5.MEDIUM2"
  ...
}

资源创建后,Terraform 可以输出这些实例的公网 IP:

复制代码
output "instance_ips" {
  value = tencentcloud_instance.web[*].public_ip
}

随后,我们可以将输出的 IP 列表交给 Ansible 动态清单。

动态清单实战:让 Terraform 输出直接驱动 Ansible

编写一个简单的脚本 inventory.sh,调用 terraform output -json 并解析生成 Ansible 所需的 JSON 格式:

json 复制代码
{
  "web_servers": {
    "hosts": ["1.2.3.4", "5.6.7.8"],
    "vars": { "ansible_user": "root" }
  }
}

然后在 Ansible 命令中使用它:

bash 复制代码
ansible-playbook -i inventory.sh site.yml

这样,每次 terraform apply 创建新资源后,Ansible 可以无缝接管配置,实现从"点到点"到"生产级流水线"的跃升。

九、总结:一条稳定的自动化管理链路

本文通过真实案例,揭示了 Ansible 在生产中常见的版本兼容性陷阱Python 环境差异问题。核心经验:

  • 控制节点 Ansible 版本需与目标节点的 Python 版本匹配,建议 Ansible ≥ 2.16
  • 混合 OS 环境统一 Python 解释器(如都使用 Python 3.8+)是最佳实践;
  • 基础设施即代码应结合 Terraform 与 Ansible,前者管资源,后者管配置,各自发挥长处。

下次再搭建 Ansible 控制节点时,不妨直接用官方 PPA 安装最新版;接到目标机器后,先确认 python3 --version,省去一堆弯路。

自动化之路,坑不少,但趟平之后便是快速、可靠、可复制的运维体验。

相关推荐
宵时待雨1 小时前
linux笔记归纳4:进程概念
linux·运维·服务器·c++·笔记
leoZ2312 小时前
Linux 环境常用服务一键部署文档(Docker 版)
运维·docker·容器
落魄实习生2 小时前
Jenkins安装及使用
运维·jenkins
QuestLab2 小时前
让AI真正“看见“界面:纯视觉GUI自动化编排器开源了
运维·人工智能·自动化
怿星科技2 小时前
怿星科技助力极氪汽车打造ZEEA 3.0智能座舱冒烟测试“自动化验证中枢”
科技·自动化·汽车
imuliuliang3 小时前
五大编程语言核心对比:特性与应用全解析
运维·spring boot·nginx
Agent产品评测局3 小时前
制造业考勤智能管理系统,主流AI Agent方案横评:2026年企业级自动化选型深度指南
运维·人工智能·ai·chatgpt·自动化
bukeyiwanshui3 小时前
20260509 docker项目总结
运维·docker·容器
玄尺3 小时前
jenkins安装和使用
运维·jenkins