Ansible 完整中文使用指南

📚 目录

  1. Ansible 简介

  2. 环境准备

  3. 基础配置

  4. 基础概念

  5. Ad-hoc 命令使用

  6. Playbook 编写指南

  7. 常用模块详解

  8. 实战示例

  9. 高级功能

  10. 最佳实践

  11. 故障排查


Ansible 简介

Ansible 是一个开源的自动化工具,用于配置管理、应用部署、任务编排和基础设施管理。它具有以下特点:

核心优势

  • 无代理架构:只需要 SSH 连接,无需在目标主机安装代理

  • 简单易学:使用 YAML 语法,可读性强

  • 幂等性:多次执行相同操作结果一致

  • 声明式:描述期望状态而非具体步骤

核心组件

  • 控制节点(Control Node):运行 Ansible 的机器

  • 被管理节点(Managed Nodes):被 Ansible 管理的服务器

  • 清单(Inventory):定义被管理节点的文件

  • 模块(Modules):执行具体任务的代码单元

  • 剧本(Playbooks):定义自动化任务的 YAML 文件


环境准备

Level 0: 使用 Terraform 搭建环境

1. 生成 SSH 密钥对


ssh-keygen -t rsa -f deployer-key.pem -q -N ""

2. 部署基础设施


# 初始化 Terraform

terraform init



# 应用配置,创建 AWS EC2 实例

terraform apply

3. 环境配置

基础设施包括:

  • Ansible 服务器:Amazon Linux 2,预装 Ansible

  • 客户端节点:Ubuntu 22.04

  • 安全组:允许 SSH (22 端口) 访问

4. SSH 连接配置


# 1. 将私钥复制到 Ansible 服务器

scp -i ./deployer-key.pem deployer-key.pem ec2-user@<ansible_server_ip>:~/.ssh



# 2. 连接到 Ansible 服务器

ssh -i ./deployer-key.pem ec2-user@<ansible_server_ip>



# 3. 在 Ansible 服务器上创建 SSH 配置

vim ~/.ssh/config

SSH 配置内容:


Host <client_ip>

    User ubuntu

    IdentityFile ~/.ssh/deployer-key.pem


基础配置

ansible.cfg 配置文件

在项目目录创建 ansible.cfg 文件:


[defaults]

# 禁用主机密钥检查(生产环境建议开启)

host_key_checking = False



# 指定清单文件位置

inventory = hosts



# 默认远程用户

remote_user = ubuntu



# 私钥文件位置

private_key_file = ~/.ssh/deployer-key.pem



# 并发连接数

forks = 5



# 超时设置

timeout = 30



# 日志路径

log_path = ./ansible.log

清单文件 (hosts)

创建 hosts 文件定义被管理的主机:


# 基本格式

[tag_node]

192.168.1.100



# 带变量的格式

[webservers]

web1 ansible_host=192.168.1.100 ansible_user=ubuntu

web2 ansible_host=192.168.1.101 ansible_user=ubuntu



# 主机组变量

[webservers:vars]

http_port=80

max_clients=200



# 嵌套组

[production:children]

webservers

databases


基础概念

YAML 语法基础


---

# 这是注释

# 键值对

name: "Ansible Tutorial"

version: 2.9



# 列表

packages:

  - nginx

  - mysql

  - php



# 字典

database:

  host: localhost

  port: 3306

  name: myapp



# 多行字符串

description: |

  这是一个多行

  字符串示例

  保持换行格式



# 布尔值

enabled: true

debug: false

Ansible 变量

变量定义方式


---

- hosts: webservers

  vars:

    http_port: 80

    server_name: example.com



  tasks:

    - name: 使用变量

      debug:

        msg: "服务器 {{ server_name }} 监听端口 {{ http_port }}"

变量优先级(从高到低)

  1. 命令行变量 (-e)

  2. 任务变量

  3. 剧本变量

  4. 主机变量

  5. 组变量

  6. 默认变量


Ad-hoc 命令使用

Ad-hoc 命令用于执行简单的一次性任务,非常适合开发和调试阶段。

