19.3.4 变更流程、审批与追溯机制

在平台化运维中,变更流程的目标是降低风险、提升可追溯性与可审计性,同时兼顾交付效率。围绕配置项、模板、版本与环境差异,建立统一的变更入口、审批链路、执行与回滚机制,并通过自动化记录实现端到端追溯。

文章图片
sequenceDiagram
    participant Dev as 申请人
    participant CMDB as 配置平台
    participant CI as CI/CD
    participant Ops as 审批人
    participant Mon as 监控
    Dev->>CMDB: 创建变更单(配置项/基线/环境)
    CMDB->>Ops: 发送审批
    Ops-->>CMDB: 审批通过
    CMDB->>CI: 触发流水线
    CI->>CI: 执行配置变更
    CI->>Mon: 标记变更窗口
    CI->>CMDB: 回写结果与日志

变更流程框架(示例化)
- 提出:变更单创建,关联配置项、基线、模板与目标环境,明确变更原因、范围、影响与窗口期。
- 评估:技术评审与风险评估,校验依赖关系、兼容性与资源影响,输出风险等级与回滚策略。
- 审批:按风险分级配置审批链(负责人/架构/安全/业务),支持自动化审批与加急通道。
- 执行:以自动化任务为主(CI/CD、配置管理工具),严格分批与灰度策略。
- 验证:执行后进行配置一致性校验、服务健康检查与业务验证。
- 关闭:汇总变更结果、记录指标与复盘要点,沉淀知识库。

安装与环境准备(示例工具链:Git + Ansible + Jenkins)

# 1) 安装 Git/Ansible(以 Ubuntu 为例)
sudo apt update
sudo apt install -y git ansible

# 2) 安装 Jenkins(示例)
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee \
  /usr/share/keyrings/jenkins-keyring.asc >/dev/null
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
  https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
  /etc/apt/sources.list.d/jenkins.list >/dev/null
sudo apt update && sudo apt install -y jenkins
sudo systemctl enable --now jenkins

# 3) 验证版本
git --version
ansible --version
systemctl status jenkins --no-pager

变更单与配置版本示例(Git 管控)

# 目录结构示例
# repo/
# ├── cmdb/
# │   └── change_requests/CR-2024-0007.yaml
# └── nginx/
#     ├── templates/nginx.conf.j2
#     └── vars/prod.yml

# 创建变更单(YAML)
cat > cmdb/change_requests/CR-2024-0007.yaml <<'EOF'
id: CR-2024-0007
app: web-portal
env: prod
risk: medium
reason: "启用gzip以降低带宽"
scope: ["nginx-prod-01","nginx-prod-02"]
window: "2024-10-12 02:00-03:00"
rollback: "git tag rollback-CR-2024-0007 && ansible-playbook rollback.yml"
approvers: ["ops_lead","sec_officer"]
EOF

git add cmdb/change_requests/CR-2024-0007.yaml
git commit -m "CR-2024-0007: enable gzip in prod"
git push origin main

审批与控制策略(示例实现)

// Jenkinsfile 片段:依据风险等级要求人工审批
pipeline {
  agent any
  stages {
    stage('Load CR') {
      steps {
        sh 'yq e .risk cmdb/change_requests/CR-2024-0007.yaml > /tmp/risk.txt'
      }
    }
    stage('Approval') {
      steps {
        script {
          def risk = readFile('/tmp/risk.txt').trim()
          if (risk != 'low') {
            input message: "CR-2024-0007 需要审批,风险等级=${risk}", ok: "审批通过"
          }
        }
      }
    }
    stage('Deploy') {
      steps {
        sh 'ansible-playbook -i inventories/prod.ini deploy_nginx.yml'
      }
    }
  }
}

变更执行与回滚机制(Ansible 示例)

# deploy_nginx.yml:执行变更并验证
- hosts: nginx_prod
  become: yes
  vars_files:
    - nginx/vars/prod.yml
  tasks:
    - name: 更新配置
      template:
        src: nginx/templates/nginx.conf.j2
        dest: /etc/nginx/nginx.conf
        owner: root
        group: root
        mode: '0644'
      notify: reload nginx

    - name: 语法检查
      command: nginx -t
      register: nginx_check
      changed_when: false

    - name: 输出检查结果
      debug:
        var: nginx_check.stderr

  handlers:
    - name: reload nginx
      service:
        name: nginx
        state: reloaded
# rollback.yml:回滚到上一版本
- hosts: nginx_prod
  become: yes
  tasks:
    - name: 回滚配置文件(从Git tag 拉取)
      command: git checkout rollback-CR-2024-0007 -- nginx/templates/nginx.conf.j2
      args:
        chdir: /opt/config-repo

    - name: 重新部署并验证
      command: ansible-playbook -i inventories/prod.ini deploy_nginx.yml
      args:
        chdir: /opt/config-repo

关键命令解释

# nginx -t:检查 Nginx 配置语法,返回 0 表示语法正确
nginx -t

# ansible-playbook -i inventories/prod.ini deploy_nginx.yml
# -i 指定清单,playbook 执行变更
ansible-playbook -i inventories/prod.ini deploy_nginx.yml

# git tag rollback-CR-2024-0007
# 记录当前版本快照,用于回滚定位
git tag rollback-CR-2024-0007

变更验证示例

# 配置一致性与服务健康检查
ansible nginx_prod -i inventories/prod.ini -m shell -a "md5sum /etc/nginx/nginx.conf"
curl -I http://nginx-prod-01/ | head -n 1

# 预期效果:
# 1) md5sum 在目标主机一致
# 2) HTTP 返回 200 或业务预期状态码

追溯与审计(日志与关联示例)

# 在变更执行脚本中记录审计信息
export CR_ID=CR-2024-0007
export OPERATOR=$(whoami)
echo "$(date) CR=$CR_ID operator=$OPERATOR result=success" \
  >> /var/log/change_audit.log

变更质量度量(采集示例)

# 提取近7天变更成功率(示例:grep统计)
total=$(grep -c "CR-" /var/log/change_audit.log)
success=$(grep -c "result=success" /var/log/change_audit.log)
echo "success_rate=$(awk "BEGIN{print ${success}/${total}*100}")%"

常见排错
- 审批卡住:检查 Jenkins 审批节点日志 Manage Jenkins -> System Log,确认权限与输入超时。
- 配置语法失败:查看 nginx -t 输出,核对模板变量与语法;回滚到上一个 Git tag。
- 执行未生效:确认服务 reload/restart 是否成功,检查 handler 是否触发。
- 追溯缺失:核对变更单 ID 与流水线变量是否一致,审计日志是否写入。

练习
1. 创建一个低风险变更单(例如 Nginx 访问日志格式调整),设置自动审批并在测试环境执行。
2. 在变更失败时触发回滚:人为制造一个语法错误,观察 nginx -t 的失败输出并回滚。
3. 用脚本统计近一周变更成功率与平均审批耗时,输出为 CSV 报表。