阶段2(下):运维专题 Docker/Nginx/Linux/CI-CD/Git 的课程、企业场景、面试题和可运行示例
This commit is contained in:
1 parent
5eb67c5d08
commit
b8010a74f3
42 files changed
+3533
-55
No files matched your search
@@ -0,0 +1,89 @@
|
||||
---
|
||||
id: devops.git.scenario.hotfix-and-leaked-secret
|
||||
title: 线上紧急修复和密钥误提交:热修复分支、cherry-pick、清理历史和轮换密钥
|
||||
type: scenario
|
||||
domain: devops
|
||||
stack: [git, cicd]
|
||||
tags: [热修复, cherry-pick, 密钥泄露, 历史清理, 安全]
|
||||
level: intermediate
|
||||
prerequisites: [devops.git.merge-rebase-recovery]
|
||||
est_hours: 1.5
|
||||
related: [devops.git.interview, devops.cicd.pipeline]
|
||||
week: [8, 15]
|
||||
---
|
||||
|
||||
# 线上紧急修复和密钥误提交:热修复分支、cherry-pick、清理历史和轮换密钥
|
||||
|
||||
## 业务背景与问题
|
||||
|
||||
团队按“release 分支发版”的方式工作:`main` 上已经合入了下个版本的多个功能(未测试完),线上运行的是 `release/1.4`。周五下午出现两件事:
|
||||
|
||||
1. 线上 1.4 版本有一个金额计算的 bug,需要马上修复,但不能把 main 上未测试的功能带上线。
|
||||
2. 有同事把含有大模型 API Key 的 `.env` 文件提交并推送到了远程仓库。
|
||||
|
||||
## 约束
|
||||
|
||||
- 热修复要在一小时内上线,而且下个版本也必须包含这个修复。
|
||||
- 仓库在公司内部平台上,有十几个人已经拉取过包含密钥的提交。
|
||||
|
||||
## 方案设计
|
||||
|
||||
**热修复**
|
||||
|
||||
1. 从线上版本的标签 / release 分支创建 `hotfix/amount-rounding`;
|
||||
2. 修复 + 补测试,走合并请求和 CI,合入 `release/1.4`,打标签 `v1.4.1` 发布;
|
||||
3. 把修复提交 `cherry-pick` 到 main(或从 release 合并回 main),保证下个版本不会“复活”这个 bug。
|
||||
|
||||
**密钥泄露**——顺序很重要:
|
||||
|
||||
1. **第一时间轮换密钥**:在模型服务商控制台作废旧 Key、生成新 Key,并更新部署环境的密钥配置。只要密钥进过远程仓库,就必须当作已经泄露,**清理历史不能代替轮换**。
|
||||
2. 检查旧 Key 的调用记录,确认是否有异常使用。
|
||||
3. 删除文件并加入 `.gitignore`;提供 `.env.example`。
|
||||
4. 评估是否需要清理历史:用 `git filter-repo` 从所有历史中移除文件,强制推送,通知所有人重新克隆;托管平台上的缓存、合并请求、fork 中可能仍有副本,需要联系平台管理员。
|
||||
5. 预防:提交前钩子扫描密钥(本仓库的 `tools/check_sensitive.py`),CI 中也执行密钥扫描。
|
||||
|
||||
## 关键代码
|
||||
|
||||
```bash
|
||||
# 热修复
|
||||
git switch -c hotfix/amount-rounding v1.4.0
|
||||
# ……修改代码、补测试……
|
||||
git commit -am "fix(order): 金额四舍五入改为银行家舍入前先转换为分"
|
||||
# 合并请求合入 release/1.4 后打标签
|
||||
git tag -a v1.4.1 -m "热修复:金额计算"
|
||||
git push origin v1.4.1
|
||||
# 带回 main
|
||||
git switch main && git cherry-pick <修复提交哈希>
|
||||
|
||||
# 密钥:先轮换!然后再处理仓库
|
||||
git rm --cached .env
|
||||
echo ".env" >> .gitignore
|
||||
git commit -m "chore: 移除误提交的 .env,并忽略该文件"
|
||||
# 需要清理历史时(会改写所有提交哈希,需要团队协调):
|
||||
git filter-repo --path .env --invert-paths
|
||||
git push --force --all && git push --force --tags
|
||||
```
|
||||
|
||||
`git filter-repo` 需要单独安装,用法以官方说明为准:https://github.com/newren/git-filter-repo 。在临时仓库里练习 cherry-pick、revert、reflog 的脚本见 [examples/git-lab](../examples/git-lab/)。
|
||||
|
||||
## 取舍
|
||||
|
||||
| 做法 | 优点 | 缺点 |
|
||||
| --- | --- | --- |
|
||||
| **只轮换密钥 + 删除文件** | 快、不影响团队 | 旧密钥仍留在历史里(已作废,风险可控) |
|
||||
| 轮换 + 清理历史 | 历史中不再有密钥 | 所有提交哈希改变,所有人要重新克隆;平台副本仍需单独处理 |
|
||||
| 只清理历史不轮换 | —— | **错误做法**:密钥可能已被复制 |
|
||||
|
||||
热修复用 cherry-pick 还是“release 合并回 main”:cherry-pick 精确,只带修复;合并回 main 能保证 release 上所有改动都回到 main,但可能带来冲突。团队约定一种即可。
|
||||
|
||||
## 易错点
|
||||
|
||||
- 热修复只改了 release 分支,忘了带回 main:下个版本 bug 又出现。
|
||||
- 从 main 拉热修复分支:把未测试的功能带上线。
|
||||
- 以为“删除文件再提交一次”密钥就安全了:历史里仍然有。
|
||||
- 先花半天清理历史再轮换密钥:轮换应该是第一步。
|
||||
- 强制推送清理后的历史却没通知团队:有人基于旧历史推送,又把文件带回来。
|
||||
|
||||
## 面试怎么讲
|
||||
|
||||
> “线上版本出 bug 时,我从线上的标签拉热修复分支,修复并补测试后合入 release 分支打补丁版本发布,再 cherry-pick 回 main,避免把 main 上未测试的功能带上线。还处理过密钥误提交:第一步是作废并轮换密钥,检查调用记录;然后删除文件、加入 .gitignore,加上提交前的密钥扫描。是否清理历史要评估成本,清理时用 filter-repo 并通知团队重新克隆。”
|
||||
Reference in new issue
Block a user