在阿里云使用Ansible一键部署Web服务

3 阅读2分钟

基于阿里云ECS(CentOS 7)实操,一键完成全套Web服务部署。

一、极简环境准备

1. 基础要求

  • 阿里云ECS:CentOS 7(已配置root免密登录)
  • 本地控制机:安装Ansible 2.9+
  • 服务器开放端口:80(Nginx)、8000(Gunicorn)

2. 快速配置Ansible

# 本地安装Ansible(CentOS)
yum install epel-release ansible -y

# 配置主机清单
echo "[web_servers]
aliyun_server ansible_host=IP(我的不敢露) ansible_user=root" > /etc/ansible/hosts

# 测试连通性
ansible web_servers -m ping

返回pong即连通成功。

二、创建目录结构

# 创建部署目录
mkdir -p ansible-web-deploy/{roles/{common,mysql,redis,web,nginx},files}
cd ansible-web-deploy

三、编写拆分后的 Playbook

1. 总入口文件(site.yml)

- hosts: web_servers
  gather_facts: yes
  become: yes  # 使用root
  vars:
    # 全局配置(统一修改这里)
    mysql_root_pwd: "MySql@123456"
    redis_pwd: "Redis@123456"
    app_dir: "/opt/webapp"
  roles:
    - common
    - mysql
    - redis
    - web
    - nginx

2. 各服务核心配置

(1)基础环境

创建roles/common/tasks/main.yml

- name: 安装基础依赖包(root)
  yum:
    name: [gcc, python3, python3-pip, firewalld]
    state: present
  become_user: root

- name: 启动防火墙并开放80端口(root)
  firewalld:
    port: 80/tcp
    permanent: yes
    state: enabled
    immediate: yes

(2)MySQL配置

创建roles/mysql/tasks/main.yml

- name: 安装MySQL YUM源
  yum:
    name: https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
    state: present

- name: 安装MySQL服务器
  yum:
    name: mysql-community-server
    state: present
    disable_gpg_check: yes

- name: 启动并开机自启MySQL
  service:
    name: mysqld
    state: started
    enabled: yes

- name: 初始化MySQL
  shell: |
    temp_pwd=$(grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}')
    # 修改root密码
    mysql -uroot -p"$temp_pwd" --connect-expired-password -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '{{ mysql_root_pwd }}';"
    # 创建测试库
    mysql -uroot -p"{{ mysql_root_pwd }}" -e "CREATE DATABASE IF NOT EXISTS web_db;"
  become_user: root
  ignore_errors: yes

(3)Redis配置

创建roles/redis/tasks/main.yml

- name: 安装Redis
  yum:
    name: redis
    state: present

- name: 修改Redis核心配置
  lineinfile:
    path: /etc/redis.conf
    regexp: "{{ item.regex }}"
    line: "{{ item.line }}"
  loop:
    - { regex: '^requirepass', line: 'requirepass {{ redis_pwd }}' }
    - { regex: '^protected-mode', line: 'protected-mode no' }

- name: 启动并开机自启Redis
  service:
    name: redis
    state: started
    enabled: yes

(4)主要Web服务

创建roles/web/tasks/main.yml

- name: 安装Gunicorn及Python依赖
  pip:
    name: [gunicorn, flask, pymysql, redis]
    executable: pip3
  become_user: root

- name: 创建应用目录
  file:
    path: "{{ app_dir }}"
    state: directory
    owner: root
    group: root
  become_user: root

- name: 写入Flask示例应用
  copy:
    dest: "{{ app_dir }}/app.py"
    content: |
      from flask import Flask
      import pymysql
      import redis

      app = Flask(__name__)
      # 连接MySQL和Redis
      mysql = pymysql.connect(host='localhost', user='root', password='{{ mysql_root_pwd }}', db='web_db')
      redis = redis.Redis(host='localhost', password='{{ redis_pwd }}', decode_responses=True)

      @app.route('/')
      def index():
          redis.incr('visit_count')
          return f"""
          <h1>部署成功!</h1>
          <p>MySQL连接状态:{mysql.ping()}</p>
          <p>访问次数:{redis.get('visit_count')}</p>
          """

      if __name__ == '__main__':
          app.run(host='0.0.0.0', port=8000)
    owner: root
    group: root
  become_user: root

- name: 创建Gunicorn系统服务
  copy:
    dest: /etc/systemd/system/gunicorn.service
    content: |
      [Unit]
      Description=Gunicorn Service
      After=network.target

      [Service]
      User=root
      Group=root
      WorkingDirectory={{ app_dir }}
      ExecStart=/usr/bin/gunicorn --workers 2 --bind 127.0.0.1:8000 app:app
      Restart=on-failure

      [Install]
      WantedBy=multi-user.target
    owner: root
    group: root
  become_user: root

- name: 启动并开机自启Gunicorn(root)
  systemd:
    name: gunicorn
    state: started
    enabled: yes
    daemon_reload: yes
  become_user: root

(5)nginx部署(反向代理)

创建roles/nginx/tasks/main.yml

yaml

- name: 安装Nginx
  yum:
    name: nginx
    state: present
  become_user: root

- name: 写入简化版Nginx配置
  copy:
    dest: /etc/nginx/nginx.conf
    content: |
      user root;
      worker_processes auto;
      events { worker_connections 1024; }
      http {
          server {
              listen 80;
              location / {
                  proxy_pass http://127.0.0.1:8000;
                  proxy_set_header Host $host;
                  proxy_set_header X-Real-IP $remote_addr;
              }
          }
      }
    owner: root
    group: root
  become_user: root

- name: 启动并开机自启Nginx
  service:
    name: nginx
    state: started
    enabled: yes
  become_user: root

四、一键执行部署

# 在ansible-web-deploy目录下执行
ansible-playbook site.yml

全程约 3-5 分钟,无报错即部署完成。

五、验证部署结果

  1. 浏览器访问:输入http://IP,看到以下内容即成功:

    部署成功!
    MySQL连接状态:True
    访问次数:1
    
  2. 登录服务器(root)检查服务状态:

    # 所有服务均以root运行
    systemctl status nginx gunicorn mysqld redis
    # 验证Nginx运行用户
    ps aux | grep nginx | grep -v grep
    # 验证Gunicorn运行用户
    ps aux | grep gunicorn | grep -v grep
    

总结

  1. 角色拆分清晰:5 个角色各司其职,修改某一组件只需改对应角色文件,全局变量集中在site.yml,易维护;
  2. 新手友好:去掉权限相关的复杂配置,聚焦核心部署逻辑,无权限报错风险;
  3. 生产提示:该方案适合测试 / 入门场景,生产环境建议按需创建专用用户,仅保留必要权限。