跳转至

27- 自动化与脚本编写(Shell + Ansible) 🤖

前提条件 ✅

  • 已完成云 CLI 工具安装与基本配置(AWS CLI / Azure CLI / gcloud)
  • 以 ops 用户登录(具有 sudo 权限)
  • 系统运行在 Debian 12 Bookworm
  • 建议准备至少 2–3 台测试机(虚拟机或云实例),用于 Ansible 控制节点与被管理节点
  • 全局约定:主机名 LinuxDC,IP 192.168.1.100(控制节点)

详细步骤 🛠️

  1. Shell 脚本基础强化(生产级写法)

推荐模板(带错误处理、日志、参数检查):

#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'

# 日志函数
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a /var/log/my-script.log; }

usage() {
    echo "Usage: $0 [install|update|backup]"
    exit 1
}

# 参数检查
[[ $# -eq 0 ]] && usage

case $1 in
    install)
        log "开始安装..."
        sudo apt update && sudo apt install -y nginx
        log "安装完成"
        ;;
    update)
        log "开始更新系统..."
        sudo apt update && sudo apt full-upgrade -y && sudo apt autoremove -y
        log "更新完成"
        ;;
    backup)
        log "开始备份 /data..."
        rsync -avz --delete /data/ /backup/data-$(date +%Y%m%d)/
        log "备份完成"
        ;;
    *) usage ;;
esac

保存为 /opt/scripts/sys-mgmt.sh,添加执行权限:

chmod +x /opt/scripts/sys-mgmt.sh

  1. Ansible 安装与基础配置

安装:

sudo apt update
sudo apt install -y ansible
ansible --version

创建项目目录结构(推荐):

mkdir -p ~/ansible/{inventory,playbooks,roles,group_vars,host_vars}
cd ~/ansible

库存文件(inventory/hosts):

[webservers]
192.168.1.101 ansible_user=ops ansible_ssh_private_key_file=~/.ssh/id_ed25519

[dbservers]
192.168.1.102 ansible_user=ops ansible_ssh_private_key_file=~/.ssh/id_ed25519

[all:vars]
ansible_python_interpreter=/usr/bin/python3

测试连接:

ansible all -m ping
# 预期输出:SUCCESS

  1. 第一个 Ansible Playbook(安装 Nginx 并配置)

创建 playbooks/install-nginx.yml:

---
- name: Install and configure Nginx
  hosts: webservers
  become: yes
  vars:
    http_port: 80
    https_port: 443

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

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

    - name: Ensure Nginx is enabled and started
      systemd:
        name: nginx
        enabled: yes
        state: started

    - name: Copy custom index.html
      copy:
        content: "<h1>Welcome from {{ inventory_hostname }}</h1>"
        dest: /var/www/html/index.html
        mode: '0644'

    - name: Allow Nginx in ufw
      ufw:
        rule: allow
        name: 'Nginx Full'
      notify: Reload ufw

  handlers:
    - name: Reload ufw
      ufw:
        state: reloaded

执行:

ansible-playbook -i inventory/hosts playbooks/install-nginx.yml

  1. 角色(Roles)结构化管理(生产推荐)

创建角色:

ansible-galaxy init roles/common

在 roles/common/tasks/main.yml 中添加通用任务(如用户创建、时区设置、基础包安装)。

使用角色:

- name: Apply common configuration
  hosts: all
  become: yes
  roles:
    - common

  1. 变量管理与加密(Vault)

创建 group_vars/all.yml:

timezone: Asia/Seoul
common_packages:
  - vim
  - htop
  - curl
  - git

加密敏感变量:

ansible-vault create group_vars/secrets.yml
# 输入 vault 密码,然后添加:
db_password: SuperSecret123!

使用 vault:

ansible-playbook site.yml --vault-id @prompt

实践任务 🎯

  1. 编写一个带参数和日志的 Shell 脚本,实现系统更新 + 备份 /data
  2. 在控制节点安装 Ansible,创建 inventory 文件,ping 测试至少两台被管节点
  3. 编写并执行 install-nginx.yml playbook,在目标机器上安装并启动 Nginx
  4. 创建一个简单角色 common,包含安装 htop、设置时区为 Asia/Seoul、创建 ops 用户等任务

自测问题 ❓

  1. Shell 脚本中 set -euo pipefail 的作用是什么?
  2. Ansible 中 inventory 文件的 [webservers] 组和 all:vars 的区别是什么?
  3. ansible-vault 的主要用途是什么?如何在 playbook 中安全使用加密变量?
  4. 为什么生产环境中推荐使用 roles 而不是把所有任务写在一个 playbook 里?

总结 📌

Shell 脚本适合快速、单机任务;Ansible 提供无代理、幂等、可读性强的批量自动化能力,是现代运维核心工具。
本章建立了从简单脚本到结构化 playbook + roles 的完整自动化基础,后续镜像构建(Packer)、系统迁移、Git 管理都将大量依赖 Ansible。