27- 自动化与脚本编写(Shell + Ansible) 🤖
前提条件 ✅
- 已完成云 CLI 工具安装与基本配置(AWS CLI / Azure CLI / gcloud)
- 以 ops 用户登录(具有 sudo 权限)
- 系统运行在 Debian 12 Bookworm
- 建议准备至少 2–3 台测试机(虚拟机或云实例),用于 Ansible 控制节点与被管理节点
- 全局约定:主机名 LinuxDC,IP 192.168.1.100(控制节点)
详细步骤 🛠️
- 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
- 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
- 第一个 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
- 角色(Roles)结构化管理(生产推荐)
创建角色:
ansible-galaxy init roles/common
在 roles/common/tasks/main.yml 中添加通用任务(如用户创建、时区设置、基础包安装)。
使用角色:
- name: Apply common configuration
hosts: all
become: yes
roles:
- common
- 变量管理与加密(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
实践任务 🎯
- 编写一个带参数和日志的 Shell 脚本,实现系统更新 + 备份 /data
- 在控制节点安装 Ansible,创建 inventory 文件,ping 测试至少两台被管节点
- 编写并执行 install-nginx.yml playbook,在目标机器上安装并启动 Nginx
- 创建一个简单角色 common,包含安装 htop、设置时区为 Asia/Seoul、创建 ops 用户等任务
自测问题 ❓
- Shell 脚本中
set -euo pipefail的作用是什么? - Ansible 中 inventory 文件的 [webservers] 组和 all:vars 的区别是什么?
- ansible-vault 的主要用途是什么?如何在 playbook 中安全使用加密变量?
- 为什么生产环境中推荐使用 roles 而不是把所有任务写在一个 playbook 里?
总结 📌
Shell 脚本适合快速、单机任务;Ansible 提供无代理、幂等、可读性强的批量自动化能力,是现代运维核心工具。
本章建立了从简单脚本到结构化 playbook + roles 的完整自动化基础,后续镜像构建(Packer)、系统迁移、Git 管理都将大量依赖 Ansible。