基本语法


ansible [主机模式] -m [模块名] -a "[模块参数]" [其他选项]

常用 Ad-hoc 命令示例

1. 连通性测试


# 测试所有主机连通性

ansible all -m ping



# 测试特定组

ansible webservers -m ping



# 测试特定主机

ansible web1 -m ping

2. 收集系统信息


# 收集所有系统信息

ansible all -m setup



# 收集特定信息

ansible all -m setup -a "filter=ansible_os_family"



# 只显示内存信息

ansible all -m setup -a "filter=ansible_memory_mb"

3. 包管理


# 安装软件包

ansible all -b -m apt -a "name=nginx state=present"



# 安装多个包

ansible all -b -m apt -a "name=nginx,mysql-server state=present"



# 更新包缓存

ansible all -b -m apt -a "update_cache=yes"



# 卸载软件包

ansible all -b -m apt -a "name=nginx state=absent"

4. 服务管理


# 启动服务

ansible all -b -m systemd -a "name=nginx state=started"



# 停止服务

ansible all -b -m systemd -a "name=nginx state=stopped"



# 重启服务

ansible all -b -m systemd -a "name=nginx state=restarted"



# 设置服务开机启动

ansible all -b -m systemd -a "name=nginx enabled=yes"

5. 用户管理


# 创建用户

ansible all -b -m user -a "name=testuser shell=/bin/bash"



# 创建用户并设置密码

ansible all -b -m user -a "name=testuser password={{ 'password123' | password_hash('sha512') }}"



# 删除用户

ansible all -b -m user -a "name=testuser state=absent remove=yes"

6. 文件操作


# 复制文件

ansible all -m copy -a "src=/etc/hosts dest=/tmp/hosts"



# 创建目录

ansible all -m file -a "path=/tmp/testdir state=directory mode=0755"



# 删除文件

ansible all -m file -a "path=/tmp/testfile state=absent"



# 修改文件权限

ansible all -m file -a "path=/tmp/testfile mode=0644 owner=ubuntu group=ubuntu"

7. 命令执行


# 执行简单命令

ansible all -m command -a "uptime"



# 执行 shell 命令(支持管道等)

ansible all -m shell -a "ps aux | grep nginx"



# 在特定目录执行命令

ansible all -m command -a "ls -la" -a "chdir=/tmp"

重要选项说明

  • -b, --become:使用特权提升(sudo)

  • -u USER:指定远程用户

  • -i INVENTORY:指定清单文件

  • -l LIMIT:限制执行的主机

  • -f FORKS:指定并发数

  • --check:检查模式,不实际执行

  • --diff:显示更改差异


Playbook 编写指南

Level 1: 基础 Playbook

1. 第一个 Playbook (first.yaml)


---

- name: "我的第一个 Playbook"

  hosts: localhost



  tasks:

    - name: "测试连通性"

      ping:

运行命令:


ansible-playbook first.yaml

2. Hello World 示例 (helloworld.yaml)


---

- name: 我的第二个 Playbook

  hosts: localhost



  tasks:

    - name: 打印 Hello World

      debug:

        msg: "Hello World"

3. 多任务 Playbook (mtask.yaml)


---

- name: 运行多个任务

  hosts: localhost



  tasks:

    - name: 测试连通性

      ping:



    - name: 打印 Hello World

      debug:

        msg: "Hello World"

Level 2: 远程主机 Playbook

远程连通性测试 (rfirst.yaml)


---

- name: "远程主机测试"

  hosts: all



  tasks:

    - name: "测试远程连通性"

      ping:

Playbook 结构说明


---

# 剧本开始标记

- name: "剧本描述" # 剧本名称(可选)

  hosts: target_hosts # 目标主机或主机组

  become: yes # 是否使用特权提升(可选)

  become_user: root # 特权提升到的用户(可选)

  user: ubuntu # 连接用户(可选)

  gather_facts: yes # 是否收集主机信息(默认yes)



  vars: # 变量定义

    variable_name: value



  tasks: # 任务列表

    - name: "任务描述" # 任务名称

      module_name: # 模块名称

        parameter: value # 模块参数

      register: result # 保存任务结果(可选)

      when: condition # 执行条件(可选)

      notify: handler_name # 触发处理器(可选)



  handlers: # 处理器定义(可选)

    - name: "处理器名称"

      module_name:

        parameter: value


