Ansible教程
5分钟阅读

Ansible 基础概念

什么是 Ansible

Ansible 是一个开源的自动化运维工具,由 Red Hat 公司维护。它可以帮助我们实现:

  • 配置管理:统一管理服务器配置
  • 应用部署:自动化应用程序部署
  • 任务执行:批量执行系统任务
  • 编排协调:复杂工作流程自动化

核心特性

1. 无代理架构(Agentless)

  • 不需要在目标主机上安装客户端
  • 通过 SSH 连接进行管理
  • 减少系统资源消耗

2. 简单易用

  • 使用 YAML 语法编写配置
  • 人类可读的配置文件
  • 学习曲线平缓

3. 幂等性

  • 多次执行相同操作结果一致
  • 避免重复配置导致的问题
  • 确保系统状态的一致性

4. 模块化设计

  • 丰富的内置模块
  • 支持自定义模块开发
  • 社区贡献的模块生态

核心组件

1. Control Node(控制节点)

  • 安装 Ansible 的机器
  • 执行 Playbook 和命令
  • 管理 Inventory 和配置

2. Managed Nodes(被管理节点)

  • 被 Ansible 管理的目标主机
  • 通过 SSH 连接
  • 不需要安装 Ansible

3. Inventory(主机清单)

  • 定义被管理的主机列表
  • 支持静态和动态清单
  • 可以分组管理主机

4. Modules(模块)

  • 执行具体任务的代码单元
  • 如文件操作、服务管理等
  • 支持各种操作系统和应用

5. Playbooks(剧本)

  • 定义自动化任务的 YAML 文件
  • 包含一系列 plays 和 tasks
  • 描述期望的系统状态

6. Roles(角色)

  • 可重用的 Playbook 组件
  • 按功能组织任务和配置
  • 便于分享和维护

工作原理

graph LR
    A[Control Node] --> B[SSH Connection]
    B --> C[Managed Node 1]
    B --> D[Managed Node 2]
    B --> E[Managed Node N]
    
    A --> F[Inventory]
    A --> G[Playbook]
    A --> H[Modules]

执行流程

  1. 读取 Inventory:确定目标主机
  2. 解析 Playbook:理解要执行的任务
  3. 建立连接:通过 SSH 连接目标主机
  4. 传输模块:将 Python 模块传输到目标主机
  5. 执行任务:在目标主机上执行模块
  6. 收集结果:返回执行结果到控制节点
  7. 清理临时文件:删除临时文件

安装 Ansible

系统要求

控制节点要求:

  • Python 3.8 或更高版本
  • Linux 或 macOS 系统
  • 不支持 Windows 作为控制节点

被管理节点要求:

  • Python 2.7 或 3.5+
  • SSH 服务
  • 支持 Linux、Windows、macOS

安装方法

1. 使用包管理器安装

Ubuntu/Debian:

sudo apt update
sudo apt install ansible

CentOS/RHEL:

sudo yum install epel-release
sudo yum install ansible

macOS:

brew install ansible

2. 使用 pip 安装

# 安装最新版本
pip install ansible

# 安装指定版本
pip install ansible==6.0.0

# 升级 Ansible
pip install --upgrade ansible

3. 从源码安装

git clone https://github.com/ansible/ansible.git
cd ansible
make install

验证安装

# 查看版本信息
ansible --version

# 查看配置信息
ansible-config dump

# 测试连接
ansible localhost -m ping

基本配置

1. 配置文件位置

Ansible 按以下顺序查找配置文件:

  1. ANSIBLE_CONFIG 环境变量指定的文件
  2. 当前目录下的 ansible.cfg
  3. 用户家目录下的 ~/.ansible.cfg
  4. 系统配置文件 /etc/ansible/ansible.cfg

2. 基本配置示例

[defaults]
# 默认主机清单文件
inventory = ./inventory

# 默认远程用户
remote_user = ansible

# SSH 私钥文件
private_key_file = ~/.ssh/id_rsa

# 禁用主机密钥检查
host_key_checking = False

