19.4.9 任务编排的审计与可追溯性
本节聚焦任务编排的审计与可追溯性,目标是在自动化执行中实现“可查、可证、可回放”。审计范围覆盖编排设计、审批流转、执行过程、变更结果与回滚记录,并确保跨系统链路可关联。核心审计对象包括:作业模板版本、参数输入与来源、触发方式、执行人/系统身份、目标资源清单、执行步骤时间线、输出日志与证据、异常与重试策略、审批链路与时间戳。
审计数据模型需要统一字段并贯穿平台。示例以 MySQL 作为审计库,支持任务与节点级别追踪,配合证据链与哈希校验提升不可篡改性。
-- /opt/ops/schema/audit.sql
CREATE DATABASE IF NOT EXISTS ops_audit DEFAULT CHARSET utf8mb4;
USE ops_audit;
CREATE TABLE task_instance (
task_id VARCHAR(64) PRIMARY KEY,
flow_version VARCHAR(32) NOT NULL,
trace_id VARCHAR(64) NOT NULL,
trigger_type ENUM('manual','schedule','event') NOT NULL,
operator VARCHAR(64) NOT NULL,
approve_chain JSON,
start_time DATETIME,
end_time DATETIME,
result ENUM('success','failed','partial') NOT NULL,
output_digest CHAR(64) NOT NULL,
evidence_url VARCHAR(255)
);
CREATE TABLE task_node (
node_id VARCHAR(64) PRIMARY KEY,
task_id VARCHAR(64) NOT NULL,
step_name VARCHAR(128) NOT NULL,
target VARCHAR(128) NOT NULL,
command_sha CHAR(64) NOT NULL,
exit_code INT NOT NULL,
stdout_digest CHAR(64),
stderr_digest CHAR(64),
start_time DATETIME,
end_time DATETIME,
retry_count INT DEFAULT 0,
FOREIGN KEY (task_id) REFERENCES task_instance(task_id)
);
CREATE TABLE audit_chain (
seq_id BIGINT AUTO_INCREMENT PRIMARY KEY,
task_id VARCHAR(64) NOT NULL,
payload_json JSON NOT NULL,
prev_hash CHAR(64) NOT NULL,
curr_hash CHAR(64) NOT NULL,
created_at DATETIME NOT NULL
);
示例:任务执行时写入审计链,生成全局 trace_id,并对每条记录进行 hash 链接,保证可回放与完整性校验。
# /opt/ops/bin/audit_append.sh
#!/usr/bin/env bash
set -euo pipefail
TASK_ID="task-20240101-0001"
TRACE_ID="$(uuidgen | tr -d '-')"
PAYLOAD='{"step":"deploy_nginx","target":"10.0.1.12","operator":"svc_ops","result":"success"}'
# 读取上一条 hash
PREV_HASH=$(mysql -N -s -e "SELECT curr_hash FROM ops_audit.audit_chain ORDER BY seq_id DESC LIMIT 1;" | awk '{print $1}')
PREV_HASH=${PREV_HASH:-"0"}
# 计算当前 hash(payload+prev_hash)
CURR_HASH=$(printf "%s%s" "$PAYLOAD" "$PREV_HASH" | sha256sum | awk '{print $1}')
# 写入审计链
mysql -e "INSERT INTO ops_audit.audit_chain(task_id,payload_json,prev_hash,curr_hash,created_at)
VALUES('$TASK_ID','$PAYLOAD','$PREV_HASH','$CURR_HASH',NOW());"
echo "trace_id=$TRACE_ID curr_hash=$CURR_HASH"
预期效果:执行脚本后,audit_chain 表新增一条记录,prev_hash 指向上一条记录的 curr_hash。
# 执行示例
bash /opt/ops/bin/audit_append.sh
# 输出示例:
# trace_id=3c8f... curr_hash=8fd2...
安装与采集建议:在执行节点启用系统审计(auditd)捕获关键二进制与配置变更,配合 rsyslog 输出到审计库或对象存储。
# 安装 auditd
sudo yum -y install audit || sudo apt-get -y install auditd
sudo systemctl enable --now auditd
# 定义审计规则:监控编排执行器与关键配置
cat <<'EOF' | sudo tee /etc/audit/rules.d/ops.rules
-w /opt/ops/runner -p x -k ops_exec
-w /etc/nginx/nginx.conf -p wa -k ops_conf
EOF
# 重新加载规则
sudo augenrules --load
# 查询审计事件
sudo ausearch -k ops_exec -ts today
命令解释:
- -w 监控路径;-p x/wa 表示执行/写入与属性变更;
- -k 关键字标签,便于检索;
- ausearch 可按关键字与时间窗口查询审计记录。
回放示例:根据任务 ID 查询节点执行明细,配合对象存储证据恢复过程。
-- 查询任务实例与节点时间线
SELECT t.task_id, t.trace_id, t.operator, n.step_name, n.target, n.exit_code, n.start_time, n.end_time
FROM ops_audit.task_instance t
JOIN ops_audit.task_node n ON t.task_id = n.task_id
WHERE t.task_id = 'task-20240101-0001'
ORDER BY n.start_time ASC;
排错要点:
1. 无审计日志:检查 auditd 服务状态与规则加载(systemctl status auditd、augenrules --check)。
2. 时间线错乱:统一 NTP 时间基准(timedatectl),避免跨系统时间漂移。
3. hash 校验失败:确认写入顺序、是否有并发插入导致链断裂;必要时按 seq_id 回放核对。
4. 追踪链断裂:确保 trace_id 在编排引擎、执行器与审计采集器之间透传。
练习:
1. 基于示例表结构,增加 approval 表记录审批意见与时间戳,并写一条审批记录。
2. 编写脚本为每次执行生成 trace_id,并在日志中输出并入库。
3. 设计一个“高危操作”规则:当命令包含 rm -rf 时,要求双人审批并记录审批链。