Ansible代码上线项目实战案例

描述

从零到一:用Ansible打造企业级自动化部署流水线

在DevOps浪潮中,自动化部署已经成为每个运维工程师的必备技能。今天我将分享一个完整的Ansible代码上线项目实战案例,让你的部署效率提升10倍!

为什么选择Ansible?

在众多自动化工具中,Ansible凭借其无代理架构简单易学强大功能脱颖而出:

• 无需安装客户端:只需SSH连接即可管理所有服务器

• YAML语法:人类可读的配置文件,团队协作更高效

• 幂等性:多次执行结果一致,避免重复操作带来的问题

• 模块丰富:内置2000+模块,覆盖99%的运维场景

项目架构设计

我们将构建一个完整的Web应用部署流水线:

 

项目结构
├── inventories/          # 环境清单
│   ├── dev/
│   ├── staging/
│   └── production/
├── group_vars/           # 组变量
├── roles/               # 角色目录
│   ├── common/          # 基础环境
│   ├── nginx/           # Web服务器
│   ├── app/             # 应用部署
│   └── monitoring/      # 监控配置
├── playbooks/           # 剧本文件
└── deploy.yml           # 主部署文件

 

核心组件实现

1. 环境清单配置

inventories/production/hosts.yml

 

all:
  children:
    webservers:
      hosts:
        web-01:
          ansible_host: 10.0.1.10
        web-02:
          ansible_host: 10.0.1.11
    databases:
      hosts:
        db-01:
          ansible_host: 10.0.2.10
    loadbalancers:
      hosts:
        lb-01:
          ansible_host: 10.0.3.10

 

2. 应用部署角色

roles/app/tasks/main.yml

 

---
- name: "创建应用目录"
  file:
    path: "{{ app_path }}"
    state: directory
    owner: "{{ app_user }}"
    group: "{{ app_group }}"
    mode: '0755'

- name: "从Git仓库拉取代码"
  git:
    repo: "{{ git_repo }}"
    dest: "{{ app_path }}/releases/{{ deployment_id }}"
    version: "{{ git_branch | default('main') }}"
    force: yes
  register: git_result

- name: "安装依赖包"
  pip:
    requirements: "{{ app_path }}/releases/{{ deployment_id }}/requirements.txt"
    virtualenv: "{{ app_path }}/venv"
    virtualenv_python: python3
  when: git_result.changed

- name: "配置应用参数"
  template:
    src: config.j2
    dest: "{{ app_path }}/releases/{{ deployment_id }}/config.py"
    backup: yes
  notify: restart application

- name: "创建软链接"
  file:
    src: "{{ app_path }}/releases/{{ deployment_id }}"
    dest: "{{ app_path }}/current"
    state: link
    force: yes
  notify: restart application

 

3. 滚动部署策略

playbooks/rolling_deploy.yml

 

---
- name: "滚动部署应用"
  hosts: webservers
  serial: 1  # 一台一台部署
  max_fail_percentage: 0
  
  pre_tasks:
    - name: "从负载均衡器移除节点"
      uri:
        url: "http://{{ lb_host }}/remove/{{ inventory_hostname }}"
        method: POST
      delegate_to: localhost
      
    - name: "等待连接断开"
      wait_for:
        port: 80
        state: stopped
        timeout: 60

  tasks:
    - name: "部署应用"
      include_role:
        name: app
        
    - name: "健康检查"
      uri:
        url: "http://{{ inventory_hostname }}/health"
        method: GET
        status_code: 200
      retries: 10
      delay: 5

  post_tasks:
    - name: "添加节点到负载均衡器"
      uri:
        url: "http://{{ lb_host }}/add/{{ inventory_hostname }}"
        method: POST
      delegate_to: localhost

 

4. 回滚机制

roles/app/tasks/rollback.yml

 

---
- name: "获取历史版本列表"
  find:
    paths: "{{ app_path }}/releases"
    file_type: directory
  register: releases

- name: "排序版本并获取上一版本"
  set_fact:
    previous_release: "{{ (releases.files | sort(attribute='mtime', reverse=true))[1].path | basename }}"
  when: releases.files | length > 1

- name: "回滚到上一版本"
  file:
    src: "{{ app_path }}/releases/{{ previous_release }}"
    dest: "{{ app_path }}/current"
    state: link
    force: yes
  when: previous_release is defined
  notify: restart application

 

高级特性实现

1. 蓝绿部署

 