常用模块详解

1. 包管理模块 (apt)

基础用法示例 (1-builtin-apt.yml)


---

- hosts: tag_node

  become: yes

  become_user: root

  user: ubuntu



  tasks:

    # 安装单个软件包

    - name: 安装 nginx

      ansible.builtin.apt:

        name: nginx

        state: present

        update_cache: yes



    # 安装多个软件包

    - name: 安装软件包列表

      ansible.builtin.apt:

        pkg:

          - apt-transport-https

          - ca-certificates

          - lsb-release

          - gnupg

          - zip

        state: latest



    # 卸载软件包

    - name: 卸载 zip

      ansible.builtin.apt:

        name: zip

        state: absent



    # 添加 GPG 密钥

    - name: 添加 Docker GPG 密钥

      ansible.builtin.apt_key:

        url: "https://download.docker.com/linux/{{ ansible_distribution | lower }}/gpg"

        state: present



    # 添加软件源

    - name: 添加 Docker 软件源

      ansible.builtin.apt_repository:

        repo: "deb [arch={{ ansible_architecture }}] https://download.docker.com/linux/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} stable"

        state: present

        filename: docker



    # 安装 Docker

    - name: 安装 Docker

      ansible.builtin.apt:

        name:

          - docker

          - docker.io

          - docker-compose

          - docker-registry

        state: latest

        update_cache: true

apt 模块参数说明

  • name:软件包名称

  • state:包状态(present/absent/latest)

  • update_cache:是否更新包缓存

  • pkg:软件包列表

  • force:强制安装

  • purge:卸载时是否清除配置文件

2. 用户和组管理模块

示例 (2-builtin-user-group.yml)


---

- hosts: tag_node

  become: yes

  become_user: root

  user: ubuntu



  tasks:

    # 创建组

    - name: 创建 devops

      ansible.builtin.group:

        name: devops

        state: present



    # 删除组

    - name: 删除 docker

      ansible.builtin.group:

        name: docker

        state: absent



    # 创建用户

    - name: 添加用户 zhangsan

      ansible.builtin.user:

        name: zhangsan

        shell: /bin/bash

        group: devops



    # 创建用户并指定多个组

    - name: 添加用户 william

      ansible.builtin.user:

        name: william

        comment: William

        uid: 1040

        groups: sudo,admin,devops

        append: yes



    # 删除用户

    - name: 删除用户 zhangsan

      ansible.builtin.user:

        name: zhangsan

        state: absent

        remove: yes



    # 为用户生成 SSH 密钥

    - name: william 生成 SSH 密钥

      ansible.builtin.user:

        name: william

        generate_ssh_key: yes

        ssh_key_bits: 2048

        ssh_key_file: .ssh/id_rsa

user 模块主要参数

  • name:用户名

  • state:用户状态(present/absent)

  • shell:默认 shell

  • home:家目录

  • groups:附加组列表

  • append:是否追加到组(而非替换)

  • remove:删除用户时是否删除家目录

  • generate_ssh_key:是否生成 SSH 密钥

3. 文件和目录管理模块

示例 (3-builtin-file-copy.yml)


---

