Ansible 入门指南:从零开始掌握自动化配置管理

钩子/开头:凌晨三点的运维噩梦

凌晨三点,手机在床头柜上疯狂震动。你眯着眼解锁屏幕——又是运维告警。

“生产环境 Nginx 配置出错,100 台服务器需要紧急修复。”

你深吸一口气,SSH 登录第一台机器,输入命令;复制粘贴到第二台;第三台……第十台时,你开始怀疑人生。两小时后,你终于完成。咖啡凉了,眼睛酸了,键盘上还沾着泡面碎屑。

如果当时用了 Ansible,这一切只需一条命令:

bash

ansible webservers -m copy -a "src=nginx.conf dest=/etc/nginx/nginx.conf" -b
ansible webservers -m service -a "name=nginx state=restarted" -b

没错,自动化不是未来,是现在。而你,即将掌握它。


引言:为什么是 Ansible?

什么是 Ansible?

Ansible 是一个开源的自动化工具,用于配置管理、应用部署、任务编排和云资源管理。它的核心哲学是:简单、无代理、声明式、幂等性

  • 无代理(Agentless):通过 SSH 通信,无需在目标机器安装客户端。
  • 声明式(Declarative):你描述“目标状态”,而非“执行步骤”。
  • 幂等性(Idempotency):无论运行多少次,系统状态始终一致 [3]。

为什么选择 Ansible 而不是 Puppet/SaltStack?

特性 Ansible Puppet SaltStack
代理 ❌ 无需 ✅ 需要 ✅ 可选
学习曲线 ⭐ 简单(YAML) ⭐⭐ 中等(DSL) ⭐⭐ 中等(Python)
社区支持 ⭐⭐⭐ 极强(Red Hat) ⭐⭐ 稳定 ⭐⭐ 活跃
适用场景 快速部署、中小规模 大型企业合规 实时响应

据 Red Hat 的《2023 State of DevOps Automation Report》,使用 Ansible 的企业平均将配置和部署时间减少了 70%,从数小时缩短至几分钟 [1]。

本文目标:零基础也能在 30 分钟内写出并运行第一个 playbook


第一节:Ansible 核心概念解析

控制节点 vs 管理节点

  • 控制节点(Control Node):运行 Ansible 的机器(你的笔记本或跳板机)。
  • 管理节点(Managed Nodes):被 Ansible 控制的远程主机(通过 SSH)。

💡 提示:控制节点只需安装 Ansible,无需额外服务。

Inventory 文件:定义你的主机

Inventory 是 Ansible 的“通讯录”,告诉它去哪执行任务。

ini

# /etc/ansible/hosts 或项目目录下的 hosts.ini
[webservers]
web01 ansible_host=192.168.1.10
web02 ansible_host=192.168.1.11

[dbservers]
db01 ansible_host=192.168.1.20

你也可以使用动态 inventory(如 AWS EC2、OpenStack)。

Modules:Ansible 的“动作单元”

模块是执行具体任务的插件。常用模块:

  • command:运行 shell 命令(不通过 shell 解析)
  • shell:运行 shell 命令(支持管道、重定向)
  • copy:复制文件到远程主机
  • service:管理服务(start/stop/restart)
  • apt / yum:包管理
  • git:拉取代码仓库

“幂等性”意味着:多次运行 service nginx restart 不会报错,即使服务已运行 [3]。

Playbook:YAML 格式的任务编排

Playbook 是 Ansible 的核心。它用 YAML 编写,描述一组任务(tasks)如何在哪些主机(hosts)上执行。

yaml

- name: 安装并启动 Nginx
  hosts: webservers
  become: yes  # 使用 sudo
  tasks:
    - name: 安装 Nginx
      apt:
        name: nginx
        state: present

    - name: 启动 Nginx 服务
      service:
        name: nginx
        state: started
        enabled: yes

Ad-hoc 命令:快速执行单条命令

当你只想快速检查或执行一次任务时,用 ad-hoc:

bash

# 测试所有主机连通性
ansible all -i hosts.ini -m ping

# 在 webservers 组上查看磁盘使用
ansible webservers -i hosts.ini -m shell -a "df -h"

