← 返回文章列表

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
gitgit clonerepo=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

执行顺序:

  1. 任务执行 → 发现配置变了 → notify
  2. 所有任务执行完 → 触发 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
    - app

Galaxy(社区市场)

# 下载别人写好的 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_pass

Playbook 里引用加密变量:

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
gitGit clonerepo=xxx dest=/opt
lineinfile追加/替换行line="xxx" dest=/etc/hosts
cron定时任务name=backup minute=0 hour=2
uriHTTP 请求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
分享

// RELATED_POSTS

0%