- hosts: tag_node

  become: yes

  become_user: root

  user: ubuntu



  vars:

    demo_files:

      - /home/ubuntu/ansible/demo1.conf

      - /home/ubuntu/ansible/demo2.conf

      - /home/ubuntu/ansible/demo3.conf

    demo_directories:

      - /home/ubuntu/ansible/1

      - /home/ubuntu/ansible/2



  tasks:

    # 创建目录

    - name: 创建目录

      ansible.builtin.file:

        path: "{{ item }}"

        state: directory

        mode: "0755"

      loop: "{{ demo_directories }}"



    # 创建文件

    - name: 创建文件

      ansible.builtin.file:

        path: "{{ item }}"

        state: touch

        mode: u=rw,g=r,o=r

      loop: "{{ demo_files }}"



    # 递归修改目录权限

    - name: 递归修改目录所有权

      ansible.builtin.file:

        path: /home/ubuntu/ansible/

        state: directory

        recurse: yes

        owner: ubuntu

        group: ubuntu



    # 修改特定文件权限

    - name: 修改文件权限

      ansible.builtin.file:

        path: /home/ubuntu/ansible/demo2.conf

        owner: william

        group: devops

        mode: "0644"



    # 删除文件

    - name: 删除文件

      ansible.builtin.file:

        path: /home/ubuntu/ansible/demo2.conf

        state: absent



    # 复制文件

    - name: 复制本地文件到远程

      ansible.builtin.copy:

        src: /etc/zshrc

        dest: /home/ubuntu/ansible/

        owner: william

        group: devops

        mode: "0644"



    # 远程复制

    - name: 远程文件复制

      ansible.builtin.copy:

        src: /home/ubuntu/ansible/zshrc

        dest: /home/ubuntu/ansible/zshrc.backup

        remote_src: yes



    # 递归删除目录

    - name: 递归删除目录

      ansible.builtin.file:

        path: /home/ubuntu/ansible/

        state: absent

file 模块参数说明

  • path:文件/目录路径

  • state:状态(file/directory/touch/absent/link)

  • mode:权限(数字或符号模式)

  • owner:所有者

  • group:所属组

  • recurse:是否递归操作

copy 模块参数说明

  • src:源文件路径

  • dest:目标路径

  • remote_src:源文件是否在远程主机

  • backup:是否备份原文件

  • force:是否强制覆盖

4. 服务管理模块

示例 (4-builtin-service-systemd.yml)


---

- hosts: tag_node

  become: yes

  become_user: root

  user: ubuntu



  tasks:

    # 停止服务

    - name: 停止 nginx 服务

      ansible.builtin.service:

        name: nginx

        state: stopped



    # 禁用服务

    - name: 禁用 nginx 服务

      ansible.builtin.service:

        name: nginx

        enabled: no



    # 启动服务

    - name: 启动 nginx 服务

      ansible.builtin.service:

        name: nginx

        state: started



    # 启用服务

    - name: 启用 nginx 服务

      ansible.builtin.service:

        name: nginx

        enabled: yes

service 模块参数

  • name:服务名称

  • state:服务状态(started/stopped/restarted/reloaded)

  • enabled:是否开机启动(yes/no)

5. 命令执行模块

示例 (5-builtin-command-shell.yml)


---

- hosts: tag_node

  user: ubuntu



  tasks:

    # 使用 command 模块

    - name: 在指定目录创建文件

      ansible.builtin.command: touch 2.txt

      args:

        chdir: /home/ubuntu/ansible/2/



    # 使用 shell 模块

    - name: 执行 shell 命令

      ansible.builtin.shell:

        cmd: |

          echo "Hello"

          ls -la ./2

        chdir: /home/ubuntu/ansible

command vs shell 模块对比

| 特性     | command | shell |

| -------- | ------- | ----- |

| 管道支持 | ❌      | ✅    |

| 重定向   | ❌      | ✅    |

| 环境变量 | ❌      | ✅    |

| 安全性   | 更高    | 较低  |

| 性能     | 更快    | 较慢  |


实战示例

完整的 Web 服务器部署 Playbook


---