第二节:环境搭建与第一个 Ad-hoc 命令

安装 Ansible

Ubuntu / Debian

bash

sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install ansible
CentOS / RHEL

bash

sudo yum install epel-release
sudo yum install ansible
macOS(使用 Homebrew)

bash

brew install ansible

✅ 验证安装:ansible --version

配置 Inventory

创建项目目录:

bash

mkdir ansible-demo && cd ansible-demo
touch hosts.ini

编辑 hosts.ini(假设你有两台测试机,或使用本地 Docker 容器):

ini

[local]
localhost ansible_connection=local

💡 使用 localhost 可在本机测试,无需 SSH。

测试连通性

bash

ansible local -i hosts.ini -m ping

输出应为:

json

localhost | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

示例:批量创建用户

bash

ansible local -i hosts.ini -m user -a "name=deploy state=present" --become

--become 等价于 sudo,用于提权。


第三节:编写你的第一个 Playbook

YAML 基础语法提醒

  • 缩进必须用空格(通常 2 空格)
  • 列表用 - 表示
  • 键值对用 key: value

实战:部署 Nginx 并启动服务

创建文件 nginx-playbook.yml

yaml

---
- name: 部署 Nginx Web 服务器
  hosts: local
  become: yes
  tasks:
    - name: 更新 apt 缓存
      apt:
        update_cache: yes

    - name: 安装 Nginx
      apt:
        name: nginx
        state: present

    - name: 确保 Nginx 正在运行并开机自启
      service:
        name: nginx
        state: started
        enabled: yes

    - name: 创建自定义欢迎页面
      copy:
        content: "<h1>Hello from Ansible!</h1>"
        dest: /var/www/html/index.nginx-debian.html
        owner: www-data
        group: www-data
        mode: '0644'

运行 Playbook

bash

ansible-playbook -i hosts.ini nginx-playbook.yml

输出将显示每个任务的执行状态(changed/skipped/ok)。

幂等性演示

再次运行相同命令:

bash

ansible-playbook -i hosts.ini nginx-playbook.yml

你会发现所有任务显示 ok,无 changed —— 这就是幂等性!


第四节:进阶技巧与最佳实践

使用 Roles 组织复杂项目

Roles 是 Ansible 的“模块化”方式。结构如下:

roles/
└── nginx/
    ├── tasks/
    │   └── main.yml
    ├── handlers/
    │   └── main.yml
    ├── templates/
    │   └── nginx.conf.j2
    └── defaults/
        └── main.yml

创建 role:

bash

ansible-galaxy init roles/nginx

roles/nginx/tasks/main.yml 中写入任务,然后在 playbook 中调用:

yaml

- name: 使用 Role 部署 Nginx
  hosts: local
  become: yes
  roles:
    - nginx

变量优先级

Ansible 变量来源(从低到高优先级):

  1. role defaults
  2. inventory vars
  3. playbook vars
  4. host_vars / group_vars
  5. extra vars (-e)

条件判断:when

yaml

- name: 仅在 Ubuntu 上安装
  apt:
    name: nginx
    state: present
  when: ansible_os_family == "Debian"

循环:loop

yaml

- name: 创建多个用户
  user:
    name: "{{ item }}"
    state: present
  loop:
    - alice
    - bob
    - charlie

错误处理

yaml

- name: 尝试启动可能不存在的服务
  service:
    name: fake-service
    state: started
  ignore_errors: yes

加密敏感数据:Ansible Vault

bash

ansible-vault create secrets.yml
# 输入密码,然后编辑文件

运行带 vault 的 playbook:

bash

ansible-playbook site.yml --ask-vault-pass

🔐 Vault 在企业中广泛用于保护数据库密码、API 密钥。


第五节:调试与优化

调试模式

bash

ansible-playbook -i hosts.ini nginx-playbook.yml -vvv

-vvv 显示详细执行过程。

使用 debug 模块

yaml

- name: 显示变量
  debug:
    var: ansible_os_family

性能优化

  • forks:控制并发连接数(默认 5)

    bash

    ansible-playbook -i hosts.ini playbook.yml --forks 50
    
  • pipelining:减少 SSH 连接次数(在 ansible.cfg 中启用)

