管理 1 台 VPS 靠手动,管理 10 台 VPS 靠脚本,管理 50 台 VPS 必须上自动化工具。我用 Ansible 实现了批量部署、配置管理、应用发布,50 台服务器同时操作只需 1 分钟。今天把完整实战方案分享出来。
一、为什么选择 Ansible
对比其他工具:
- Ansible – 无需客户端,SSH 即可,学习曲线平缓
- Puppet – 需要客户端,配置复杂
- Chef – Ruby 语法,学习成本高
- SaltStack – 功能强大但较重
Ansible 优势:
- 无需在目标服务器安装任何软件
- Playbook 语法简单,YAML 格式
- 模块丰富,覆盖常见运维场景
- 幂等性设计,重复执行安全
二、环境准备
控制节点(你的本地电脑或跳板机):
# 安装 Ansible
apt install ansible -y # Ubuntu/Debian
yum install ansible -y # CentOS
# 验证安装
ansible --version
# 创建工作组目录
mkdir -p ~/ansible/{inventory,playbooks,roles}
目标节点(所有要管理的 VPS):
- Linux 系统(Ubuntu/CentOS)
- 开启 SSH 服务
- 确保 Python 已安装(大部分系统默认有)
三、配置 SSH 免密登录
步骤 1:生成 SSH 密钥对
ssh-keygen -t ed25519 -C "ansible-deploy"
步骤 2:分发公钥到所有服务器
# 创建主机列表 cat > ~/ansible/inventory/hosts.ini << 'EOF' [webservers] web1.example.com ansible_user=root web2.example.com ansible_user=root [dbservers] db1.example.com ansible_user=root [all:vars] ansible_ssh_private_key_file=~/.ssh/id_ed25519 EOF # 批量分发公钥 ssh-copy-id -i ~/.ssh/id_ed25519.pub [email protected] ssh-copy-id -i ~/.ssh/id_ed25519.pub [email protected] ssh-copy-id -i ~/.ssh/id_ed25519.pub [email protected]
步骤 3:测试连通性
cd ~/ansible ansible all -i inventory/hosts.ini -m ping # 应看到所有服务器返回 SUCCESS
四、第一个 Playbook:批量安装 Nginx
创建 playbook:
cat > ~/ansible/playbooks/install_nginx.yml << 'EOF'
---
- name: 安装 Nginx Web 服务器
hosts: webservers
become: yes
tasks:
- name: 更新 apt 缓存(Ubuntu)
apt:
update_cache: yes
cache_valid_time: 3600
when: ansible_os_family == "Debian"
- name: 安装 Nginx(Ubuntu/Debian)
apt:
name: nginx
state: present
when: ansible_os_family == "Debian"
- name: 安装 Nginx(CentOS/RHEL)
yum:
name: nginx
state: present
when: ansible_os_family == "RedHat"
- name: 启动 Nginx 服务
systemd:
name: nginx
state: started
enabled: yes
- name: 创建测试页面
copy:
content: |
欢迎访问 {{ inventory_hostname }}
服务器由 Ansible 自动部署
dest: /var/www/html/index.html
- name: 配置防火墙
ufw:
rule: allow
port: "{{ item }}"
loop:
- "80/tcp"
- "443/tcp"
when: ansible_os_family == "Debian"
EOF
执行 playbook:
cd ~/ansible ansible-playbook -i inventory/hosts.ini playbooks/install_nginx.yml # 查看执行结果 # 应显示:ok=6, changed=5(首次执行) # 再次执行:ok=6, changed=0(幂等性验证)
五、实战:批量部署 WordPress
创建 WordPress 部署 playbook:
cat > ~/ansible/playbooks/deploy_wordpress.yml << 'EOF'
---
- name: 批量部署 WordPress
hosts: webservers
become: yes
vars:
wp_domain: "{{ domain | default('example.com') }}"
wp_db_name: wordpress
wp_db_user: wpuser
wp_db_password: "{{ lookup('password', '/dev/null length=16 chars=ascii_letters,digits') }}"
wp_root: /var/www/wordpress
tasks:
- name: 安装 LNMP 环境
apt:
name:
- nginx
- mysql-server
- php-fpm
- php-mysql
- php-curl
- php-gd
- php-mbstring
- php-xml
state: present
update_cache: yes
- name: 创建 WordPress 数据库
mysql_db:
name: "{{ wp_db_name }}"
state: present
login_unix_socket: /var/run/mysqld/mysqld.sock
- name: 创建 WordPress 数据库用户
mysql_user:
name: "{{ wp_db_user }}"
password: "{{ wp_db_password }}"
priv: "{{ wp_db_name }}.*:ALL"
host: localhost
state: present
login_unix_socket: /var/run/mysqld/mysqld.sock
- name: 下载 WordPress
get_url:
url: https://wordpress.org/latest.tar.gz
dest: /tmp/wordpress.tar.gz
mode: '0644'
- name: 解压 WordPress
unarchive:
src: /tmp/wordpress.tar.gz
dest: /tmp/
remote_src: yes
- name: 移动 WordPress 到网站目录
copy:
src: "/tmp/wordpress/"
dest: "{{ wp_root }}"
remote_src: yes
owner: www-data
group: www-data
mode: '0755'
- name: 配置 Nginx
template:
src: templates/nginx_wordpress.conf.j2
dest: /etc/nginx/sites-available/{{ wp_domain }}
notify: restart nginx
- name: 启用站点
file:
src: /etc/nginx/sites-available/{{ wp_domain }}
dest: /etc/nginx/sites-enabled/{{ wp_domain }}
state: link
notify: restart nginx
- name: 创建 wp-config.php
template:
src: templates/wp-config.php.j2
dest: "{{ wp_root }}/wp-config.php"
owner: www-data
group: www-data
mode: '0644'
handlers:
- name: restart nginx
systemd:
name: nginx
state: restarted
EOF
六、Variables 和 Templates
创建变量文件:
cat > ~/ansible/inventory/group_vars/webservers.yml << 'EOF' --- # 通用配置 ntp_timezone: Asia/Shanghai admin_email: [email protected] # WordPress 配置 wp_domain: "{{ inventory_hostname }}" wp_title: "{{ inventory_hostname }} 博客" wp_admin_user: admin wp_admin_email: "{{ admin_email }}" EOF
创建模板文件 templates/wp-config.php.j2:
七、Roles:组织复杂项目
创建 Role 结构:
mkdir -p ~/ansible/roles/nginx/{tasks,handlers,templates,files,vars,meta} # 创建目录结构后的效果: roles/ └── nginx/ ├── tasks/ │ └── main.yml ├── handlers/ │ └── main.yml ├── templates/ │ └── nginx.conf.j2 ├── files/ ├── vars/ │ └── main.yml └── meta/ └── main.yml编写 tasks/main.yml:
--- - name: 安装 Nginx 包 apt: name: nginx state: present - name: 复制配置文件 template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf notify: restart nginx - name: 启动 Nginx systemd: name: nginx state: started enabled: yes使用 Role:
cat > ~/ansible/playbooks/deploy_all.yml << 'EOF' --- - name: 部署所有服务 hosts: all become: yes roles: - nginx - mysql - wordpress - php EOF八、我踩过的坑
坑 1:权限问题导致 playbook 失败
Ansible 默认用当前用户 SSH,如果目标服务器需要 root 权限,需要配置become: yes。
坑 2:模板变量未定义报错
使用 default 过滤器或 group_vars 定义默认值,避免变量缺失。
坑 3:大文件传输慢
使用synchronize 模块代替copy 模块,基于 rsync,速度更快。
坑 4:并发过高导致目标服务器压力大
在 ansible.cfg 中调整 forks 参数:forks = 10(默认是 5)。
九、高级技巧
1. 动态Inventory(云环境)
# 阿里云动态 Inventory cat > ~/ansible/inventory/alicloud.py << 'EOF' #!/usr/bin/env python import json # 调用阿里云 API 获取实例列表 print(json.dumps({"alicloud_ecs": {"hosts": ["192.168.1.10", "192.168.1.11"]}})) EOF chmod +x ~/ansible/inventory/alicloud.py # 使用 ansible-playbook -i inventory/alicloud.py playbooks/deploy.yml2. 加密敏感数据(Ansible Vault)
# 创建加密文件 ansible-vault create secrets.yml # 编辑加密文件 ansible-vault edit secrets.yml # 执行时使用Vault 密码 ansible-playbook -i inventory/hosts.ini playbooks/deploy.yml --ask-vault-pass3. 并行执行优化
# 修改 ansible.cfg [defaults] forks = 20 # 并发数 timeout = 30 # 超时时间 retry_files_enabled = False # 禁用重试文件 [ssh_connection] pipelining = True # 管道模式,减少 SSH 连接数 control_path = /tmp/ansible-%%r@%%h:%%p十、CI/CD集成
将 Ansible 集成到 GitHub Actions:
name: Deploy with Ansible on: push: branches: [ main ] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Setup Ansible run: pip install ansible - name: Configure SSH run: | mkdir -p ~/.ssh echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa ssh-keyscan -H your-server.com >> ~/.ssh/known_hosts - name: Run Ansible Playbook run: | cd ansible ansible-playbook -i inventory/hosts.ini playbooks/deploy.yml总结
用 Ansible 管理 VPS 后,我的运维效率提升显著:
- ✅ 50 台服务器批量部署从 1 天缩短到 5 分钟
- ✅ 配置统一,避免人为错误
- ✅ 所有操作可追溯(Git 管理 Playbook)
- ✅ 新服务器 5 分钟上线
- ✅ 支持回滚和版本控制
如果你管理 3 台以上 VPS,强烈建议学习 Ansible,一劳永逸。
来源:https://mjj.728.hk/