# 并发连接数
forks = 10

# 日志文件
log_path = ./ansible.log

[ssh_connection]
# SSH 连接超时时间
timeout = 30

# 启用 SSH 管道
pipelining = True

3. 环境变量

# 配置文件路径
export ANSIBLE_CONFIG=/path/to/ansible.cfg

# 主机清单文件
export ANSIBLE_INVENTORY=/path/to/inventory

# 远程用户
export ANSIBLE_REMOTE_USER=ansible

# SSH 私钥
export ANSIBLE_PRIVATE_KEY_FILE=~/.ssh/id_rsa

第一个 Ansible 命令

1. 创建主机清单

# inventory 文件
[webservers]
web1.example.com
web2.example.com

[databases]
db1.example.com
db2.example.com

[all:vars]
ansible_user=ansible
ansible_ssh_private_key_file=~/.ssh/id_rsa

2. 测试连接

# 测试所有主机连接
ansible all -m ping

# 测试特定组
ansible webservers -m ping

# 测试单个主机
ansible web1.example.com -m ping

3. 执行简单命令

# 查看系统信息
ansible all -m setup

# 执行 shell 命令
ansible webservers -m shell -a "uptime"

# 安装软件包
ansible webservers -m yum -a "name=nginx state=present" --become

Ansible 与其他工具对比

1. Ansible vs Puppet

特性AnsiblePuppet
架构无代理需要代理
配置语言YAMLRuby DSL
学习曲线平缓陡峭
执行方式推送模式拉取模式
适用场景快速部署、临时任务大规模配置管理

2. Ansible vs Chef

特性AnsibleChef
配置复杂度简单复杂
代理要求无需代理需要代理
配置文件YAMLRuby
社区支持活跃活跃
企业支持Red HatProgress

3. Ansible vs SaltStack

# Ansible 示例
- name: Install nginx
  yum:
    name: nginx
    state: present

# SaltStack 示例(对比)
# nginx:
#   pkg.installed

实际应用场景

1. 基础设施即代码(IaC)

# infrastructure.yml
---
- name: Infrastructure as Code
  hosts: localhost
  tasks:
    - name: Create AWS EC2 instances
      ec2:
        key_name: mykey
        instance_type: t2.micro
        image: ami-12345678
        wait: yes
        count: 3
        vpc_subnet_id: subnet-12345678
        assign_public_ip: yes
        
    - name: Add instances to inventory
      add_host:
        name: "{{ item.public_ip }}"
        groups: webservers
      loop: "{{ ec2.instances }}"

2. 配置漂移检测

# drift_detection.yml
---
- name: Configuration drift detection
  hosts: all
  tasks:
    - name: Check nginx configuration
      stat:
        path: /etc/nginx/nginx.conf
        checksum_algorithm: md5
      register: nginx_config
      
    - name: Compare with baseline
      fail:
        msg: "Configuration drift detected!"
      when: nginx_config.stat.checksum != expected_checksum

3. 灾难恢复自动化

# disaster_recovery.yml
---
- name: Disaster recovery procedure
  hosts: backup_servers
  serial: 1
  tasks:
    - name: Stop application services
      service:
        name: "{{ item }}"
        state: stopped
      loop: "{{ app_services }}"
      
    - name: Restore from backup
      unarchive:
        src: "{{ backup_location }}/{{ backup_file }}"
        dest: "{{ app_directory }}"
        remote_src: yes
        
    - name: Start services
      service:
        name: "{{ item }}"
        state: started
      loop: "{{ app_services }}"

开发环境搭建

1. 使用 Vagrant 搭建测试环境

