特定分支旧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要求的参数格式,一次删除多个镜像。
注意事项
- 确保
$branch_name变量已正确传入脚本,比如从GitHub Actions的GITHUB_REF_NAME环境变量获取。 - 如果待删除镜像超过100个,需要将
digests_to_delete分批处理(比如每100个执行一次batch-delete-image)。 - 执行前可以先注释掉
aws ecr batch-delete-image命令,只打印待删除的摘要,验证是否正确。
内容的提问来源于stack exchange,提问作者x89
相关产品推荐
相关产品推荐

