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,省去一堆弯路。

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

相关推荐
我头发多我先学33 分钟前
linux系统编程:初识进程
linux·运维·服务器
东舟技术44 分钟前
AI全链路测试智能体上线啦!
人工智能·功能测试·测试工具·自动化
Tinyfacture1 小时前
接口自动化之添加商品(pytest)
python·测试工具·自动化·pytest
云飞云共享云桌面1 小时前
SolidWorks—天津智能装备工厂1台高配主机共享给10个研发用
运维·服务器·自动化·汽车·制造
苍狗T1 小时前
LVS相关知识总结
linux·运维·服务器·lvs
你有哈莫吗1 小时前
记一次 .NET 某自动化智能制造软件 卡死分析
自动化·.net·制造
各类产品分享2 小时前
什么是AR智慧运维系统,主要能解决什么问题
运维·ar·ar智慧运维解决方案
RisunJan3 小时前
Linux命令-skill(发送信号给进程)
linux·运维·服务器
潘正翔3 小时前
k8s基础_kubeadm搭建k8s集群
linux·运维·docker·云原生·容器·kubernetes
Echo flower3 小时前
Docker 容器中 Puppeteer 僵尸进程排查与修复
运维·docker·容器·puppeteer