18.5.7 发布合规与审计:记录、追踪与报表

发布合规与审计:记录、追踪与报表#

目标与范围
- 目标:确保发布过程可追溯、可复盘、可问责,满足内部制度与外部合规要求。
- 范围:变更申请、审批、构建、制品、部署、验证、回滚、发布后监控与复盘。

原理草图:审计链路与数据流

文章图片

审计记录要素(最小字段集合)
- 变更基本信息:变更单号、系统/服务、版本号、发布窗口、风险等级。
- 人员与权限:申请人、审批人、执行人、权限校验记录。
- 过程节点:审批时间、构建时间、部署时间、验证时间、回滚时间。
- 变更内容:commit/tag、制品ID、配置变更、DB变更脚本。
- 环境与资源:环境、集群/节点、命名空间、镜像摘要。
- 验证与监控:测试结果、健康检查、指标阈值与告警记录。

Jenkins流水线审计实现(示例:记录+上报)

// Jenkinsfile
pipeline {
  agent any
  environment {
    CHANGE_ID = "${params.CHANGE_ID}"
    ENV_NAME  = "${params.ENV_NAME}"
  }
  stages {
    stage('Build') {
      steps {
        sh '''
        set -e
        echo "build at $(date -Iseconds)" | tee audit_meta.txt
        echo "change_id=${CHANGE_ID}"     | tee -a audit_meta.txt
        echo "env=${ENV_NAME}"            | tee -a audit_meta.txt
        git rev-parse HEAD               | tee -a audit_meta.txt
        ./mvnw -q -DskipTests package
        '''
      }
    }
    stage('Publish Audit') {
      steps {
        sh '''
        set -e
        # 生成JSON审计事件
        jq -n \
          --arg change_id "${CHANGE_ID}" \
          --arg env "${ENV_NAME}" \
          --arg commit "$(git rev-parse HEAD)" \
          --arg build_id "${BUILD_ID}" \
          --arg job "${JOB_NAME}" \
          --arg ts "$(date -Iseconds)" \
          '{
            change_id:$change_id, env:$env, commit:$commit,
            build_id:$build_id, job:$job, ts:$ts
          }' > audit.json

        # 上报到审计HTTP服务(或Logstash/自研接口)
        curl -sS -X POST http://audit.example.com/events \
          -H 'Content-Type: application/json' \
          -d @audit.json
        '''
      }
    }
  }
}

审计数据落库(ELK示例)
- 安装 Filebeat 并采集 Jenkins 构建日志:

# Ubuntu示例
sudo apt-get install -y filebeat
sudo tee /etc/filebeat/filebeat.yml >/dev/null <<'EOF'
filebeat.inputs:
  - type: log
    enabled: true
    paths:
      - /var/lib/jenkins/jobs/*/builds/*/log
    fields:
      app: jenkins
      type: build_log
output.elasticsearch:
  hosts: ["http://elk.example.com:9200"]
  index: "audit-jenkins-%{+yyyy.MM.dd}"
EOF
sudo systemctl enable --now filebeat
  • 预期效果:ES 中出现 audit-jenkins-* 索引,可按 job/build_id 查询。

发布合规与审批策略(示例:参数化+门禁)

// Jenkins参数与审批门禁
parameters {
  string(name: 'CHANGE_ID', description: '变更单号')
  choice(name: 'ENV_NAME', choices: ['test','staging','prod'])
}
stage('Approval') {
  when { expression { params.ENV_NAME == 'prod' } }
  steps {
    input message: "发布到生产需审批", ok: "批准"
  }
}

制品签名与追踪(示例:制品摘要)

# 计算镜像摘要并记录
IMAGE=repo/app:1.2.3
docker pull $IMAGE
docker inspect --format='{{index .RepoDigests 0}}' $IMAGE | tee image_digest.txt
# 预期输出:repo/app@sha256:xxxx

报表与统计(示例:审计库SQL)

-- 发布成功率
SELECT
  date_trunc('day', ts) AS day,
  COUNT(*) AS total,
  SUM(CASE WHEN status='success' THEN 1 ELSE 0 END) AS success
FROM audit_events
GROUP BY 1
ORDER BY 1;

-- 回滚率
SELECT
  COUNT(*) FILTER (WHERE action='rollback')::float / COUNT(*) AS rollback_rate
FROM audit_events;

排错与诊断
- 审计上报失败(HTTP 5xx):

curl -v http://audit.example.com/health
tail -n 200 /var/lib/jenkins/jobs/<job>/builds/<id>/log
  • Filebeat未采集到日志:
sudo filebeat test output
sudo filebeat test config
sudo journalctl -u filebeat -n 100
  • ES索引不增长:
curl -s http://elk.example.com:9200/_cat/indices?v | grep audit-jenkins

练习
1. 在 Jenkinsfile 中新增 deploy_id 字段,写入 audit.json 并上报。
2. 在 ES 中创建索引模板,按 env 字段分片路由。
3. 用 SQL 统计过去 30 天的发布平均时长与失败率。
4. 模拟一次回滚并验证审计链路中 action=rollback 的完整性。