← 返回文章列表
Ansible 快速入门完全指南
Ansible 批量服务器管理工具的完整指南,包含 Ad-Hoc 命令、Playbook、Roles、Handlers 和企业实战场景
11 分钟阅读
字号
Ansible 快速入门完全指南
学习日期:2026-03-27
一、Ansible 是什么
Ansible 是一款批量服务器管理工具,通过 SSH 远程连接服务器,不需要在被管理节点安装任何 agent。
核心价值:
- 幂等性:执行多次结果一致,不会重复安装
- YAML 语法:声明式描述"做什么",不是"怎么做"
- 批量管理:一台命令,100 台同时生效
对比传统方式:
| 方式 | 缺点 |
|---|---|
| 手动 SSH 逐台登录 | 累、易出错、无法批量 |
| Bash 脚本 for 循环 | 非幂等,执行多次结果不确定 |
| Ansible | 幂等,执行多次结果一致 |
二、核心架构
┌──────────────────────────────────────┐
│ 控制节点(本地电脑 / CI 服务器) │
│ 安装 Ansible,配置 inventory │
└──────────────────────────────────────┘
│ SSH 连接(密码或密钥)
▼
┌──────────────────────────────────────┐
│ 被管理节点 1、2、3...(N 台服务器) │
│ 无需安装任何软件,只要 SSH 能连上 │
└──────────────────────────────────────┘安装:
# Linux / Mac
pip install ansible
# WSL2(Windows 原生不支持 Ansible)
wsl --install三、Inventory(主机清单)
Inventory 告诉 Ansible 要管理哪些服务器。
方式一:INI 格式
# /etc/ansible/hosts 或 -i 指定文件
[webservers] # 组名
192.168.1.101 # IP
192.168.1.102
[dbservers]
192.168.1.201
[all\:vars] # 全局变量
ansible_user=root
ansible_port=22方式二:YAML 格式
all:
hosts:
web01:
ansible_host: 192.168.1.101
web02:
ansible_host: 192.168.1.102
children:
webservers:
hosts:
web01:
web02:
dbservers:
hosts:
db01:
ansible_host: 192.168.1.201
vars:
ansible_user: root四、Ad-Hoc 命令(临时命令)
不需要写 Playbook,直接一行命令搞定。
常用模块
# 所有主机执行 ping(测试连通性)
ansible all -m ping
# webservers 组执行 ping
ansible webservers -m ping
# 单台执行
ansible 192.168.1.101 -m ping
# 安装软件包
ansible all -m yum -a "name=nginx state=present"
ansible all -m apt -a "name=nginx state=present"
# 启动服务
ansible all -m systemd -a "name=nginx state=started enabled=yes"
# 复制文件
ansible all -m copy -a "src=./nginx.conf dest=/etc/nginx/nginx.conf"
# 创建目录
ansible all -m file -a "path=/data state=directory mode=0755"
# 删除文件
ansible all -m file -a "path=/data state=absent"
# 重启服务
ansible all -m systemd -a "name=nginx state=restarted"模块速查表
| 模块 | 作用 | 示例 |
|---|---|---|
ping | 测试连通性 | ansible all -m ping |
yum/apt | 安装软件包 | yum state=present name=nginx |
copy | 复制文件(本地→远程) | src=./a.conf dest=/path/ |
template | 复制文件(支持变量) | src=a.conf.j2 dest=/path/ |
systemd/service | 管理服务 | name=nginx state=restarted |
file | 创建目录/文件/链接 | path=/data state=directory |
user | 创建/删除用户 | name=alice state=present |
git | git clone | repo=git@github.com:xxx dest=/opt/app |
shell/command | 执行命令(少用) | cmd="ls /data" |
get_url | 下载文件 | url=https://xxx dest=/tmp/ |
五、Playbook(剧本,核心)
Ansible 的真正威力。YAML 格式,描述"做什么"。
最小完整示例
# nginx.yml
- hosts: webservers # 针对哪台/哪些服务器
become: yes # 提权 root
tasks: # 任务列表
- name: 安装 Nginx
yum:
name: nginx
state: present
- name: 配置 Nginx
copy:
src: ./nginx.conf
dest: /etc/nginx/nginx.conf
notify: 重启 Nginx # 触发 handler
- name: 启动 Nginx
systemd:
name: nginx
state: started
enabled: yes
handlers: # 处理器(被 notify 触发)
- name: 重启 Nginx
systemd:
name: nginx
state: restarted执行:
ansible-playbook nginx.yml常用命令
ansible-playbook nginx.yml # 执行
ansible-playbook nginx.yml --check # 模拟执行(不真正改)
ansible-playbook nginx.yml --diff # 显示改动详情
ansible-playbook nginx.yml --start-at-task="配置 Nginx" # 从指定任务开始六、变量
定义变量
- hosts: webservers
vars:
app_path: /var/www/app
nginx_port: 8080
tasks:
- name: 创建目录
file:
path: "{{ app_path }}"
state: directory使用变量
tasks:
- name: 复制配置
template:
src: app.conf.j2
dest: "{{ app_path }}/app.conf"Facts 变量(系统自带)
# 查看所有 facts
ansible all -m setup
# 使用 facts
ansible all -m debug -a "msg={{ ansible_hostname }} {{ ansible_default_ipv4.address }}"注册变量
tasks:
- name: 执行命令并记录输出
shell: df -h
register: disk_usage
- name: 显示结果
debug:
msg: "{{ disk_usage.stdout }}"七、条件判断
tasks:
- name: 安装 EPEL(仅 RedHat 系)
yum:
name: epel-release
when: ansible_os_family == "RedHat"
- name: 安装 Apache(仅 Debian 系)
apt:
name: apache2
when: ansible_os_family == "Debian"八、循环
标准循环
tasks:
- name: 创建多个用户
user:
name: "{{ item }}"
state: present
loop:
- alice
- bob
- charlie哈希列表循环
tasks:
- name: 配置多个端口
lineinfile:
path: /etc/nginx/nginx.conf
line: "{{ item.port }} {{ item.path }}"
loop:
- { port: 80, path: /var/www/site1 }
- { port: 8080, path: /var/www/site2 }九、Handlers(处理器)
Handlers 类似"触发器"——只有 task 真正执行了 notify 时才运行。
tasks:
- name: 修改了配置文件
copy:
src: nginx.conf
dest: /etc/nginx/nginx.conf
notify: 重启 Nginx
- name: 修改了端口
lineinfile:
path: /etc/nginx/nginx.conf
line: "listen 8080"
notify: 重启 Nginx
handlers:
- name: 重启 Nginx
systemd:
name: nginx
state: restarted执行顺序:
- 任务执行 → 发现配置变了 → notify
- 所有任务执行完 → 触发 handler(只执行一次)
十、Roles(角色)
大型项目用 Roles 分解,每个角色独立目录:
roles/
├── common/ # 所有服务器通用配置(时区、NTP)
│ ├── tasks/
│ │ └── main.yml
│ └── handlers/
├── nginx/
│ ├── tasks/
│ │ └── main.yml
│ ├── templates/ # 配置文件(Jinja2)
│ ├── handlers/
│ └── vars/
│ └── main.yml
├── mysql/
│ ├── tasks/
│ └── defaults/
└── app/
├── tasks/
└── templates/使用 Role
# site.yml
- hosts: webservers
roles:
- common
- nginx
- mysql
- appGalaxy(社区市场)
# 下载别人写好的 Role
ansible-galaxy install geerlingguy.nginx
ansible-galaxy install geerlingguy.mysql
# 创建 Role 骨架
ansible-galaxy init nginx十一、Ansible Vault(加密敏感数据)
生产环境不能把密码明文写在 Playbook 里。
# 创建加密文件
ansible-vault create secrets.yml
# 编辑加密文件
ansible-vault edit secrets.yml
# 加密现有文件
ansible-vault encrypt secrets.yml
# 解密
ansible-vault decrypt secrets.yml
# 执行时输入密码
ansible-playbook site.yml --ask-vault-pass
# 或用密码文件
ansible-playbook site.yml --vault-password-file=~/.vault_passPlaybook 里引用加密变量:
vars_files:
- secrets.yml
tasks:
- name: 创建数据库
mysql_db:
name: "{{ db_name }}"
state: present
login_password: "{{ db_password }}"十二、Templates(Jinja2 模板)
配置文件支持变量和逻辑:
# nginx.conf.j2
server {
listen {{ nginx_port }};
root {{ document_root }};
{% if enable_ssl %}
ssl_certificate /etc/ssl/{{ cert_name }};
ssl_certificate_key /etc/ssl/{{ cert_key }};
{% endif %}
server_name {{ server_name }};
}tasks:
- name: 配置 Nginx
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: 重启 Nginx十三、常见模块速查
| 模块 | 用途 | 示例 |
|---|---|---|
yum/apt | 安装软件包 | name=nginx state=present |
copy | 复制本地文件 | src=a.txt dest=/tmp/ |
template | 复制文件(变量替换) | src=a.j2 dest=/tmp/ |
systemd/service | 服务管理 | name=nginx state=restarted |
file | 文件/目录/链接 | path=/tmp state=directory |
user | 用户管理 | name=alice state=present |
group | 用户组 | name=www state=present |
git | Git clone | repo=xxx dest=/opt |
lineinfile | 追加/替换行 | line="xxx" dest=/etc/hosts |
cron | 定时任务 | name=backup minute=0 hour=2 |
uri | HTTP 请求 | url=https://xxx |
docker_image | 镜像管理 | name=nginx state=present |
docker_container | 容器管理 | name=web image=nginx |
十四、企业实战场景
场景一:初始化 K8s 节点
- hosts: k8s-nodes
become: yes
tasks:
- name: 关闭防火墙
systemd:
name: firewalld
state: stopped
enabled: no
- name: 关闭 SELinux
lineinfile:
path: /etc/selinux/config
regexp: '^SELINUX='
line: 'SELINUX=disabled'
- name: 关闭 swap
shell: swapoff -a && sed -i '/swap/d' /etc/fstab
- name: 加载内核模块
modprobe:
name: "{{ item }}"
state: present
loop:
- overlay
- br_netfilter场景二:批量部署 Nginx
- hosts: webservers
become: yes
tasks:
- name: 安装 EPEL
yum:
name: epel-release
state: present
- name: 安装 Nginx
yum:
name: nginx
state: present
- name: 复制配置
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: 重启 Nginx
- name: 启动 Nginx
systemd:
name: nginx
state: started
enabled: yes
handlers:
- name: 重启 Nginx
systemd:
name: nginx
state: restarted场景三:多环境部署
# dev 环境
- hosts: dev-servers
vars:
env: dev
db_host: 192.168.1.100
tasks:
- include: deploy.yml
# prod 环境
- hosts: prod-servers
vars:
env: prod
db_host: 10.0.0.100
tasks:
- include: deploy.yml十五、与 K8s 的关系
| 工具 | 擅长 |
|---|---|
| Ansible | 基础设施初始化(系统参数、网络、基础软件) |
| K8s | 应用部署、扩缩容、自愈 |
典型分工:
# Ansible 初始化 K8s 节点
# (系统参数、Docker、K8s 二进制)
# K8s Deployment 部署应用
# (YAML / Helm / ArgoCD)Ansible 初始化 K8s Worker 节点:
- hosts: k8s-workers
become: yes
tasks:
- name: 写入 kubeadm join 命令
copy:
dest: /tmp/join-command
content: "{{ hostvars.groups.k8s_master[0].join_command }}"
- name: 执行 join
shell: "bash /tmp/join-command"
when: inventory_hostname != groups.k8s_master[0]常用命令汇总
# Inventory
ansible-inventory -i inventory.ini --list
# 测试连通性
ansible all -m ping
# 执行 Ad-Hoc
ansible webservers -m yum -a "name=nginx state=present"
# 执行 Playbook
ansible-playbook site.yml
# 带 vault 密码
ansible-playbook site.yml --ask-vault-pass
# 模拟执行(不真正改)
ansible-playbook site.yml --check
# 指定 inventory
ansible-playbook -i inventory-prod.ini site.yml
# 列出所有任务(不执行)
ansible-playbook site.yml --list-tasks分享