- name: 部署 Web 服务器

  hosts: webservers

  become: yes

  vars:

    web_user: www-data

    web_group: www-data

    site_name: example.com

    document_root: /var/www/{{ site_name }}



  tasks:

    # 1. 更新系统

    - name: 更新包缓存

      apt:

        update_cache: yes

        cache_valid_time: 3600



    # 2. 安装必要软件

    - name: 安装 Web 服务器软件

      apt:

        pkg:

          - nginx

          - php-fpm

          - mysql-server

          - git

        state: latest



    # 3. 创建网站目录

    - name: 创建网站目录

      file:

        path: "{{ document_root }}"

        state: directory

        owner: "{{ web_user }}"

        group: "{{ web_group }}"

        mode: "0755"



    # 4. 部署网站文件

    - name: 创建测试页面

      copy:

        content: |

          <!DOCTYPE html>

          <html>

          <head>

              <title>{{ site_name }}</title>

          </head>

          <body>

              <h1>欢迎访问 {{ site_name }}</h1>

              <p>服务器时间: {{ ansible_date_time.iso8601 }}</p>

          </body>

          </html>

        dest: "{{ document_root }}/index.html"

        owner: "{{ web_user }}"

        group: "{{ web_group }}"

        mode: "0644"



    # 5. 配置 Nginx

    - name: 配置 Nginx 虚拟主机

      template:

        src: nginx-site.conf.j2

        dest: "/etc/nginx/sites-available/{{ site_name }}"

      notify: restart nginx



    # 6. 启用站点

    - name: 启用 Nginx 站点

      file:

        src: "/etc/nginx/sites-available/{{ site_name }}"

        dest: "/etc/nginx/sites-enabled/{{ site_name }}"

        state: link

      notify: restart nginx



    # 7. 启动服务

    - name: 启动并启用服务

      systemd:

        name: "{{ item }}"

        state: started

        enabled: yes

      loop:

        - nginx

        - mysql

        - php7.4-fpm



  handlers:

    - name: restart nginx

      systemd:

        name: nginx

        state: restarted

Nginx 配置模板 (templates/nginx-site.conf.j2)


server {

    listen 80;

    server_name {{ site_name }};

    root {{ document_root }};

    index index.html index.php;



    location / {

        try_files $uri $uri/ =404;

    }



    location ~ \.php$ {

        include snippets/fastcgi-php.conf;

        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;

    }



    error_log /var/log/nginx/{{ site_name }}_error.log;

    access_log /var/log/nginx/{{ site_name }}_access.log;

}


高级功能

1. Ansible Vault - 敏感数据加密

创建加密文件


# 创建新的加密文件

ansible-vault create secret.yml



# 编辑加密文件

ansible-vault edit secret.yml



# 查看加密文件

ansible-vault view secret.yml



# 加密现有文件

ansible-vault encrypt plain.yml



# 解密文件

ansible-vault decrypt secret.yml

在 Playbook 中使用加密变量


---

- hosts: localhost

  vars_files:

    - secret.yml



  tasks:

    - name: 使用加密的密码

      debug:

        msg: "数据库密码是: {{ db_password }}"

运行使用加密文件的 Playbook


# 交互式输入密码

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



# 使用密码文件

ansible-playbook --vault-password-file .vault_pass playbook.yml

2. 模板 (Templates)

Jinja2 模板示例


# 配置文件模板 (templates/app.conf.j2)

[database]

host = {{ db_host | default('localhost') }}

port = {{ db_port | default(3306) }}

name = {{ db_name }}

user = {{ db_user }}

password = {{ db_password }}



[web]

listen_port = {{ web_port | default(80) }}

workers = {{ ansible_processor_vcpus * 2 }}

debug = {{ debug_mode | default(false) | bool }}



# 生成配置文件的任务

- name: 生成应用配置文件

  template:

    src: app.conf.j2

    dest: /etc/myapp/app.conf

    owner: myapp

    group: myapp

    mode: '0600'

3. 条件执行


---

- hosts: all

  tasks:

    # 基于操作系统的条件执行

    - name: Ubuntu 上安装包

      apt:

        name: nginx

        state: present

      when: ansible_os_family == "Debian"



    - name: CentOS 上安装包

      yum:

        name: nginx

        state: present

      when: ansible_os_family == "RedHat"



    # 基于变量的条件执行

    - name: 仅在生产环境执行

      service:

        name: nginx

        state: started

      when: environment == "production"



    # 复杂条件

    - name: 复杂条件示例

      debug:

        msg: "执行此任务"

      when:

        - ansible_memory_mb.real.total > 1024

        - ansible_processor_vcpus >= 2

        - inventory_hostname in groups['webservers']