ini

[ssh_connection]
pipelining = True

使用 tags 选择性执行

yaml

- name: 安装 Nginx
  apt:
    name: nginx
    state: present
  tags: nginx

运行特定 tag:

bash

ansible-playbook -i hosts.ini playbook.yml --tags nginx

第六节:真实项目实战——部署 Flask 应用

场景

部署一个简单的 Flask 应用到 Ubuntu 服务器。

步骤

  1. 安装 Python、pip、virtualenv
  2. 拉取代码(使用 git module)
  3. 安装依赖
  4. 配置 systemd 服务
  5. 启动服务

完整 Playbook:flask-deploy.yml

yaml

---
- name: 部署 Flask 应用
  hosts: local
  become: yes
  vars:
    app_name: myflaskapp
    app_dir: /opt/{{ app_name }}
    repo_url: https://github.com/example/flask-demo.git
    python_version: python3.10

  tasks:
    - name: 安装系统依赖
      apt:
        name:
          - git
          - python3-venv
          - python3-pip
          - nginx
        state: present

    - name: 创建应用目录
      file:
        path: "{{ app_dir }}"
        state: directory
        owner: ubuntu
        group: ubuntu
        mode: '0755'

    - name: 克隆代码仓库
      git:
        repo: "{{ repo_url }}"
        dest: "{{ app_dir }}"
        version: main
        force: yes

    - name: 创建虚拟环境
      command: "{{ python_version }} -m venv {{ app_dir }}/venv"
      args:
        creates: "{{ app_dir }}/venv"

    - name: 安装 Python 依赖
      pip:
        requirements: "{{ app_dir }}/requirements.txt"
        virtualenv: "{{ app_dir }}/venv"

    - name: 配置 systemd 服务
      copy:
        content: |
          [Unit]
          Description=Gunicorn instance for {{ app_name }}
          After=network.target

          [Service]
          User=ubuntu
          Group=www-data
          WorkingDirectory={{ app_dir }}
          ExecStart={{ app_dir }}/venv/bin/gunicorn --workers 3 --bind unix:{{ app_name }}.sock -m 007 wsgi:app

          [Install]
          WantedBy=multi-user.target
        dest: /etc/systemd/system/{{ app_name }}.service
        mode: '0644'
      notify: 重启 {{ app_name }}

    - name: 启动并启用服务
      systemd:
        name: "{{ app_name }}"
        state: started
        enabled: yes

    - name: 配置 Nginx 反向代理
      copy:
        content: |
          server {
              listen 80;
              server_name _;

              location / {
                  include proxy_params;
                  proxy_pass http://unix:/opt/{{ app_name }}/{{ app_name }}.sock;
              }
          }
        dest: /etc/nginx/sites-available/{{ app_name }}
      notify: 重启 Nginx

    - name: 启用 Nginx 站点
      file:
        src: /etc/nginx/sites-available/{{ app_name }}
        dest: /etc/nginx/sites-enabled/{{ app_name }}
        state: link
      notify: 重启 Nginx

  handlers:
    - name: 重启 Nginx
      service:
        name: nginx
        state: restarted

    - name: 重启 {{ app_name }}
      systemd:
        name: "{{ app_name }}"
        state: restarted

🎉 运行:ansible-playbook -i hosts.ini flask-deploy.yml


结论

Ansible 不仅是一个工具,更是一种思维方式:用代码描述基础设施,用自动化解放双手

总结 Ansible 的核心优势

  • 简单:YAML 易读,无需编程基础
  • 强大:支持从单机到云环境的自动化
  • 可扩展:通过 Roles、Collections、Modules 无限扩展

学习路径建议

  1. 从 ad-hoc 命令开始,熟悉模块
  2. 编写简单 playbook(如安装软件)
  3. 使用 roles 组织项目
  4. 探索 collections(如 community.general
  5. 集成 CI/CD(如 GitLab CI + Ansible)

行动号召

打开终端,运行:

bash

ansible localhost -m ping

如果看到 "ping": "pong",恭喜你——你已踏上自动化之路。

现在,修改本文的 Nginx 示例,部署你自己的静态网站或博客。自动化不是未来,是现在

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