核心是通过仓库层不可变配置杜绝覆盖,而非人工防控;启用acr/harbor/gitlab等仓库的镜像版本不可变功能,配合不可变标签命名、摘要拉取、只读凭证、归档冻结流程等多层防护。

核心思路不是“防覆盖”,而是让覆盖操作在技术上无法发生——关键靠仓库层的不可变配置,而非依赖人工守则或本地脚本拦截。
启用仓库级镜像版本不可变功能
这是最直接、最可靠的方式。阿里云ACR、Harbor 2.8+、GitLab Container Registry等主流私有仓库均支持该能力:
- 在ACR企业版仓库的“基本信息”页勾选不可变,开启后除
latest外,所有已存在标签(如v1.2.0、2025-Q3-LTS)将拒绝重复推送,报错提示:The requested tag already exists and cannot be overwritten - Harbor需在项目级别开启“内容信任”并配合Tag Retention Policy:添加规则匹配
v\d+\.\d+\.\d+-prod或LTS-.*,勾选“永不删除”,同时设置为“只读标签” - 避免使用Docker Hub托管生产镜像——它不支持任何标签保护机制,
docker push同名标签会静默覆盖
强制使用不可变标签命名 + 内容校验
即使仓库未开启不可变,也能通过命名与校验降低误操作影响:
- 标签必须携带唯一构建标识,例如
myapp:v2.1.0-git-9f3a1b2或myapp:v2.1.0-build-20260428-1523,杜绝复用v2.1.0这种易覆盖的简写 - 部署时不用
docker pull myapp:v2.1.0,而用摘要拉取:docker pull myapp@sha256:abc123...,确保运行的是确切内容 - CI流水线中自动记录每次推送的
REPO:TAG → DIGEST映射,并写入审计日志,便于事后比对是否被篡改
限制本地操作权限与清理行为
防止运维在节点上误删或强制覆盖:
- 生产环境节点禁用完整仓库凭证,仅配置只读token用于
docker pull,禁止push和rmi操作 - CI脚本中禁用裸
docker rmi -f,加入防护逻辑:若检测到匹配v[0-9]+\.[0-9]+\.[0-9]+-prod的本地镜像,立即中止并告警 - 定期执行
docker images --filter "reference=myapp:v*.prod"扫描,缺失即触发告警,作为第二道防线
建立归档—冻结—下线的生命周期流程
把“不能删”转化为“有据可依的冻结”:
- 新主版本上线后,立即推送归档标签,如
myapp:v1.2.0-archive,并在仓库策略中将其纳入保留范围 - 冻结期内(建议不少于6个月),该标签设为Harbor只读,且K8s Deployment中禁止引用该标签启动新Pod
- 下线前需走审批流程,归档标签需同步从保留策略中移出,再执行人工删除——删除动作本身也应被审计日志完整记录