- name: "蓝绿部署切换"
  block:
    - name: "部署到绿色环境"
      include_role:
        name: app
      vars:
        app_env: green
        
    - name: "验证绿色环境"
      uri:
        url: "http://{{ inventory_hostname }}:{{ green_port }}/health"
        status_code: 200
        
    - name: "切换流量到绿色环境"
      replace:
        path: /etc/nginx/sites-enabled/app.conf
        regexp: 'proxy_pass http://blue'
        replace: 'proxy_pass http://green'
      notify: reload nginx
      
  rescue:
    - name: "部署失败,保持蓝色环境"
      debug:
        msg: "部署失败,自动保持当前蓝色环境运行"

 

2. 配置管理与密钥处理

group_vars/all/vault.yml (使用ansible-vault加密)

 

$ANSIBLE_VAULT;1.1;AES256
66386439653765386464626463653765346464...

 

解密使用:

 

ansible-playbook deploy.yml --ask-vault-pass

 

3. 监控集成

roles/monitoring/tasks/main.yml

 

- name: "部署Prometheus监控配置"
  template:
    src: prometheus.yml.j2
    dest: /etc/prometheus/targets/{{ inventory_hostname }}.yml
  delegate_to: "{{ monitoring_server }}"
  notify: reload prometheus

- name: "发送部署通知到Slack"
  uri:
    url: "{{ slack_webhook_url }}"
    method: POST
    body_format: json
    body:
      text: " {{ inventory_hostname }} 部署完成 - 版本: {{ git_branch }}"
  delegate_to: localhost

 

性能优化技巧

1. 并行执行优化

 

- name: "并行安装软件包"
  package:
    name: "{{ item }}"
    state: present
  loop: "{{ packages }}"
  async: 300  # 5分钟超时
  poll: 0     # 立即返回
  register: package_install

- name: "等待所有包安装完成"
  async_status:
    jid: "{{ item.ansible_job_id }}"
  loop: "{{ package_install.results }}"
  register: job_result
  until: job_result.finished
  retries: 30

 

2. 条件执行减少无效操作

 

- name: "检查应用是否需要更新"
  stat:
    path: "{{ app_path }}/current"
  register: current_version

- name: "部署新版本"
  include_tasks: deploy.yml
  when: not current_version.stat.exists or 
        git_result.after != current_version.stat.lnk_target | basename

 

故障排查与调试

1. 调试模式启用

 

# 详细输出
ansible-playbook deploy.yml -vvv

# 检查模式(不实际执行)
ansible-playbook deploy.yml --check --diff

# 逐步执行
ansible-playbook deploy.yml --step

 

2. 日志记录配置

 

- name: "记录部署日志"
  lineinfile:
    path: /var/log/deployment.log
    line: "{{ ansible_date_time.iso8601 }} - {{ inventory_hostname }} - {{ deploy_action }}"
    create: yes

 

一键部署脚本

deploy.sh

 

#!/bin/bash
set -e

ENVIRONMENT=${1:-staging}
BRANCH=${2:-main}
DEPLOYMENT_ID=$(date +%Y%m%d_%H%M%S)

echo " 开始部署到 $ENVIRONMENT 环境"
echo " 分支: $BRANCH"
echo " 部署ID: $DEPLOYMENT_ID"

# 预检查
ansible-playbook -i inventories/$ENVIRONMENT playbooks/precheck.yml

# 执行部署
ansible-playbook -i inventories/$ENVIRONMENT deploy.yml 
  -e "git_branch=$BRANCH" 
  -e "deployment_id=$DEPLOYMENT_ID" 
  --vault-password-file .vault_pass

# 部署后验证
ansible-playbook -i inventories/$ENVIRONMENT playbooks/verify.yml

echo " 部署完成!"

 

最佳实践总结

1. 版本管理:所有Ansible代码都应纳入Git版本控制

2. 环境隔离:不同环境使用独立的配置文件

3. 密钥安全:敏感信息使用ansible-vault加密

4. 幂等性:确保多次执行结果一致

5. 错误处理:为关键任务添加rescue块

6. 监控告警:集成监控系统,及时发现问题

7. 文档维护:保持详细的操作文档

结语

通过这个完整的Ansible部署项目,我们实现了:

• 零宕机时间的滚动部署

• 一键回滚能力

• 多环境配置管理

• 自动化监控集成

• 安全的密钥管理

这套方案已在我们的生产环境稳定运行2年,支撑了日均千万级访问量的业务系统。

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分