最近给一批 openEuler 22.03 LTS SP4 的虚拟机搭自动化控制机,准备用 Ansible 统一管理。原以为装个 Ansible 就是一条 dnf install -y ansible 的事,结果在最小化安装的干净环境里敲下去,系统直接回了一句 No package ansible available。我第一反应是源没配好,但仔细看了 /etc/yum.repos.d/openEuler.repo,OS、源都正常,问题出在 openEuler 默认的 BaseOS 仓库里本来就不带 Ansible,需要额外启用 EPOL 仓库或者走 Python 环境安装。
如果你是刚在 VMware 里装好 openEuler,想在控制机上跑 Ansible 的运维新手,这篇可以直接“抄作业”。我会把安装之前的环境检查、软件源原理、两种安装方案、一键脚本、第一个 Playbook 实战,以及我踩过的坑全部整理出来。无论你的系统是 22.03 LTS 还是 24.03 LTS,只要跟着下面的思路走,大概率不会翻车。
1. openEuler 环境准备:装 Ansible 之前先把这几件事搞清楚
1.1 先别急着敲命令:确认你的 openEuler 版本和架构
很多人拿到机器就直接复制网上的安装命令,也不管自己的系统是哪个小版本、CPU 是什么架构。在 openEuler 上,这很容易踩到 404 和找不到包的坑。
先登录系统,执行下面两条命令:
bash复制cat /etc/os-release
uname -m
/etc/os-release 能看到系统版本,比如 PRETTY_NAME="openEuler 22.03 (LTS-SP4)",uname -m 决定你用的是 x86_64 还是 aarch64。这两项信息后面配置 EPOL 源的时候必须用到,因为 openEuler 软件仓库的路径格式是:
code复制https://repo.openeuler.org/openEuler-版本号/仓库目录/架构/
比如说 openEuler 22.03 LTS SP4 的 x86_64 架构,EPOL 完整路径就是:
code复制https://repo.openeuler.org/openEuler-22.03-LTS-SP4/EPOL/main/x86_64/
如果你在 VMware 里用默认模板安装,通常是 x86_64。如果是在树莓派或者 ARM 服务器上装的,就要把 url 里的 x86_64 手动改成 aarch64。网络上的教程大多默认 x86_64,新手在 ARM 机器上照抄,自然就装不上。
1.2 openEuler 默认软件源与 EPOL 的关系
先解释一个关键概念。openEuler 的软件仓库不是只有一个“源”,它分了几层:BaseOS、EPOL、update、debuginfo 等。平时执行 dnf install 默认只去启用的仓库里找软件包。
openEuler 的 BaseOS 仓库里放的是操作系统基础组件,比如 openssh、systemd、tar 这些。而 Ansible、Nginx、Docker 这类常见但非系统基础的软件,很多被放进了 EPOL,全称是 Extra Packages for openEuler,可以理解为 openEuler 的“扩展软件包仓”。
为什么 openEuler 出厂没有默认启用全部 EPOL?原因很简单,如果所有扩展包仓库默认启用,用户执行 dnf update 时可能要下载大量并不需要的软件包元数据,速度慢而且没意义。所以很多版本只是把仓库配置文件放好,或者需要你额外添加。
查看当前已经启用的仓库:
bash复制dnf repolist --enabled
如果能在结果里看到 openEulerEPOL-openEuler-22.03-LTS-SP4 之类的记录,说明 EPOL 已经启用。如果看不到,就需要继续看下面 2.1 节里的手动配置。
另一个常见疑问是“我要不要用 CentOS 的 EPEL 源”。答案是不建议混用。openEuler 虽然兼容 RHEL/CentOS 的一些包管理习惯,但软件包编译依赖、版本号都有差异,强行把 CentOS 的 EPEL 源加进来,轻则依赖冲突,重则把系统 Python 环境搞乱。openEuler 自己的 EPOL 已经覆盖了 Ansible,没必要舍近求远。
1.3 网络、时间同步和 Python 环境也要提前确认
安装 Ansible 之前,系统至少要有基本的网络连通能力。控制机需要能访问 repo.openeuler.org,否则无论 dnf 还是 pip 都没法下载。如果你在 VMware 里用了 NAT 模式,宿主机能上网的前提下,虚拟机默认也能访问外网,一般没问题。
时间同步也很关键。用 Ansible 连接被管理机器或者下载加密源时,如果系统时间和实际时间差太多,可能出现 HTTPS 证书验证失败、SSH 认证异常。最稳妥的做法是在安装之前把 chrony 启起来:
bash复制systemctl start chronyd
systemctl enable chronyd
如果没有安装 chrony,可以先用 dnf install -y chrony 装一下。
还要确认 python3 是否存在。Ansible 本身是基于 Python 开发的工具,虽然现在用 dnf 安装时系统会自动拉依赖,但如果你准备走 pip 路线,一个可用的 Python 环境是硬前提。在 openEuler 上执行:
bash复制python3 --version
如果提示 command not found,属于最小化安装时没装 Python,可以先用 dnf install -y python3 补上。下面的一键脚本里也会处理这个情况。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 保姆级实操:Ansible 在 openEuler 上一键安装全流程
2.1 方法一:通过 dnf 直接安装原生 Ansible
最优先推荐的方案是 dnf 安装。因为这样装出来的 Ansible 会直接和系统 Python 依赖、文件路径做好适配,后续卸载也方便。
理论上,如果你的系统已经启用了 EPOL,直接执行:
bash复制dnf update -y
dnf install -y ansible
然后确认版本:
bash复制ansible --version
如果看到类似 ansible [core 2.14.x] 的输出,说明已经装好了。
但我的实际经验是,很多 openEuler 干净环境下,EPOL 并没有启用。执行 dnf install -y ansible 会报 No package ansible available。这时候不要硬着头皮去搜 CentOS 的 EPEL 源,正确的做法是写一个 openEuler EPOL 仓库文件。
假设你的系统是 openEuler 22.03 LTS SP4,x86_64 架构,执行:
bash复制cat > /etc/yum.repos.d/openEuler_EPOL.repo <<EOF
[openEulerEPOL]
name=openEuler EPOL Repository
baseurl=https://repo.openeuler.org/openEuler-22.03-LTS-SP4/EPOL/main/x86_64/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-openEuler
EOF
dnf makecache
dnf install -y ansible
如果你是其他小版本,只需要把路径里的 22.03-LTS-SP4 替换成自己的版本,例如 openEuler 24.03 LTS 就换成 24.03-LTS,openEuler 22.03 LTS 普通版就换成 22.03-LTS。如果你不确定自己的版本适合什么路径,回到 1.1 节查看 /etc/os-release,但注意 os-release 里显示的是 PRETTY_NAME,仓库路径要用短格式,比如 22.03-LTS-SP4,不是 22.03 (LTS-SP4)。
配置仓库文件时有几个容易踩的细节。gpgcheck=1 会验证 RPM 包签名,如果看到 public key not available 的报错,可以先执行:
bash复制rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-openEuler
如果 /etc/pki/rpm-gpg 下没有这个 key 文件,可以把 gpgkey 改成官方在线地址:
code复制https://repo.openeuler.org/openEuler-22.03-LTS-SP4/EPOL/main/x86_64/RPM-GPG-KEY-openEuler
但这种方法依赖网络和路径准确度,本地 key 文件通常更可靠。
2.2 方法二:通过 Python venv 安装 Ansible(干净且通用)
如果你的 openEuler 版本太老、EPOL 仓库里怎么也找不到 Ansible,或者你不想为了一个工具去动系统源,我强烈建议用 Python venv 的方式安装。Ansible 本质上是一堆 Python 模块和命令行的集合,只要 Python 版本满足要求,pip 安装是最通用且干净的方式。
为什么要用 venv?因为直接 pip3 install ansible 会把依赖装进系统 Python 的 site-packages,可能覆盖 openEuler 自带的 cryptography、PyYAML 等底层库。一旦系统组件依赖的版本和你装的不兼容,重启后可能出现奇怪报错,甚至影响 dnf 的运行。venv 相当于在 /opt/ansible-venv 里隔离出一个独立的 Python 环境,Ansible 装在里面,和系统 Python 互不干扰。
在 openEuler 上执行:
bash复制# 安装 Python 虚拟环境和基础依赖
dnf install -y python3 python3-pip
# 创建虚拟环境
python3 -m venv /opt/ansible-venv
# 升级 pip
/opt/ansible-venv/bin/pip install --upgrade pip
# 安装 Ansible
/opt/ansible-venv/bin/pip install ansible
install 过程取决于网络,一般十几秒到几分钟。装完后,ansible 的可执行文件在 /opt/ansible-venv/bin/ 下,不会自动进入你的 PATH。为了方便在任意目录直接用 ansible 命令,建议做软链:
bash复制ln -sf /opt/ansible-venv/bin/ansible /usr/local/bin/ansible
ln -sf /opt/ansible-venv/bin/ansible-playbook /usr/local/bin/ansible-playbook
ln -sf /opt/ansible-venv/bin/ansible-galaxy /usr/local/bin/ansible-galaxy
ln -sf /opt/ansible-venv/bin/ansible-doc /usr/local/bin/ansible-doc
如果你不想做软链,也可以把虚拟环境目录加到 PATH 里:
bash复制echo 'export PATH=/opt/ansible-venv/bin:$PATH' > /etc/profile.d/ansible.sh
source /etc/profile.d/ansible.sh
两种方式选一种即可。我个人更倾向于软链,因为写法直观,而且只对四个 Ansible 命令生效,不会影响整个 PATH。
注意:venv 环境默认不激活时,ansible命令是通过软链访问/opt/ansible-venv/bin/ansible的,它会自动使用虚拟环境里的 Python。但如果你用python3去import ansible,仍然是系统 Python,不会看到 Ansible 模块。这不是 bug,是虚拟环境隔离的正常表现。如果你需要在脚本里调用 Ansible 的 Python API,记得用/opt/ansible-venv/bin/python。
2.3 一键安装脚本:把准备工作全部塞进一个文件
既然标题是“一键安装”,前面两条手动方案还是偏麻烦。我这里整理了一个可落地的脚本,它在运行时会判断系统版本、自动添加 EPOL 源、优先用 dnf 装,dnf 找不到再用 pip+venv。
bash复制#!/bin/bash
set -euo pipefail
# openEuler 下安装 Ansible 一键脚本
# 用法: bash install_ansible.sh
# 1. 检测系统
if ! grep -qi "openEuler" /etc/os-release; then
echo "当前系统不是 openEuler,脚本退出" >&2
exit 1
fi
# 2. 从系统自带的 repo 中尝试提取版本路径
OE_VERSION="22.03-LTS-SP4"
OFFICIAL_REPO="/etc/yum.repos.d/openEuler.repo"
if [ -f "$OFFICIAL_REPO" ]; then
REPO_VERSION=$(grep -E "baseurl=.*/openEuler-.*/OS/" "$OFFICIAL_REPO" | head -1 | sed -E 's#.*/openEuler-([^/]+)/OS/.*#\1#')
if [ -n "$REPO_VERSION" ]; then
OE_VERSION="$REPO_VERSION"
fi
fi
ARCH=$(uname -m)
echo "当前系统版本路径: openEuler-$OE_VERSION, 架构: $ARCH"
# 3. 确保基础软件
if ! command -v dnf >/dev/null 2>&1; then
echo "未检测到 dnf,无法继续安装" >&2
exit 1
fi
# 4. 如果启用仓库里没有 EPOL,就补充 EPOL 源
if ! dnf repolist --enabled | grep -qi openEulerEPOL; then
echo "EPOL 仓库未启用,开始配置..."
if [ -f /etc/yum.repos.d/openEuler_EPOL.repo ]; then
echo "检测到已有 EPOL repo 文件,先备份"
mv /etc/yum.repos.d/openEuler_EPOL.repo /etc/yum.repos.d/openEuler_EPOL.repo.bak.$(date +%Y%m%d%H%M%S)
fi
cat > /etc/yum.repos.d/openEuler_EPOL.repo <<EOF
[openEulerEPOL]
name=openEuler EPOL Repository
baseurl=https://repo.openeuler.org/openEuler-$OE_VERSION/EPOL/main/$ARCH/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-openEuler
EOF
dnf makecache
fi
# 5. 优先尝试 dnf 安装
if dnf list --available ansible >/dev/null 2>&1; then
echo "dnf 源中存在 Ansible,开始安装..."
dnf install -y ansible
echo "dnf 安装完成"
ansible --version
exit 0
fi
# 6. dnf 不可用时,使用 venv + pip
echo "dnf 源中暂未找到 Ansible,改用 Python venv 方案..."
dnf install -y python3 python3-pip
python3 -m venv /opt/ansible-venv
/opt/ansible-venv/bin/pip install --upgrade pip
/opt/ansible-venv/bin/pip install ansible
ln -sf /opt/ansible-venv/bin/ansible /usr/local/bin/ansible
ln -sf /opt/ansible-venv/bin/ansible-playbook /usr/local/bin/ansible-playbook
ln -sf /opt/ansible-venv/bin/ansible-galaxy /usr/local/bin/ansible-galaxy
ln -sf /opt/ansible-venv/bin/ansible-doc /usr/local/bin/ansible-doc
echo "venv+pip 安装完成"
ansible --version
把上面的内容保存成 install_ansible.sh,然后执行:
bash复制bash install_ansible.sh
脚本能自动从 /etc/yum.repos.d/openEuler.repo 里提取当前系统的实际版本路径,所以大多数正常安装的 openEuler 不需要手动改版本号。只有在你把系统的默认 repo 文件删除过、或者改过 baseurl 的情况下,才需要手动修改 OE_VERSION 变量。
我自己在 openEuler 22.03 LTS SP4 最小化环境里实测过这个脚本。EPOL 没有启用时,它会自动写入 repo 文件并 makecache,然后 dnf 安装。输出末尾能看到 ansible --version 显示的版本信息,全程大概需要两到三分钟,看网络速度。
脚本里有一行 set -euo pipefail,很多新手可能不熟。它的意思是脚本中任何一个命令执行出错,都会立即退出,避免后面继续运行产生连锁错误。u 代表变量未定义时报错,pipefail 表示管道里有命令失败也算失败。写一键脚本时这个开关能帮你避免“以为成功实际失败”的情况。
2.4 安装后第一时间确认版本和运行路径
不管用哪种方式装完,都要验证一下。执行:
bash复制which ansible
ansible --version
正常情况下输出包含版本号和 Python 路径。如果用的是 dnf 安装,ansible 可能位于 /usr/bin/ansible;如果用的是 venv+pip,soft link 之后的路径是 /usr/local/bin/ansible。
可以把两种安装方式的差异整理一下,方便决策:
| 安装方式 | 适用场景 | 优点 | 潜在问题 |
|---|---|---|---|
| dnf + EPOL | 大多数 openEuler 22.03/24.03 联网环境 | 依赖由系统管理,升级卸载方便 | EPOL 未启用时需要手动配置 |
| Python venv + pip | EPOL 没有包或不想动系统源 | 不污染系统 Python,版本比较新 | 需要自己管路径和软链 |
对绝大多数场景来说,推荐优先级是:dnf 方式 > venv+pip 方式。只有 dnf 确实装不上时才用 pip。
3. 从“装好”到“能用”:主机清单、免密登录与第一个 Playbook
3.1 创建 Ansible 工作目录和主机清单
Ansible 和很多单机软件不同,它是典型的控制端/被管端模式。你当前装的这台机器是控制端,理论上可以管理任意数量的 openEuler、CentOS 甚至 Windows 机器。但是要让它知道“管哪些机器”,必须先写主机清单。
我建议不要直接用系统默认的 /etc/ansible/hosts,因为你自己的配置混在系统配置里,管理起来乱。创建一个独立工作目录:
bash复制mkdir -p ~/ansible-demo
cd ~/ansible-demo
vim hosts
hosts 文件内容可以按分组规划,比如:
ini复制[openEuler_demo]
192.168.122.10
192.168.122.11
[openEuler_demo:vars]
ansible_user=root
第一行 [openEuler_demo] 是组名,下面每行一个被管节点的 IP 或主机名。:vars 代表这个组的公共变量,这里将登录用户统一为 root。
然后写一个最简单的 ansible.cfg,告诉 Ansible 默认读取当前目录的 hosts,并且关闭首次连接的主机指纹确认:
ini复制[defaults]
inventory = hosts
host_key_checking = False
host_key_checking = False 只建议在测试环境用。生产环境建议保持默认的 True,因为首次连接时它会提示确认目标主机指纹,防止中间人攻击。如果自动化任务太多,确认指纹很烦人,可以先把 known_hosts 预填好,而不是直接关闭检查。
工作目录里放 ansible.cfg 后,你在该目录执行的 ansible 命令会自动使用当前目录的配置,不需要每次加 -i hosts。
3.2 配置 SSH 免密登录
Ansible 通过 SSH 远程执行命令,最省事的登录方式是密钥免密。先在控制端生成密钥:
bash复制ssh-keygen -t ed25519 -C "ansible-demo"
一路回车即可,默认生成 ~/.ssh/id_ed25519。然后把公钥分发到被管节点:
bash复制ssh-copy-id root@192.168.122.10
ssh-copy-id root@192.168.122.11
执行过程中会让你输入目标机器 root 密码。如果 ssh-copy-id 没装,可以 dnf install -y openssh-clients。分发完以后,手动验证一次免密是否成功:
bash复制ssh root@192.168.122.10 "hostname"
如果这条命令不需要输入密码,说明免密已经通了。如果还想做得更好,可以在被管节点上新建一个专门的运维用户,并给该用户配置 sudo 提权权限。不过对学习和测试,直接使用 root 是最简单直接的方法,只要你的测试环境不暴露在公网即可。
注意:Ansible 的 ping 模块并不是真的发送 ICMP 请求,它是通过 SSH 连接到目标机器后执行一段 Python 代码,验证目标机器 Python 环境和用户权限是否正常。所以如果目标机器没有安装 Python 或者 SSH 服务没启动,ping 模块照样失败。
3.3 使用 ansible ad-hoc 验证连通性
连通的验证方式很简单,在 ~/ansible-demo 目录下执行:
bash复制ansible all -m ping
如果之前配置好免密,输出大概长这样:
text复制192.168.122.10 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.122.11 | SUCCESS => {
"changed": false,
"ping": "pong"
}
看到 SUCCESS 和 pong,说明控制端已经能通过 SSH 管理这两台 openEuler 机器了。如果不想用免密,可以临时加 -k 参数,执行时输入 SSH 密码,但需要额外安装 sshpass,不建议依赖这种用法。
3.4 用 Ansible Playbook 完成第一个实际任务
ad-hoc 命令适合临时执行单条指令。真正体现 Ansible 威力的是 Playbook,它能把一系列操作写成“剧本”,可以反复执行且具备幂等性。
在 ~/ansible-demo 下创建一个文件 first.yml:
yaml复制---
- hosts: all
gather_facts: true
tasks:
- name: 打印被管节点的系统信息
ansible.builtin.debug:
msg: "当前主机 {{ inventory_hostname }},系统 {{ ansible_distribution }} {{ ansible_distribution_version }}"
执行:
bash复制ansible-playbook first.yml
如果一切正常,输出中会看到每个节点都有一个 ok 状态的 task,并且打印出类似:
text复制"msg": "当前主机 192.168.122.10,系统 openEuler 22.03"
这个 Playbook 虽然简单,但已经能说明 Ansible 的核心运行机制:控制端读 hosts 清单,通过 SSH 连到被管节点,在被管节点收集系统信息(gather_facts),然后执行任务,最后把输出汇总回控制端。
再写一个稍微实用一点的 Playbook,比如确保被管节点统一安装 vim 并启动 chronyd:
yaml复制---
- hosts: all
become: true
tasks:
- name: 确保安装 vim
ansible.builtin.dnf:
name: vim-enhanced
state: present
- name: 确保 chronyd 启动并开机自启
ansible.builtin.service:
name: chronyd
state: started
enabled: true
用 ansible-playbook -C install_common.yml 可以先做一次语法和变更预检,-C 是 dry-run 模式,不会真正改变系统。确认无误后去掉 -C 执行。这个例子看起来简单,但它展示了 Ansible 最常用的三个模块:dnf 安装软件、service 管理系统服务、debug 输出调试信息。只要掌握这套写法,后续扩展安装 Nginx、配置防火墙、下发配置文件都不难。
4. 常见问题与排查技巧实录
4.1 常见错误速查表
把我在安装和调试过程中遇到的典型问题整理成了一张速查表,先收藏再逐个排查:
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
No package ansible available |
系统仓库里没有 Ansible,EPOL 未启用 | 配置 openEuler EPOL 源后重新 dnf install |
Could not resolve host: repo.openeuler.org |
网络不通或 DNS 配置有问题 | ping 外网,检查 /etc/resolv.conf |
pip 安装后 command not found |
可执行文件不在 PATH 中 | 做软链或 export PATH |
SSH 连接报 Permission denied |
root 为空密码或密钥未配置 | 设置密码;重新 ssh-copy-id |
目标节点返回 ModuleNotFoundError |
被管节点 Python 环境损坏 | 用 dnf 重新安装 python3 常见依赖 |
ansible-playbook 提示未知模块,比如 dnf |
模块名写法不是最新 collection 格式 | 使用 ansible.builtin.dnf 全限定名 |
| Ansible 能安装,但执行命令特别慢 | DNS 反查或 Python 环境启动慢 | 在 ansible.cfg 里设置 gathering = smart 等 |
4.2 安装时报“No package ansible available”的深挖
这个报错是最多人问的。看到它,第一反应不是怀疑 EPOL,而是先确认一下当前 dnf 是否真能看到 ansible:
bash复制dnf search ansible
dnf repo list --enabled
如果 search 结果为空,基本就是仓库里没有这个包。这时按 2.1 节的方法添加 EPOL 源,然后重新 dnf makecache。注意不要写成 EPEL,openEuler 和 CentOS 不是一回事,虽然拼音相近但仓库完全不一样。
一个容易忽略的问题是版本路径。我遇到过用户在 openEuler 24.03 LTS SP2 上照抄 22.03 的 repo 文件,baseurl 指向 openEuler-22.03-LTS-SP4,导致 404。虽然 dnf 不会明确报 404,但 makecache 后仓库元数据为空,后面再安装就会提示找不到包。所以配置 EPOL 后,可以用 curl 测试一下路径是否有效:
bash复制curl -I https://repo.openeuler.org/openEuler-22.03-LTS-SP4/EPOL/main/x86_64/repodata/repomd.xml
只要返回 200 OK,说明路径没问题;如果返回 404,检查版本号和架构拼写。
4.3 pip 安装后的 command not found 与 Python 环境疑问
“明明 pip3 install ansible 成功了,为什么敲 ansible 说 command not found?”这类问题,原因大多数是可执行文件不在 PATH 里。用 pip 装到系统 Python 时,可执行文件会出现在 /usr/local/bin,通常已经在 PATH 里,但如果你用了普通用户且没有 root 权限,pip 会装到用户目录 ~/.local/bin,这个目录默认不一定在 PATH 中。
你可以执行:
bash复制python3 -m site --user-base
看到用户安装目录后,把里面的 bin 目录加进 PATH:
bash复制export PATH="$HOME/.local/bin:$PATH"
如果你用的是 venv 方案,则不需要管用户目录,直接用 /opt/ansible-venv/bin/ansible 或者做软链。
还有一类“安装成功但版本很老”的问题。openEuler EPOL 仓库里的 Ansible