# Vagrantfile
Vagrant.configure("2") do |config|
  # 定义多个虚拟机
  (1..3).each do |i|
    config.vm.define "web#{i}" do |web|
      web.vm.box = "centos/7"
      web.vm.network "private_network", ip: "192.168.56.#{10+i}"
      web.vm.hostname = "web#{i}.local"
      
      # 配置 SSH
      web.vm.provision "shell", inline: <<-SHELL
        # 添加 ansible 用户
        useradd ansible
        echo "ansible ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/ansible
        
        # 配置 SSH 密钥
        mkdir -p /home/ansible/.ssh
        echo "ssh-rsa AAAAB3NzaC1yc2E..." > /home/ansible/.ssh/authorized_keys
        chown -R ansible:ansible /home/ansible/.ssh
        chmod 700 /home/ansible/.ssh
        chmod 600 /home/ansible/.ssh/authorized_keys
      SHELL
    end
  end
end

2. Docker 测试环境

# Dockerfile.ansible-target
FROM centos:7

# 安装 SSH 和 Python
RUN yum update -y && \
    yum install -y openssh-server python3 sudo && \
    yum clean all

# 配置 SSH
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N '' && \
    ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N '' && \
    ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ''

# 创建 ansible 用户
RUN useradd -m ansible && \
    echo "ansible ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/ansible && \
    mkdir -p /home/ansible/.ssh

# 复制公钥
COPY ansible_rsa.pub /home/ansible/.ssh/authorized_keys
RUN chown -R ansible:ansible /home/ansible/.ssh && \
    chmod 700 /home/ansible/.ssh && \
    chmod 600 /home/ansible/.ssh/authorized_keys

EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
# 构建和运行测试容器
docker build -t ansible-target -f Dockerfile.ansible-target .
docker run -d --name test-node1 -p 2221:22 ansible-target
docker run -d --name test-node2 -p 2222:22 ansible-target

3. 测试清单配置

# test-inventory
[test_nodes]
test-node1 ansible_host=localhost ansible_port=2221 ansible_user=ansible
test-node2 ansible_host=localhost ansible_port=2222 ansible_user=ansible

[test_nodes:vars]
ansible_ssh_private_key_file=~/.ssh/ansible_rsa
ansible_ssh_common_args='-o StrictHostKeyChecking=no'

企业级部署考虑

1. 高可用性配置

# ha_setup.yml
---
- name: Setup Ansible Tower HA
  hosts: tower_nodes
  tasks:
    - name: Install PostgreSQL cluster
      include_role:
        name: postgresql_ha
        
    - name: Configure shared storage
      mount:
        path: /var/lib/awx
        src: "{{ nfs_server }}:/var/lib/awx"
        fstype: nfs
        state: mounted
        
    - name: Setup load balancer
      template:
        src: haproxy.cfg.j2
        dest: /etc/haproxy/haproxy.cfg
      notify: restart haproxy

2. 监控集成

# monitoring.yml
---
- name: Setup monitoring
  hosts: ansible_controllers
  tasks:
    - name: Install Prometheus node exporter
      unarchive:
        src: https://github.com/prometheus/node_exporter/releases/download/v1.3.1/node_exporter-1.3.1.linux-amd64.tar.gz
        dest: /opt
        remote_src: yes
        
    - name: Create systemd service
      template:
        src: node_exporter.service.j2
        dest: /etc/systemd/system/node_exporter.service
      notify: 
        - reload systemd
        - start node_exporter
        
    - name: Configure Ansible callback plugins
      lineinfile:
        path: /etc/ansible/ansible.cfg
        regexp: '^callback_whitelist'
        line: 'callback_whitelist = profile_tasks, timer, log_plays'

小结

本章我们学习了:

  1. Ansible 基本概念:了解了什么是 Ansible 及其核心特性
  2. 架构组件:掌握了控制节点、被管理节点等核心组件
  3. 工作原理:理解了 Ansible 的执行流程
  4. 安装配置:学会了如何安装和配置 Ansible
  5. 基本使用:执行了第一个 Ansible 命令
  6. 工具对比:了解了 Ansible 与其他自动化工具的区别
  7. 应用场景:掌握了实际工作中的应用场景
  8. 开发环境:学会了搭建测试和开发环境
  9. 企业部署:了解了企业级部署的考虑因素

下一章我们将学习如何管理 Inventory 主机清单,这是使用 Ansible 的基础。