4. 循环 (Loops)


---

- hosts: all

  vars:

    users:

      - name: alice

        groups: [sudo, developers]

      - name: bob

        groups: [developers]



    packages:

      - git

      - vim

      - curl



  tasks:

    # 简单循环

    - name: 安装包列表

      apt:

        name: "{{ item }}"

        state: present

      loop: "{{ packages }}"



    # 字典循环

    - name: 创建用户

      user:

        name: "{{ item.name }}"

        groups: "{{ item.groups | join(',') }}"

        append: yes

      loop: "{{ users }}"



    # 范围循环

    - name: 创建目录

      file:

        path: "/tmp/dir{{ item }}"

        state: directory

      loop: "{{ range(1, 6) | list }}"



    # 文件循环

    - name: 复制配置文件

      copy:

        src: "{{ item }}"

        dest: "/etc/myapp/"

      with_fileglob:

        - "configs/*.conf"

5. 错误处理


---

- hosts: all

  tasks:

    # 忽略错误

    - name: 可能失败的任务

      command: /some/command

      ignore_errors: yes



    # 基于返回码决定是否失败

    - name: 检查返回码

      command: /some/command

      register: result

      failed_when: result.rc != 0 and result.rc != 2



    # 重试机制

    - name: 重试下载

      get_url:

        url: http://example.com/file.zip

        dest: /tmp/file.zip

      retries: 3

      delay: 5



    # 救援任务

    - name: 主要任务

      block:

        - name: 尝试执行的任务

          command: /risky/command

      rescue:

        - name: 失败时执行的任务

          debug:

            msg: "主要任务失败,执行救援任务"

      always:

        - name: 总是执行的任务

          debug:

            msg: "清理工作"

6. Roles - 代码重用

Role 目录结构


roles/

└── nginx/

    ├── tasks/

    │   └── main.yml

    ├── handlers/

    │   └── main.yml

    ├── templates/

    │   └── nginx.conf.j2

    ├── files/

    ├── vars/

    │   └── main.yml

    ├── defaults/

    │   └── main.yml

    └── meta/

        └── main.yml

Role 使用示例


---

- hosts: webservers

  roles:

    - nginx

    - mysql

    - { role: php, version: 7.4 }


最佳实践

1. 目录结构组织


ansible-project/

├── inventories/

│   ├── production/

│   │   ├── hosts

│   │   └── group_vars/

│   └── staging/

│       ├── hosts

│       └── group_vars/

├── roles/

├── playbooks/

├── group_vars/

├── host_vars/

├── ansible.cfg

└── requirements.yml

2. 变量管理

按环境组织变量


# 生产环境变量

inventories/production/group_vars/all.yml

inventories/production/group_vars/webservers.yml



# 测试环境变量

inventories/staging/group_vars/all.yml

inventories/staging/group_vars/webservers.yml

敏感数据处理


# 加密敏感变量

ansible-vault encrypt group_vars/all/vault.yml



# 在变量文件中引用

# group_vars/all/vars.yml

db_password: "{{ vault_db_password }}"

api_key: "{{ vault_api_key }}"

3. Playbook 编写规范

良好的 Playbook 结构


---

- name: 清晰的 Playbook 描述

  hosts: webservers

  become: yes



  # 变量定义在顶部

  vars:

    app_name: myapp

    app_version: 1.0.0



  # 预任务

  pre_tasks:

    - name: 更新包缓存

      apt:

        update_cache: yes



  # 角色

  roles:

    - common

    - nginx



  # 主要任务

  tasks:

    - name: 每个任务都有清晰的描述

      template:

        src: config.j2

        dest: /etc/myapp/config.conf

      notify: restart myapp



  # 后任务

  post_tasks:

    - name: 验证服务状态

      uri:

        url: http://{{ inventory_hostname }}

        status_code: 200



  # 处理器

  handlers:

    - name: restart myapp

      systemd:

        name: myapp

        state: restarted

4. 安全考虑

