Ansible自动化运维入门:从手工到批量部署

本文介绍Ansible基础概念、安装配置、常用模块,以及实战批量部署案例。

前言

管理1台服务器,手工操作没问题。

管理10台服务器,写脚本能应付。

管理100台服务器,必须用自动化工具。

Ansible是最流行的自动化运维工具之一,无需在目标机器安装Agent,基于SSH即可工作。

今天来入门Ansible。


一、Ansible简介

1.1 为什么选择Ansible

特点 说明
无Agent 基于SSH,目标机器无需安装客户端
YAML语法 Playbook易读易写
幂等性 多次执行结果一致
模块丰富 几千个现成模块
推送模式 从控制机推送到目标机

1.2 Ansible架构

复制代码
    ┌─────────────────┐
    │   控制机         │
    │   (Ansible)     │
    └────────┬────────┘
             │ SSH
    ┌────────┴────────┐
    │                 │
    ↓                 ↓
┌─────────┐     ┌─────────┐
│ 目标机1  │     │ 目标机2  │
│ (被管理) │     │ (被管理) │
└─────────┘     └─────────┘

核心组件:

  • Inventory:主机清单
  • Module:执行模块
  • Playbook:剧本(任务编排)
  • Role:角色(可复用的Playbook集合)

二、安装配置

2.1 安装Ansible

bash 复制代码
# Ubuntu/Debian
apt update
apt install ansible

# CentOS/RHEL
yum install epel-release
yum install ansible

# pip安装(推荐,版本更新)
pip install ansible

# 验证
ansible --version

2.2 配置SSH免密登录

bash 复制代码
# 生成密钥(如果没有)
ssh-keygen -t rsa -b 4096

# 复制公钥到目标机器
ssh-copy-id user@192.168.1.10
ssh-copy-id user@192.168.1.11
ssh-copy-id user@192.168.1.12

# 测试
ssh user@192.168.1.10

2.3 配置Inventory

ini 复制代码
# /etc/ansible/hosts 或 ./inventory

# 单个主机
192.168.1.10

# 主机组
[webservers]
192.168.1.10
192.168.1.11
192.168.1.12

[dbservers]
192.168.1.20 ansible_user=mysql

# 带变量
[webservers:vars]
ansible_user=deploy
ansible_port=22

# 组嵌套
[production:children]
webservers
dbservers

2.4 ansible.cfg配置

ini 复制代码
# ./ansible.cfg 或 /etc/ansible/ansible.cfg

[defaults]
inventory = ./inventory
remote_user = deploy
private_key_file = ~/.ssh/id_rsa
host_key_checking = False
timeout = 30

