镜像标签管理与版本策略
镜像标签这件事,看着简单吧?就是个名字嘛。
但我见过太多团队,因为标签乱用,线上出了事故。说白了一个不规范的标签,就可能让你在回滚时拉错镜像。所以这节课,我们好好聊聊标签怎么管。
标签的潜规则
很多人觉得 latest 标签最方便。我一开始也这么干。
直到有一次,我需要在凌晨紧急回滚。结果发现 latest 指向的是三小时前的新版本,根本不是线上在跑的那个。那叫一个慌。
关于 latest,记住三点:
- 不要在生产环境用
latest—— 你不确定它指向哪个版本 - 开发环境可以用 —— 方便拉取最新代码测试
- 每次构建都更新 —— 别让
latest停留在旧版本上
我曾经在深夜发布时,使用 latest 标签部署到生产环境。结果是,CI 还没来得及更新标签,我拉下来的是昨天的镜像。等我发现时,用户已经报错了。
所以,生产环境请用具体版本号。
常见的版本策略
我习惯把版本策略分成三类。你想想看,每种场景用不同的策略,会清晰很多。
| 策略 | 标签格式 | 适用场景 |
|---|---|---|
| 语义化版本 | v1.2.3 |
正式发布、对外提供 |
| Git SHA | git-abc1234 |
开发环境、测试环境 |
| 构建号 | build-5678 |
CI/CD 流水线 |
我个人偏好语义化版本。你想想看,v1.2.3 一看就知道是大版本还是小补丁,多直观。
语义化版本怎么用?
说白了就是 主版本.次版本.补丁。
- 主版本:不向下兼容的大改动
- 次版本:向下兼容的新功能
- 补丁:向下兼容的 bug 修复
举个例子:
my-app:v1.0.0 # 第一个正式版本
my-app:v1.1.0 # 加了个新功能
my-app:v1.1.1 # 修了个小bug
我个人习惯这样构建镜像时,会同时打两个标签:一个具体版本,一个 latest。但只在开发环境用 latest。
命令很简单:
docker build -t my-app:v1.0.0 -t my-app:latest .
Git SHA 标签的妙用
我记得有一次,QA 团队在测试时发现了一个 bug。他们需要知道当前部署的到底是哪个 commit 的代码。
如果用了 Git SHA 标签,直接看镜像标签就知道了。不用再费劲去翻 Jenkins 日志。
做法是:在 CI 中获取当前的 Git commit SHA,然后作为标签。
export GIT_SHA=$(git rev-parse --short HEAD)
docker build -t my-app:git-${GIT_SHA} .
我在项目中遇到过,配合 git log 使用,定位问题快得飞起。
多标签策略
实际上,一个镜像可以打多个标签。我建议你这么做:
- 主标签:语义化版本(如
v1.2.3) - 辅助标签:Git SHA(如
git-abc1234) - 环境标签:开发/测试/生产(如
dev、staging)
为什么这么做?说白了,语义化版本方便人工识别,Git SHA 方便自动化回滚,环境标签方便部署切换。
举个例子:
docker build -t my-app:v1.2.3 -t my-app:git-abc1234 -t my-app:staging .
嗯,这里要注意:环境标签 staging 是动态的,每次部署都会更新。但语义化版本和 Git SHA 是静态的,永久保留。
版本策略的坑
我踩过不少坑,分享几个给你:
- 不要用时间戳当标签 —— 你无法通过时间戳知道代码版本
- 不要覆盖历史标签 —— 除非你确定没人再用那个版本
- 不要用
latest做回滚 —— 它不指向具体版本
我曾经在一个项目中,同事用 2024-01-01 作为标签。结果三个月后,没人知道这个镜像是基于哪个 commit 构建的。最后只能全部删掉重新构建。
所以我现在坚持:标签必须能追溯到代码版本。
SVG:标签管理流程
总结几个原则
最后,给你几个我在项目中总结出来的原则:
- 标签要可追溯 —— 能直接查到对应的代码 commit
- 标签要稳定 —— 一旦发布,不要覆盖或删除
- 标签要一致 —— 团队统一规范,不要各有各的玩法
嗯,标签管理是个基本功。虽然看着简单,但坑很多。你想想看,如果连镜像都拉不对,后面那些校验、部署根本没意义。