安全配置清单

  • [ ] 使用 Ansible Vault 加密敏感数据

  • [ ] 限制 sudo 权限,只在必要时使用 become

  • [ ] 使用 SSH 密钥而非密码认证

  • [ ] 定期轮换密钥和密码

  • [ ] 在生产环境启用 host_key_checking

  • [ ] 使用防火墙限制 SSH 访问

  • [ ] 定期审计 Playbook 和 Role

安全配置示例


# ansible.cfg 安全配置

[defaults]

host_key_checking = True

ask_pass = False

ask_sudo_pass = False

remote_user = ansible

private_key_file = ~/.ssh/ansible_key



[ssh_connection]

ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=yes


故障排查

1. 调试技巧

启用调试模式


# 详细输出

ansible-playbook -v playbook.yml



# 更详细输出

ansible-playbook -vv playbook.yml



# 最详细输出

ansible-playbook -vvv playbook.yml

使用 debug 模块


- name: 调试变量

  debug:

    var: ansible_facts



- name: 调试消息

  debug:

    msg: "主机名是 {{ inventory_hostname }}"



- name: 条件调试

  debug:

    msg: "这是生产环境"

  when: environment == "production"

检查模式


# 检查模式(不实际执行)

ansible-playbook --check playbook.yml



# 显示差异

ansible-playbook --check --diff playbook.yml

2. 常见问题解决

SSH 连接问题


# 测试 SSH 连接

ansible all -m ping



# 指定 SSH 密钥

ansible all -m ping --private-key ~/.ssh/mykey



# 忽略主机密钥检查

ansible all -m ping -e 'ansible_ssh_common_args="-o StrictHostKeyChecking=no"'

权限问题


# 使用 sudo

ansible all -m command -a "whoami" --become



# 指定 sudo 用户

ansible all -m command -a "whoami" --become --become-user root



# sudo 密码

ansible all -m command -a "whoami" --become --ask-become-pass

语法检查


# 检查语法

ansible-playbook --syntax-check playbook.yml



# 使用 ansible-lint

pip install ansible-lint

ansible-lint playbook.yml

3. 日志分析

启用日志


# ansible.cfg

[defaults]

log_path = /var/log/ansible.log

分析失败任务


# 查看最近的失败

grep FAILED /var/log/ansible.log



# 查看特定主机的执行结果

grep "host1" /var/log/ansible.log

4. 性能优化

并发控制


# ansible.cfg

[defaults]

forks = 10

host_key_checking = False



[ssh_connection]

pipelining = True

ssh_args = -o ControlMaster=auto -o ControlPersist=60s

事实缓存


# ansible.cfg

[defaults]

fact_caching = jsonfile

fact_caching_connection = /tmp/ansible_facts_cache

fact_caching_timeout = 3600

减少 SSH 连接


# 使用 gather_facts: no 跳过事实收集

- hosts: all

  gather_facts: no

  tasks:

    - name: 简单任务

      ping:


扩展资源

官方文档

社区资源

学习建议

  1. 逐步学习:从简单的 ad-hoc 命令开始,逐步学习 Playbook 和 Role

  2. 动手实践:在测试环境中实际操作,验证理论知识

  3. 阅读他人代码:研究 Ansible Galaxy 中的优秀 Role

  4. 关注最佳实践:始终考虑安全性、可维护性和可读性

  5. 持续学习:Ansible 在不断发展,保持学习新功能和改进


总结

Ansible 是一个功能强大且易于学习的自动化工具。通过本指南,您应该能够:

✅ 理解 Ansible 的核心概念和架构

✅ 搭建 Ansible 环境并进行基本配置

✅ 编写和执行 Playbook

✅ 使用常用模块完成系统管理任务

✅ 应用高级功能如变量、模板、条件执行等

✅ 遵循最佳实践,编写高质量的自动化代码

✅ 排查和解决常见问题

记住,熟练掌握 Ansible 需要时间和实践。建议您从简单的任务开始,逐步增加复杂性,并始终关注代码的可读性和可维护性。

祝您 Ansible 学习愉快! 🚀