[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = False

三、Ad-Hoc命令

3.1 基本语法

bash 复制代码
ansible <主机/组> -m <模块> -a "<参数>"

3.2 常用示例

bash 复制代码
# 测试连通性
ansible all -m ping

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

# 查看内存
ansible webservers -m shell -a "free -h"

# 复制文件
ansible webservers -m copy -a "src=/tmp/file.txt dest=/tmp/file.txt"

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

# 管理服务
ansible webservers -m service -a "name=nginx state=started" --become

# 创建用户
ansible webservers -m user -a "name=deploy state=present" --become

四、常用模块

4.1 文件操作

yaml 复制代码
# copy - 复制文件
- copy:
    src: /local/file
    dest: /remote/file
    owner: root
    mode: '0644'

# file - 文件/目录管理
- file:
    path: /data/app
    state: directory
    owner: deploy
    mode: '0755'

# template - 模板渲染
- template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf

# lineinfile - 修改文件行
- lineinfile:
    path: /etc/hosts
    line: "192.168.1.100 myserver"
    state: present

4.2 软件管理

yaml 复制代码
# apt - Debian系
- apt:
    name: nginx
    state: present
    update_cache: yes

# yum - RedHat系
- yum:
    name: nginx
    state: present

# pip - Python包
- pip:
    name: flask
    state: present
    virtualenv: /opt/app/venv

4.3 服务管理

yaml 复制代码
# service/systemd
- systemd:
    name: nginx
    state: started
    enabled: yes
    daemon_reload: yes

4.4 用户管理

yaml 复制代码
# user
- user:
    name: deploy
    groups: sudo
    shell: /bin/bash
    state: present

# authorized_key
- authorized_key:
    user: deploy
    key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"

五、Playbook编写

5.1 基本结构

yaml 复制代码
# deploy.yml
---
- name: Deploy Web Application
  hosts: webservers
  become: yes
  vars:
    app_name: myapp
    app_port: 8080

  tasks:
    - name: Install required packages
      apt:
        name:
          - nginx
          - python3
          - python3-pip
        state: present
        update_cache: yes

    - name: Create app directory
      file:
        path: /opt/{{ app_name }}
        state: directory
        owner: deploy
        mode: '0755'

    - name: Copy application files
      copy:
        src: ./app/
        dest: /opt/{{ app_name }}/
        owner: deploy

    - name: Start nginx
      systemd:
        name: nginx
        state: started
        enabled: yes

5.2 执行Playbook

bash 复制代码
# 执行
ansible-playbook deploy.yml

# 检查语法
ansible-playbook deploy.yml --syntax-check

# 预演(不真正执行)
ansible-playbook deploy.yml --check

# 指定主机
ansible-playbook deploy.yml --limit webservers

# 显示详细信息
ansible-playbook deploy.yml -v  # -vv, -vvv更详细

5.3 变量

yaml 复制代码
# 在Playbook中定义
vars:
  http_port: 80
  app_name: myapp

# 在变量文件中
vars_files:
  - vars/main.yml

# 命令行传入
ansible-playbook deploy.yml -e "http_port=8080"

# 使用变量
tasks:
  - name: Configure port
    template:
      src: config.j2
      dest: /etc/app/config
    vars:
      port: "{{ http_port }}"

5.4 条件判断

yaml 复制代码
tasks:
  - name: Install nginx on Debian
    apt:
      name: nginx
    when: ansible_os_family == "Debian"

  - name: Install nginx on RedHat
    yum:
      name: nginx
    when: ansible_os_family == "RedHat"

5.5 循环

yaml 复制代码
tasks:
  - name: Install packages
    apt:
      name: "{{ item }}"
      state: present
    loop:
      - nginx
      - vim
      - git

  - name: Create users
    user:
      name: "{{ item.name }}"
      groups: "{{ item.groups }}"
    loop:
      - { name: 'user1', groups: 'sudo' }
      - { name: 'user2', groups: 'docker' }

5.6 Handler

yaml 复制代码
tasks:
  - name: Update nginx config
    template:
      src: nginx.conf.j2
      dest: /etc/nginx/nginx.conf
    notify: Restart nginx

handlers:
  - name: Restart nginx
    systemd:
      name: nginx
      state: restarted

六、实战案例

6.1 批量初始化服务器

yaml 复制代码
# init_server.yml
---
- name: Initialize Servers
  hosts: all
  become: yes

  tasks:
    - name: Update apt cache
      apt:
        update_cache: yes
        cache_valid_time: 3600

    - name: Install basic packages
      apt:
        name:
          - vim
          - curl
          - wget
          - htop
          - git
          - net-tools
        state: present

    - name: Set timezone
      timezone:
        name: Asia/Shanghai

    - name: Configure sysctl
      sysctl:
        name: "{{ item.key }}"
        value: "{{ item.value }}"
        sysctl_set: yes
      loop:
        - { key: 'net.core.somaxconn', value: '65535' }
        - { key: 'vm.swappiness', value: '10' }

    - name: Create deploy user
      user:
        name: deploy
        groups: sudo
        shell: /bin/bash

    - name: Set up SSH key for deploy user
      authorized_key:
        user: deploy
        key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"

6.2 部署Nginx + 应用

yaml 复制代码
# deploy_app.yml
---
- name: Deploy Application
  hosts: webservers
  become: yes
  vars:
    app_name: myapp
    app_port: 8080

  tasks:
    - name: Install Nginx
      apt:
        name: nginx
        state: present

    - name: Configure Nginx
      template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/sites-available/{{ app_name }}
      notify: Restart nginx

    - name: Enable site
      file:
        src: /etc/nginx/sites-available/{{ app_name }}
        dest: /etc/nginx/sites-enabled/{{ app_name }}
        state: link

    - name: Deploy application
      copy:
        src: app/
        dest: /opt/{{ app_name }}/

    - name: Install dependencies
      pip:
        requirements: /opt/{{ app_name }}/requirements.txt
        virtualenv: /opt/{{ app_name }}/venv

  handlers:
    - name: Restart nginx
      systemd:
        name: nginx
        state: restarted

6.3 组网批量部署

如果你的服务器分布在不同地点,可以先用组网软件(如星空组网)连接起来,然后通过组网的虚拟IP进行Ansible管理:

ini 复制代码
# inventory
[remote_servers]
10.10.0.1 ansible_host=10.10.0.1  # 组网虚拟IP
10.10.0.2 ansible_host=10.10.0.2
10.10.0.3 ansible_host=10.10.0.3

[remote_servers:vars]
ansible_user=deploy

这样即使服务器没有公网IP,也能通过组网进行批量管理,非常方便。


七、Role组织

7.1 Role结构

复制代码
roles/
└── nginx/
    ├── tasks/
    │   └── main.yml
    ├── handlers/
    │   └── main.yml
    ├── templates/
    │   └── nginx.conf.j2
    ├── files/
    ├── vars/
    │   └── main.yml
    └── defaults/
        └── main.yml

7.2 使用Role

yaml 复制代码
# site.yml
---
- hosts: webservers
  become: yes
  roles:
    - nginx
    - php
    - mysql

7.3 Ansible Galaxy

bash 复制代码
# 搜索Role
ansible-galaxy search nginx

# 安装Role
ansible-galaxy install geerlingguy.nginx

# 列出已安装
ansible-galaxy list

八、最佳实践

8.1 目录结构

复制代码
project/
├── ansible.cfg
├── inventory/
│   ├── production
│   └── staging
├── group_vars/
│   ├── all.yml
│   └── webservers.yml
├── host_vars/
│   └── 192.168.1.10.yml
├── roles/
│   ├── common/
│   └── nginx/
├── playbooks/
│   ├── deploy.yml
│   └── init.yml
└── templates/

8.2 安全建议

bash 复制代码
# 使用Ansible Vault加密敏感信息
ansible-vault create secrets.yml
ansible-vault edit secrets.yml

# 使用加密变量
ansible-playbook deploy.yml --ask-vault-pass

# 或使用密码文件
ansible-playbook deploy.yml --vault-password-file ~/.vault_pass

8.3 调试技巧

yaml 复制代码
# 打印变量
- debug:
    var: ansible_facts

# 打印消息
- debug:
    msg: "The value is {{ my_var }}"

# 注册结果
- shell: whoami
  register: result

- debug:
    var: result.stdout

九、总结

Ansible入门要点:

  1. 基础概念:Inventory、Module、Playbook、Role
  2. SSH免密:Ansible基于SSH,先配置好免密登录
  3. Ad-Hoc:简单任务用命令行
  4. Playbook:复杂任务用YAML编排
  5. 幂等性:多次执行结果一致
  6. 模块化:用Role组织可复用的配置

常用命令速查:

bash 复制代码
# 测试连通性
ansible all -m ping

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

# 执行Playbook
ansible-playbook deploy.yml

# 检查语法
ansible-playbook deploy.yml --syntax-check

# 预演
ansible-playbook deploy.yml --check

参考资料

  1. Ansible官方文档:https://docs.ansible.com/
  2. Ansible Galaxy:https://galaxy.ansible.com/
  3. 《Ansible权威指南》

💡 建议:从简单的Ad-Hoc命令开始,熟练后再写Playbook。不要一开始就追求完美的Role结构。

相关推荐
Hard but lovely6 小时前
linux:----进程守护化(Daemon)&&会话的原理
linux·运维·服务器
吕了了7 小时前
86 [深度解析] 系统的产生依赖于什么?
运维·windows·电脑·系统
IDC02_FEIYA7 小时前
Windows 服务器任务管理器用户客户端名怎么修改?Windows 10修改电脑设备名称
运维·服务器·windows
Trouvaille ~7 小时前
【Linux】虚拟内存揭秘:地址空间的魔法
linux·运维·服务器·系统·入门·虚拟内存·进程地址空间
木子欢儿7 小时前
Debian 13安装rime中文输入法
linux·运维·服务器·debian
科立分板机源头厂家7 小时前
第51集科立分板机:选择适合PCB板切割的全自动激光分板机?
自动化·分板机·激光分板机·科立分板机·pcb分板机
Trouvaille ~7 小时前
【Linux】进程等待与资源回收:父进程的责任
linux·运维·服务器·进程等待·进程退出·非阻塞与阻塞·资源回收
木子欢儿7 小时前
Ubuntu24.04 安装rime中文输入法
linux·运维·服务器
liuwei2000008 小时前
Ubuntu 22.04 安装 ROS 2 Humble
linux·运维·ubuntu