Ansible 安装与配置 #

系统要求 #

控制节点 #

Ansible 控制节点可以在以下系统上运行:

系统 版本要求
RHEL/CentOS 7, 8, 9
Ubuntu 18.04, 20.04, 22.04
Debian 10, 11, 12
Fedora 最新版本
macOS 10.15+
Windows WSL2(不支持原生 Windows)

被管理节点 #

被管理节点可以是:

text
┌─────────────────────────────────────────────────────────────┐
│                     被管理节点类型                           │
├─────────────────────────────────────────────────────────────┤
│  Linux        │  Windows      │  网络设备     │  云服务      │
│  ────────────│  ────────────│  ────────────│  ────────────│
│  RHEL/CentOS │  Server 2012+│  Cisco IOS   │  AWS         │
│  Ubuntu      │  Server 2016+│  Juniper     │  Azure       │
│  Debian      │  Server 2019+│  Arista      │  GCP         │
│  Fedora      │               │  Huawei      │  Alibaba     │
│  SUSE        │               │              │              │
└─────────────────────────────────────────────────────────────┘

安装方式 #

方式一:pip 安装(推荐) #

使用 pip 安装是最灵活的方式:

bash
# 安装 Python pip(如果未安装)
# Ubuntu/Debian
sudo apt update
sudo apt install python3-pip

# RHEL/CentOS
sudo dnf install python3-pip

# macOS(使用 Homebrew)
brew install python3

# 安装 Ansible
pip3 install ansible

# 安装指定版本
pip3 install ansible==2.14.0

# 升级 Ansible
pip3 install --upgrade ansible

方式二:系统包管理器 #

Ubuntu/Debian #

bash
# 添加 Ansible PPA
sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository --yes --update ppa:ansible/ansible

# 安装 Ansible
sudo apt install ansible

# 验证安装
ansible --version

RHEL/CentOS #

bash
# 启用 EPEL 仓库
sudo dnf install epel-release

# 安装 Ansible
sudo dnf install ansible

# 验证安装
ansible --version

Fedora #

bash
sudo dnf install ansible

macOS #

bash
# 使用 Homebrew
brew install ansible

# 验证安装
ansible --version

方式三:虚拟环境 #

使用虚拟环境隔离 Ansible 环境:

bash
# 创建虚拟环境
python3 -m venv ansible-env

# 激活虚拟环境
source ansible-env/bin/activate

# 安装 Ansible
pip install ansible

# 使用完毕后退出
deactivate

方式四:容器化运行 #

使用 Docker 运行 Ansible:

bash
# 拉取镜像
docker pull ansible/ansible-runner

# 运行 Ansible 命令
docker run --rm -v $(pwd):/runner ansible/ansible-runner ansible --version

# 创建别名
alias ansible='docker run --rm -v $(pwd):/runner ansible/ansible-runner ansible'

验证安装 #

检查版本 #

bash
ansible --version

# 输出示例:
# ansible [core 2.14.3]
#   config file = /etc/ansible/ansible.cfg
#   configured module search path = ['/home/user/.ansible/plugins/modules']
#   ansible python module location = /usr/lib/python3/dist-packages/ansible
#   ansible collection location = /home/user/.ansible/collections
#   executable location = /usr/bin/ansible
#   python version = 3.10.6
#   jinja version = 3.0.3
#   libyaml = True

检查模块 #

bash
# 列出所有模块
ansible-doc -l

# 查看特定模块帮助
ansible-doc copy
ansible-doc apt
ansible-doc service

配置文件 #

配置文件优先级 #

Ansible 按以下顺序查找配置文件:

text
优先级从高到低:

1. ANSIBLE_CONFIG 环境变量指定的文件
   └── export ANSIBLE_CONFIG=/path/to/ansible.cfg

2. 当前目录下的 ansible.cfg
   └── ./ansible.cfg

3. 用户家目录下的 .ansible.cfg
   └── ~/.ansible.cfg

4. 系统默认配置文件
   └── /etc/ansible/ansible.cfg

创建配置文件 #

bash
# 在项目目录创建配置文件
mkdir -p ~/my-ansible-project
cd ~/my-ansible-project
touch ansible.cfg

配置文件详解 #

ini
# ansible.cfg

