我把CI产物放OBS后的三次返工
场景和账单异常
我们组这个 Go 服务跑在 CodeArts,工作日平均每天 15 到 22 次构建,发版周会到 30 次。构建产物有三类:app 二进制、debug symbols、CycloneDX 格式的 SBOM。运行器还是那台 ECS,s6.large.2,2 vCPU 4 GiB,系统 Ubuntu 22.04.4 LTS,磁盘是 300GB 的 ESSD。4 月 28 日我把 /var/lib/ci 从 100GB 扩到 300GB,当天用 df -h 看是 71% 使用率,心里觉得能撑一阵,结果 5 月第二周又到 92%。我把本地保留从 14 天砍到 2 天,旧产物全上传到 OBS 的 ci-artifacts-prod,区域 cn-north-4,上传工具固定 obsutil 5.5.12。
我当时以为只是请求量多了一点。
5 月账单出来我是真懵了,OBS 合计 911.08 元,4 月是 327.46 元。费用中心分项里,请求次数 246.31 元,跨区域复制流量 188.52 元,存储容量 318.07 元。容量只从 1.1TB 到 1.4TB,这个涨幅对不上。那天我花了 3 小时 12 分钟,把费用中心、CES 指标、流水线日志按小时对齐,确认不是有人手动传了超大包。CES 上 PutRequests 在 5 月 12 日到 5 月 20 日每天都在 160 万到 210 万次,ListRequests 峰值 47 万次,这个量级不可能是正常下载造成的,基本就是脚本和规则把自己打穿了。
第一次返工是上传权限
流水线里调用是这条,参数一直没动过:obsutil cp dist/ obs://ci-artifacts-prod/release/ -r -f -parallel=8 -threshold=52428800。AK/SK 通过环境变量注入,IAM 用户叫 ci-artifact-bot。周一 10:17 开始失败,连续 47 分钟,卡住 19 次构建,CodeArts 页面全是红的。日志里同一个错误刷屏:
obsutil: 5.5.12
time="2026-05-12T10:17:44+08:00" level=error msg="PutObject failed"
ErrorCode=AccessDenied
ErrorMessage=Access denied by bucket policy.
RequestId=00000196A21D5FEE3F7A3B2C
HostId=ci-artifacts-prod.obs.cn-north-4.myhuaweicloud.com
我第一反应是密钥过期,去 IAM 查了 AccessKey 状态是正常。第二反应是我前一晚加的桶策略,限制了来源 VPC Endpoint 和 SourceIp。我先做了一个错误修补:把 NAT 的 EIP 填进白名单,放行 121.x.x.17/32,手动重跑第 2381 号流水线,还是 403。再看 VPC Flow Log 才发现两个项目跑在不同子网,出口会切到另一台 NAT,10 分钟内 IP 从 121.x.x.17 变成 121.x.x.23,这个方案根本不稳。
真正改动是把 Deny 语句里和 SourceIp 相关的条件删掉,只保留 SecureTransport=true 的硬限制,再把权限收回到 IAM 用户最小动作集。最终策略是:
{
"Effect": "Allow",
"Action": [
"obs:object:PutObject",
"obs:object:GetObject",
"obs:object:DeleteObject",
"obs:bucket:ListBucket"
],
"Resource": [
"obs:bucket:ci-artifacts-prod",
"obs:object:ci-artifacts-prod/release/*"
]
}
我在会议室里改了三次策略。
11:06 恢复上传,失败队列在 11:24 清空,但这只是把流水线救活,费用问题还在。
第二次返工是生命周期规则
权限修完后我去看对象明细,发现自己开了版本控制,却只配了 CurrentVersion 7 天过期,NoncurrentVersion 和 DeleteMarker 都没清。流水线每次覆盖同名 release/latest.tar.gz,版本号会一直累积。5 月 20 日 17:40 我跑 obsutil ls obs://ci-artifacts-prod/release/ -v -s,看到对象总数 832,417,真实文件才 64,203,剩下全是旧版本和删除标记。这个洞是我自己挖的。
我当晚做过一次失败尝试:直接 obsutil rm obs://ci-artifacts-prod/release/latest.tar.gz -f -v,想着删掉热点对象能止血。结果只打了一个 DeleteMarker,NoncurrentVersion 还在,第二天对象数几乎没降,LIST 请求照样高。
后来我把生命周期规则改成下面这样,关键是补了 NoncurrentVersionExpiration 和 ExpiredObjectDeleteMarker,还加了分片上传清理,避免失败分片长期占着:
{
"Rules": [
{
"ID": "release-retention",
"Prefix": "release/",
"Status": "Enabled",
"Expiration": {"Days": 14},
"NoncurrentVersionExpiration": {"NoncurrentDays": 7},
"ExpiredObjectDeleteMarker": true,
"AbortIncompleteMultipartUpload": {"DaysAfterInitiation": 2}
}
]
}
脚本也不是“改了一下”那么轻松。旧脚本会先 obsutil ls obs://ci-artifacts-prod/release/ -s,再 grep 最新对象名,单次构建平均触发 6,000 到 9,000 次 LIST,请求费就是这么来的。我改成对象键直接带 commit sha 和构建号:release/${branch}/${CI_COMMIT_SHA}/${BUILD_NO}/app-linux-amd64.tar.gz,下载侧不再扫描目录,直接按精确路径拉取。为了兼容回滚,我给元数据补了 x-obs-meta-git-ref 和 x-obs-meta-build-time,回溯时查元数据,不再遍历。
改完第二天,请求次数从 182 万次降到 27 万次,请求费用日均从 8.2 元掉到 1.3 元。生命周期清理是异步的,桶里对象数到第 3 天才从 83 万降到 11 万,控制台任务耗时 9 小时 6 分。流水线平均时长也从 11 分 24 秒降到 9 分 48 秒,省下来的时间基本都在上传前扫描那一步。
第三次返工是跨区复制和KMS
我们要保留异地副本,我给源桶加了到 cn-southwest-2 的复制规则,目标桶 ci-artifacts-dr。规则最初是全前缀复制,包含 debug symbols。结果复制状态一直 FAILED,控制台只有一行短错。我去事件中心翻完整记录才看到 KMS 权限问题:
replication task failed
errorCode: KMS.0303
errorMessage: User is not authorized to perform kms:encrypt on key 6d2f...9c1a
object: release/20260521/app-linux-amd64.tar.gz
ruleId: crr-n4-to-sw2
我还走过一条弯路。那天凌晨 00:40 我把源桶默认加密临时切成 SSE-OBS,想绕过 KMS 先把积压复制完,结果新对象能复制,旧对象依然失败,因为历史对象已经是 SSE-KMS,加密属性不会自动重写。这个操作白做了 40 分钟,还把审计日志弄得很乱。
最终是给 OBS 服务主体补 KMS 授权,Encrypt/Decrypt/GenerateDataKey 三个动作都加上,限定 keyId 和桶 ARN。授权生效后复制恢复,延迟在 6 到 18 分钟波动。复制流量还是高,我又把规则改成只复制主程序和 SBOM,debug symbols 只留主区域 14 天,不进异地桶。这个改动当天下午 15:00 生效,单日跨区流量从 74GB 掉到 19GB,复制费用从 188.52 元降到 41.67 元。
我在周三凌晨把复制规则临时关过一次,怕继续烧钱。
数据变化和还没收尾
- OBS 月费用:5 月 911.08 元,6 月 402.73 元。
- 请求次数:日均 182 万次降到 31 万次,峰值从 210 万降到 46 万。
- 桶内对象数:83 万降到 11 万,生命周期任务累计执行 9 小时 6 分。
- 流水线平均时长:11 分 24 秒降到 9 分 48 秒,P95 从 16 分 02 秒降到 12 分 11 秒。
现在还有两件事没收尾。归档层检索慢,回滚到 20 天前版本时取回要等 3 到 5 分钟,值班同学在故障窗口里会急;分支删除后产物索引没有跟着删,我在写 Git webhook 到 FunctionGraph 的清理函数,已经跑通 dry-run,真删模式还在补回归用例,重点是防止误删 release 分支产物。
- 点赞
- 收藏
- 关注作者
评论(0)