📖 前言
互联网产品迭代速度越来越快,运维人员每天面对海量重复操作。传统手工维护效率低下且易出错,自动化运维成为必然选择。Ansible 作为一款轻量级、无代理的自动化工具,正被越来越多的企业采用。
一、Ansible 概述
1.1 什么是 Ansible?
Ansible 基于 Python 开发,聚合了 Puppet、Chef、SaltStack 等众多优秀工具的优点,能够批量运行命令、部署程序、配置系统 。它默认通过 SSH 协议 进行远程管理,无需在被管理主机上安装任何客户端代理,极大简化了自动化环境的部署。
1.2 Ansible 架构组成
Ansible 本质上是一个基于模块工作的框架。其核心组件包括:
| 组件 | 说明 |
|---|---|
| Ansible Core | 核心引擎,即 Ansible 本身 |
| Host Inventory | 主机清单,定义被管理主机(默认 /etc/ansible/hosts) |
| Connect Plugin | 连接插件,负责通信(默认 SSH) |
| Playbook | 剧本,使用 YAML + Jinja2 编写,集中定义任务 |
| Core Modules | 自带的核心模块(如 command, copy, yum 等) |
| Custom Modules | 用户自定义模块,可扩展功能 |
1.3 Ansible vs SaltStack(关键对比)
| 对比项 | Ansible | SaltStack |
|---|---|---|
| 部署 | 无需客户端,仅需 SSH | 需安装 Minion 代理 |
| 响应速度 | 较慢(SSH 连接) | 极快(ZeroMQ 通信) |
| 安全性 | 高(SSH 加密传输) | 较高(需守护进程) |
| Windows 支持 | 需 PowerShell(控制端必须 Linux) | 友好 |
| 运维成本 | 低(仅管理 SSH) | 较高(需维护 Master/Minion 进程) |
一般运维场景下,Ansible 的响应速度完全满足需求,且更简单安全。
二、安装部署 Ansible 服务
2.1 实验环境清单
| 操作系统 | 主机名 | IP 地址 | 角色 |
|---|---|---|---|
| openEuler 24.03 | ansible-node1 | 192.168.207.137 | 管理节点 |
| openEuler 24.03 | ansible-node2 | 192.168.207.138 | Web 被管理主机 |
| openEuler 24.03 | ansible-node3 | 192.168.207.139 | DB 被管理主机 |
2.2 系统环境设置
(1)设置主机名(以 node1 为例)
bash
[root@localhost ~]# hostnamectl set-hostname ansible-node1
[root@localhost ~]# bash
请依次为 node2、node3 设置对应的主机名。
(2)配置 hosts 文件(所有节点都做)
bash
[root@ansible-node1 ~]# cat <<EOF >> /etc/hosts
192.168.207.137 ansible-node1
192.168.207.138 ansible-node2
192.168.207.139 ansible-node3
EOF
2.3 安装 Ansible(仅在管理节点)
bash
# 安装 ansible(openEuler 使用 dnf)
[root@ansible-node1 ~]# dnf install -y ansible
# 查看版本
[root@ansible-node1 ~]# ansible --version
# 进入配置目录
[root@ansible-node1 ~]# cd /etc/ansible
[root@ansible-node1 ansible]# ls -l
# 输出:ansible.cfg hosts roles
2.4 配置主机清单(/etc/ansible/hosts)
在文件末尾添加以下内容:
ini
[web]
192.168.207.138 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=123
[db]
192.168.207.139 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=123
💡 安全提示:生产环境建议使用 SSH 密钥认证,避免明文密码。
2.5 修改 Ansible 配置文件(/etc/ansible/ansible.cfg)
取消第 71 行左右的注释,关闭 SSH 密钥检查:
ini
host_key_checking = False
2.6 测试安装结果
bash
[root@ansible-node1 ~]# ansible all -m ping
若返回 "pong",则配置成功。
三、Ansible 命令应用基础
3.1 获取帮助
bash
# 查看 ansible 帮助
ansible -h
# 查看模块帮助(重要)
ansible-doc -l # 列出所有可用模块
ansible-doc yum # 查看 yum 模块详细用法
ansible-doc -s copy # 查看 copy 模块的简洁示例
四、常用核心模块详解(含完整代码)
4.1 command 模块
默认模块,执行简单命令(不支持管道、重定向等特殊符号)。
bash
# 针对单个 IP 执行
ansible 192.168.207.138 -m command -a 'date'
# 针对 web 组
ansible web -m command -a 'date'
# 针对 db 组
ansible db -m command -a 'date'
# 针对所有主机
ansible all -m command -a 'date'
# 省略 -m(默认 command)
ansible all -a 'tail -1 /etc/passwd'
4.2 shell 模块
支持管道、重定向等复杂命令。
bash
# 在 db 组创建用户并设置密码(非交互)
ansible db -m user -a 'name=user1'
ansible db -m shell -a 'echo redhat | passwd --stdin user1'
4.3 user 模块
管理用户账号。
bash
# 创建用户
ansible db -m user -a 'name="user1"'
# 删除用户
ansible db -m user -a 'name="user1" state=absent'
4.4 cron 模块
管理计划任务。
bash
# 添加:每10分钟输出 hello
ansible db -m cron -a 'minute="*/10" job="/bin/echo hello" name="test cron job"'
# 更详细的定时(每天2:30,周一至周五)
ansible db -m cron -a 'hour=2 minute=30 weekday=1-5 name="backup mysql" job="/root/mysql_backup.sh"'
# 删除任务
ansible db -m cron -a 'minute="*/10" job="/bin/echo hello" name="test cron job" state=absent'
4.5 group 模块
管理用户组。
bash
# 创建 mysql 组,gid=306,系统组
ansible db -m group -a 'name=mysql gid=306 system=yes'
# 将 mysql 用户添加到 mysql 组
ansible db -m user -a 'name=mysql uid=306 system=yes group=mysql'
4.6 copy 模块
文件复制与分发。
bash
# 复制本地 /etc/fstab 到远端 /tmp/fstab.ansible,权限 640
ansible db -m copy -a 'src=/etc/fstab dest=/tmp/fstab.ansible owner=root mode=640'
# 注意:若远端有 SELinux,需安装 libselinux-python,否则报错
# 解决方法:在被管理主机执行 dnf install -y libselinux-python
# 直接写入内容到远端文件
ansible db -m copy -a 'content="Hello Ansible Hi Ansible\n" dest=/tmp/test.ansible'
4.7 file 模块
设置文件属性、创建链接等。
bash
# 修改文件属主、属组、权限
ansible db -m user -a 'name="mysql"' # 先确保 mysql 用户存在
ansible db -m file -a 'owner=mysql group=mysql mode=644 path=/tmp/fstab.ansible'
# 创建软链接
ansible db -m file -a 'path=/tmp/fstab.link src=/tmp/fstab.ansible state=link'
4.8 ping 模块
测试主机连通性。
bash
ansible all -m ping
4.9 script 模块
将本地脚本传输到远端执行。
bash
# 准备脚本
cat > test.sh << 'EOF'
#!/bin/bash
echo "hello ansible from script" > /tmp/script.ansible
EOF
chmod +x test.sh
# 执行
ansible db -m script -a 'test.sh'
# 验证(在 node3 上)
cat /tmp/script.ansible
4.10 yum 模块
软件包管理(需预配 yum 源)。
bash
# 安装 zsh
ansible db -m yum -a 'name=zsh'
# 卸载
ansible db -m yum -a 'name=zsh state=absent'
4.11 service 模块
服务管理(原文缺失,补充如下)。
bash
# 启动 httpd 服务并设为开机自启
ansible web -m service -a 'name=httpd state=started enabled=yes'
# 重启服务
ansible web -m service -a 'name=httpd state=restarted'
# 停止服务
ansible web -m service -a 'name=httpd state=stopped'
4.12 setup 模块
收集被管理主机的 facts 信息(操作系统、IP、CPU 等)。
bash
# 查看 db 组所有主机的 facts
ansible db -m setup
# 过滤只查看 IP 地址
ansible db -m setup -a 'filter=ansible_default_ipv4'
五、补充知识点(博客专属,避免雷同)
5.1 主机清单的更多写法
除了直接写 IP,还支持:
ini
# 别名 + 连接参数
web1 ansible_host=192.168.207.138 ansible_user=root
# 范围写法
[web]
192.168.207.[140:150]
# 嵌套组
[webservers]
web1
web2
[dbservers]
db1
[all:children]
webservers
dbservers
5.2 使用 SSH 密钥认证(推荐)
bash
# 生成密钥对
ssh-keygen -t rsa
# 将公钥分发到被管理主机
ssh-copy-id root@192.168.207.138
然后在 /etc/ansible/hosts 中可省略密码:
ini
[web]
192.168.207.138 ansible_ssh_user=root
5.3 Ansible 变量
(1)主机变量与组变量
bash
# 方式一:在 hosts 文件中定义
[web]
192.168.207.138 http_port=8080
[web:vars]
ntp_server=ntp.aliyun.com
(2)使用变量文件
创建 /etc/ansible/group_vars/web.yml:
yaml
---
http_port: 8080
max_clients: 200
然后在 playbook 中直接引用 {``{ http_port }}。
5.4 事实(Facts)与条件判断
yaml
# playbook 示例:仅当系统是 CentOS 7 时安装软件
- hosts: all
tasks:
- name: Install httpd on CentOS 7
yum:
name: httpd
state: present
when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
5.5 Playbook 入门
将多个任务写入一个 YAML 文件,实现幂等性执行。
yaml
---
- name: Install and configure web server
hosts: web
tasks:
- name: Install nginx
yum:
name: nginx
state: latest
- name: Start nginx
service:
name: nginx
state: started
enabled: yes
执行 playbook:
bash
ansible-playbook nginx.yml
5.6 循环(Loops)
yaml
- name: Install multiple packages
yum:
name: "{{ item }}"
state: present
loop:
- git
- vim
- wget
5.7 角色(Roles)------ 大型项目标配
目录结构示例:
text
roles/
common/
tasks/
main.yml
handlers/
main.yml
templates/
files/
vars/
main.yml
defaults/
main.yml
meta/
main.yml
web/
...
使用角色:
yaml
- hosts: web
roles:
- common
- web
5.8 Ansible Galaxy
社区共享角色的平台:
bash
# 安装社区角色
ansible-galaxy install geerlingguy.nginx
# 初始化自己的角色骨架
ansible-galaxy init my_role
5.9 动态主机清单
适用于云环境(AWS、阿里云等),通过脚本动态获取主机列表。
bash
# 示例:使用 ec2.py 脚本(需安装 boto)
ansible -i ec2.py -m ping all
5.10 Ansible Vault ------ 加密敏感数据
bash
# 加密文件
ansible-vault encrypt secrets.yml
# 使用密码执行 playbook
ansible-playbook site.yml --ask-vault-pass
5.11 提升执行效率的配置
在 ansible.cfg 中开启:
ini
[ssh_connection]
pipelining = True # 减少 SSH 连接次数
control_path = /tmp/%%h-%%p-%%r
六、常见问题与排错
| 问题 | 解决方法 |
|---|---|
Host key verification failed |
设置 host_key_checking = False 或手动 ssh-keyscan |
libselinux-python 报错 |
被管理端执行 yum install -y libselinux-python(或 dnf) |
| 中文乱码 | 确保系统 locale 一致,剧本文件使用 UTF-8 编码 |
| 命令执行超时 | 增加 timeout 参数或优化网络 |
ansible all -m ping 卡住 |
检查防火墙及 SSH 连通性 |
七、总结
本文从零开始,详细演示了 Ansible 的安装、配置、常用模块使用,并补充了变量、Playbook、角色、Galaxy、Vault 等高阶知识点。Ansible 的优势在于"简单、无代理、SSH 驱动",非常适合中小型及大型混合环境。
掌握 Ansible 后,你可以:
-
一键完成百台服务器的系统初始化
-
自动化部署 Web 集群、数据库集群
-
结合 CI/CD 实现持续交付
📌 后续可深入学习:Ansible Tower(AWX)、自定义模块、回调插件等。