[defaults]
# 基本设置
inventory = ./inventory
library = ./library
module_utils = ./module_utils
remote_tmp = ~/.ansible/tmp
local_tmp = ~/.ansible/tmp
forks = 5
poll_interval = 15
sudo_user = root
ask_sudo_pass = False
ask_pass = False
transport = smart
remote_port = 22
module_lang = C
module_set_locale = False

# 主机密钥检查
host_key_checking = False

# 日志设置
log_path = ./ansible.log

# 角色路径
roles_path = ./roles

# 私钥文件
private_key_file = ~/.ssh/id_rsa

# 并发数
forks = 50

# 超时设置
timeout = 10

# 重试文件
retry_files_enabled = False
retry_files_save_path = ./retry

# 彩色输出
nocolor = False

# 委托设置
allow_world_readable_tmpfiles = True

[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = False

[paramiko_connection]
record_host_keys = False
pty = False

[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
pipelining = True
control_path = %(directory)s/ansible-%%h-%%p-%%r
scp_if_ssh = smart
transfer_method = smart
sftp_batch_mode = False

[persistent_connection]
connect_timeout = 30
command_timeout = 30

[accelerate]
accelerate_port = 5099
accelerate_timeout = 30
accelerate_connect_timeout = 5.0

[selinux]
special_context_filesystems = nfs, vboxsf, fuse, ramfs, tmpfs

[colors]
highlight = white
verbose = blue
warn = bright purple
error = red
debug = dark gray
deprecate = purple
skip = cyan
unreachable = red
ok = green
changed = yellow

常用配置示例 #

开发环境配置 #

ini
# ansible.cfg - 开发环境
[defaults]
inventory = ./inventory/hosts
host_key_checking = False
retry_files_enabled = False
log_path = ./logs/ansible.log

[privilege_escalation]
become = True
become_ask_pass = False

生产环境配置 #

ini
# ansible.cfg - 生产环境
[defaults]
inventory = ./inventory/production
host_key_checking = True
retry_files_enabled = True
retry_files_save_path = ./retry
log_path = /var/log/ansible/ansible.log
forks = 20
timeout = 30
gathering = smart
fact_caching = redis
fact_caching_timeout = 86400
fact_caching_connection = localhost:6379:0

[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = True

SSH 配置 #

生成 SSH 密钥 #

bash
# 生成 RSA 密钥对
ssh-keygen -t rsa -b 4096 -C "ansible@control"

# 生成 ED25519 密钥对(推荐)
ssh-keygen -t ed25519 -C "ansible@control"

# 查看公钥
cat ~/.ssh/id_ed25519.pub

分发公钥到被管理节点 #

方式一:ssh-copy-id #

bash
# 复制公钥到远程主机
ssh-copy-id user@192.168.1.100

# 指定端口
ssh-copy-id -p 2222 user@192.168.1.100

# 指定密钥文件
ssh-copy-id -i ~/.ssh/ansible_key user@192.168.1.100

方式二:使用 Ansible 分发 #

yaml
# setup-ssh.yml
- hosts: all
  gather_facts: no
  tasks:
    - name: Install SSH public key
      authorized_key:
        user: "{{ ansible_user }}"
        key: "{{ lookup('file', '~/.ssh/id_ed25519.pub') }}"
        state: present

方式三:手动复制 #

bash
# 查看公钥内容
cat ~/.ssh/id_ed25519.pub

# 在远程主机上执行
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "ssh-ed25519 AAAA... ansible@control" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

SSH 配置文件 #

bash
# ~/.ssh/config

# 全局设置
Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null

# 特定主机设置
Host web1
    HostName 192.168.1.100
    User admin
    Port 22
    IdentityFile ~/.ssh/id_ed25519

Host web2
    HostName 192.168.1.101
    User admin
    Port 22
    IdentityFile ~/.ssh/id_ed25519

# 通配符设置
Host web*
    User admin
    IdentityFile ~/.ssh/web_key

Host db*
    User dbadmin
    IdentityFile ~/.ssh/db_key

# 跳板机设置
Host internal-server
    HostName 10.0.0.100
    User admin
    ProxyJump jumphost.example.com

# 多跳设置
Host final-server
    HostName 10.0.0.200
    User admin
    ProxyJump user@jumphost1.example.com,user@jumphost2.example.com

测试 SSH 连接 #

bash
# 测试 SSH 连接
ssh user@192.168.1.100

# 使用 SSH 配置文件中的别名
ssh web1

# 测试 Ansible 连接
ansible all -m ping -i inventory

创建第一个清单文件 #

静态清单 #

ini
# inventory/hosts

# 直接指定主机
192.168.1.100
192.168.1.101

# 指定主机和连接参数
192.168.1.102 ansible_user=admin ansible_port=2222

# 主机别名
web1 ansible_host=192.168.1.100 ansible_user=admin
web2 ansible_host=192.168.1.101 ansible_user=admin

# 主机组
[webservers]
web1
web2
192.168.1.103

[databases]
db1 ansible_host=192.168.1.200
db2 ansible_host=192.168.1.201

# 嵌套组
[production:children]
webservers
databases

# 组变量
[webservers:vars]
ansible_user=admin
ansible_python_interpreter=/usr/bin/python3

[databases:vars]
ansible_user=dbadmin

YAML 格式清单 #

yaml
# inventory/hosts.yml
all:
  hosts:
    192.168.1.100:
    192.168.1.101:
  
  children:
    webservers:
      hosts:
        web1:
          ansible_host: 192.168.1.100
          ansible_user: admin
        web2:
          ansible_host: 192.168.1.101
          ansible_user: admin
    
    databases:
      hosts:
        db1:
          ansible_host: 192.168.1.200
        db2:
          ansible_host: 192.168.1.201
      
      vars:
        ansible_user: dbadmin
    
    production:
      children:
        webservers:
        databases:

测试环境 #

测试连接 #

bash
# 测试所有主机
ansible all -m ping -i inventory/hosts

# 测试特定组
ansible webservers -m ping -i inventory/hosts

# 测试特定主机
ansible web1 -m ping -i inventory/hosts

收集 Facts #

bash
# 收集所有主机信息
ansible all -m setup -i inventory/hosts

# 收集特定主机信息
ansible web1 -m setup -i inventory/hosts

# 过滤特定信息
ansible web1 -m setup -a "filter=ansible_eth*" -i inventory/hosts

执行命令 #

bash
# 执行简单命令
ansible all -a "uptime" -i inventory/hosts

# 执行 shell 命令
ansible all -m shell -a "df -h" -i inventory/hosts

# 使用 sudo
ansible all -a "whoami" -b -i inventory/hosts

常见问题排查 #

问题一:SSH 连接失败 #

bash
# 错误信息
# SSH Error: Permission denied (publickey,password)

# 解决方案
# 1. 检查 SSH 密钥
ls -la ~/.ssh/

# 2. 检查公钥是否已复制到远程主机
ssh user@host "cat ~/.ssh/authorized_keys"

# 3. 检查 SSH 配置
ansible host -m ping -vvv

问题二:Python 解释器未找到 #

bash
# 错误信息
# MODULE FAILURE: No Python interpreter found

# 解决方案
# 在清单文件中指定 Python 解释器
[all:vars]
ansible_python_interpreter=/usr/bin/python3

问题三:主机密钥验证失败 #

bash
# 错误信息
# Host key verification failed

# 解决方案
# 1. 在配置文件中禁用主机密钥检查
[defaults]
host_key_checking = False

# 2. 或手动添加主机密钥
ssh-keyscan -H 192.168.1.100 >> ~/.ssh/known_hosts

问题四:权限不足 #

bash
# 错误信息
# Permission denied

# 解决方案
# 使用 become 提升权限
ansible all -m ping -b

# 或在配置文件中设置
[privilege_escalation]
become = True

项目目录结构 #

推荐的项目结构 #

text
my-ansible-project/
├── ansible.cfg              # Ansible 配置文件
├── inventory/               # 清单目录
│   ├── hosts                # 主机清单
│   ├── group_vars/          # 组变量
│   │   ├── all.yml
│   │   ├── webservers.yml
│   │   └── databases.yml
│   └── host_vars/           # 主机变量
│       ├── web1.yml
│       └── db1.yml
├── playbooks/               # Playbook 目录
│   ├── site.yml             # 主 Playbook
│   ├── webservers.yml
│   └── databases.yml
├── roles/                   # 角色目录
│   ├── common/
│   ├── nginx/
│   └── mysql/
├── files/                   # 静态文件
├── templates/               # 模板文件
├── library/                 # 自定义模块
├── module_utils/            # 模块工具
└── filter_plugins/          # 过滤器插件

下一步 #

现在你已经完成了 Ansible 的安装和配置,接下来学习 基础概念 深入了解 Ansible 的核心概念!

最后更新:2026-03-29