You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

特定分支旧ECR镜像删除脚本报错及镜像残留问题求助

ECR分支镜像清理脚本修正方案

问题根源

你遇到的两个核心问题:

  • InvalidImageDigest错误:脚本里把imageTag(如1233-1-DATA)当成imageDigest传给了batch-delete-image命令。ECR的镜像摘要格式是哈希算法:哈希值(比如sha256:a1b2c3...),标签不符合这个正则规则,所以报错。
  • Image对象残留:GitHub推送的镜像包含ImageIndex(清单索引)和Image(实际镜像层)两种类型,原脚本只处理了部分数据,导致Image类型镜像没被删除。

修正后的脚本

以下脚本会正确获取镜像摘要,同时处理两种类型的镜像,保留指定分支的最新镜像,删除其余旧镜像:

#!/bin/bash
set -euo pipefail

# 配置参数
REPO_NAME="bi-dagster"
BRANCH_NAME="$branch_name"  # 确保这个变量已正确传入

# 获取所有镜像详情:包含标签、推送时间、摘要、媒体类型,按推送时间升序排序
image_details=$(aws ecr describe-images \
  --repository-name "$REPO_NAME" \
  --query 'sort_by(imageDetails, &imagePushedAt)[*].{tags: imageTags, pushedAt: imagePushedAt, digest: imageDigest, mediaType: imageMediaType}' \
  --output json)

# 检查是否有镜像
if [[ $(echo "$image_details" | jq -r 'length') -eq 0 ]]; then
  echo "仓库中无镜像"
  exit 1
fi

# 筛选出包含目标分支标签的镜像(同时匹配Image和ImageIndex类型),并整理为"摘要 推送时间"格式
branch_images=$(echo "$image_details" | jq -r --arg branch "$BRANCH_NAME" '
  .[] | 
  select(.tags != null and .tags[] | contains($branch)) | 
  "\(.digest) \(.pushedAt)"
')

# 如果没有匹配的分支镜像,直接退出
if [[ -z "$branch_images" ]]; then
  echo "未找到包含分支[$BRANCH_NAME]的镜像"
  exit 0
fi

# 获取该分支的最新推送时间
latest_pushed_at=$(echo "$branch_images" | awk '{print $2}' | sort -r | head -n1)

# 筛选出需要删除的镜像摘要(排除最新的那个)
digests_to_delete=$(echo "$branch_images" | awk -v latest="$latest_pushed_at" '$2 != latest {print $1}')

# 如果没有需要删除的镜像,直接退出
if [[ -z "$digests_to_delete" ]]; then
  echo "分支[$BRANCH_NAME]仅有最新镜像,无需删除"
  exit 0
fi

# 批量删除镜像(ECR批量删除最多支持100个,超过的话需要分批处理)
echo "开始删除以下旧镜像:"
echo "$digests_to_delete"

# 构造batch-delete-image需要的参数格式:'imageDigest=xxx'
image_ids=$(echo "$digests_to_delete" | sed 's/^/imageDigest=/')

# 执行删除命令
aws ecr batch-delete-image \
  --repository-name "$REPO_NAME" \
  --image-ids $image_ids

关键优化点

  • 区分标签与摘要:改用imageDigest作为删除标识,避免标签被重写导致的误删或漏删。
  • 兼容两种镜像类型:自动匹配所有包含目标分支标签的镜像,不管是Image还是ImageIndex类型。
  • 健壮性提升:增加空值检查,避免无镜像或无匹配分支时的报错;使用set -euo pipefail确保脚本出错时立即终止。
  • 批量处理:直接构造符合batch-delete-image要求的参数格式,一次删除多个镜像。

注意事项

  1. 确保$branch_name变量已正确传入脚本,比如从GitHub Actions的GITHUB_REF_NAME环境变量获取。
  2. 如果待删除镜像超过100个,需要将digests_to_delete分批处理(比如每100个执行一次batch-delete-image)。
  3. 执行前可以先注释掉aws ecr batch-delete-image命令,只打印待删除的摘要,验证是否正确。

内容的提问来源于stack exchange,提问作者x89

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 19:34:54