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

如何保留私有Docker仓库中指定项目的最新3个Docker镜像?

我来帮你搞定这个需求!要在私有Docker仓库里保留指定项目的最新3个镜像,其余的自动清理,咱们可以通过仓库的API来实现,甚至可以写成脚本定期执行,下面是详细的操作方案:

前提准备
  • 确保你的私有Docker仓库已开启删除功能:默认情况下私有仓库是禁用删除的,需要修改配置重启。如果是用容器运行的仓库,启动时加上环境变量:docker run -d -p 5000:5000 -e REGISTRY_STORAGE_DELETE_ENABLED=true --name registry registry:2;如果是配置文件管理,在config.yml里添加storage: { delete: { enabled: true } }后重启仓库服务。
  • 安装jq工具用来解析JSON:CentOS上执行yum install jq -y。
  • 确认能正常访问私有仓库的API:比如执行curl http://your-registry:5000/v2/_catalog(如果有认证,加上-u username:password),能返回仓库列表说明API可用。
步骤1:获取项目的所有镜像标签

假设你的项目镜像在私有仓库中的路径是your-registry:5000/my-project(my-project是仓库名),先获取该项目的所有版本标签:

# 替换成你的仓库地址和项目名
REGISTRY="your-registry:5000"
REPO="my-project"
# 如果有认证,取消下面注释并填写
# AUTH="username:password"

# 获取所有标签并输出
curl -s ${AUTH:+-u $AUTH} http://$REGISTRY/v2/$REPO/tags/list | jq '.tags'
步骤2:筛选出要保留和删除的镜像

接下来需要对标签排序,筛选出最新的3个保留,其余标记为待删除。这里要注意版本标识的排序逻辑:

  • 如果你的版本是语义化版本(比如v1.0.0、v2.1.3),用sort -Vr按版本号倒序排序;
  • 如果是时间戳或纯数字版本,用sort -r倒序即可。

示例命令:

# 获取所有标签并按版本倒序排序
ALL_TAGS=$(curl -s ${AUTH:+-u $AUTH} http://$REGISTRY/v2/$REPO/tags/list | jq -r '.tags[]' | sort -Vr)

# 保留最新的3个标签
KEEP_TAGS=$(echo "$ALL_TAGS" | head -n 3)

# 得到需要删除的标签(排除保留的标签)
DELETE_TAGS=$(echo "$ALL_TAGS" | grep -vE "^($(echo "$KEEP_TAGS" | tr '\n' '|'))$")

执行完可以分别输出KEEP_TAGS和DELETE_TAGS确认筛选结果是否正确。

步骤3:删除指定镜像

私有仓库删除镜像需要先获取镜像的digest(摘要),再调用DELETE API删除对应的manifest:

for TAG in $DELETE_TAGS; do
    echo "正在处理标签: $TAG"
    # 获取镜像的digest
    DIGEST=$(curl -s ${AUTH:+-u $AUTH} -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
        http://$REGISTRY/v2/$REPO/manifests/$TAG | jq -r '.config.digest')
    
    if [ -z "$DIGEST" ]; then
        echo "无法获取$TAG的digest,跳过"
        continue
    fi

    # 执行删除
    RESPONSE=$(curl -s -w "%{http_code}" -X DELETE ${AUTH:+-u $AUTH} \
        http://$REGISTRY/v2/$REPO/manifests/$DIGEST)
    HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
    
    if [ "$HTTP_CODE" -eq 202 ]; then
        echo "$TAG 删除成功"
    else
        echo "$TAG 删除失败,响应码: $HTTP_CODE"
    fi
done
步骤4:清理仓库存储空间

删除镜像后,仓库的实际存储文件并不会立即删除,需要执行垃圾回收来释放磁盘空间:

  • 如果是容器运行的仓库,执行:
docker exec -it registry bin/registry garbage-collect /etc/docker/registry/config.yml

(把registry换成你的仓库容器名)

  • 如果是直接安装的仓库,运行对应的垃圾回收命令即可。
脚本化自动执行

把上面的步骤整合成一个可复用的shell脚本,方便定期执行:

#!/bin/bash

# 配置参数,请根据实际情况修改
REGISTRY="your-registry:5000"
REPO="my-project"
KEEP_COUNT=3
# AUTH="username:password"  # 有认证时取消注释并填写

# 检查jq是否安装
if ! command -v jq &> /dev/null; then
    echo "错误: 未安装jq工具,请执行yum install jq -y安装"
    exit 1
fi

# 获取所有标签并排序
ALL_TAGS=$(curl -s ${AUTH:+-u $AUTH} http://$REGISTRY/v2/$REPO/tags/list | jq -r '.tags[]' | sort -Vr)

# 检查镜像数量是否需要清理
TAG_COUNT=$(echo "$ALL_TAGS" | wc -l)
if [ $TAG_COUNT -le $KEEP_COUNT ]; then
    echo "当前只有$TAG_COUNT个镜像,无需清理"
    exit 0
fi

# 筛选保留和删除的标签
KEEP_TAGS=$(echo "$ALL_TAGS" | head -n $KEEP_COUNT)
DELETE_TAGS=$(echo "$ALL_TAGS" | grep -vE "^($(echo "$KEEP_TAGS" | tr '\n' '|'))$")

echo "=== 清理计划 ==="
echo "将保留的标签: $KEEP_TAGS"
echo "将删除的标签: $DELETE_TAGS"

# 执行删除
for TAG in $DELETE_TAGS; do
    echo -e "\n正在删除标签: $TAG"
    DIGEST=$(curl -s ${AUTH:+-u $AUTH} -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
        http://$REGISTRY/v2/$REPO/manifests/$TAG | jq -r '.config.digest')
    
    if [ -z "$DIGEST" ]; then
        echo "❌ 无法获取$TAG的digest,跳过"
        continue
    fi

    RESPONSE=$(curl -s -w "%{http_code}" -X DELETE ${AUTH:+-u $AUTH} \
        http://$REGISTRY/v2/$REPO/manifests/$DIGEST)
    HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
    
    if [ "$HTTP_CODE" -eq 202 ]; then
        echo "✅ $TAG 删除成功"
    else
        echo "❌ $TAG 删除失败,响应码: $HTTP_CODE"
    fi
done

# 执行垃圾回收
echo -e "\n=== 执行垃圾回收 ==="
docker exec -it registry bin/registry garbage-collect /etc/docker/registry/config.yml
echo "✅ 清理完成"

使用方法:

  1. 保存脚本为registry-cleanup.sh,修改配置参数;
  2. 给脚本加执行权限:chmod +x registry-cleanup.sh;
  3. 测试运行:./registry-cleanup.sh;
  4. 添加到crontab定期执行(比如每周日凌晨2点):
crontab -e
# 添加下面一行,替换脚本路径
0 2 * * 0 /path/to/registry-cleanup.sh >> /var/log/registry-cleanup.log 2>&1
注意事项
  • 一定要先测试排序逻辑,确保KEEP_TAGS是你真正想要保留的最新镜像;
  • 如果仓库有HTTPS认证,curl命令需要加上-k(忽略证书)或者指定证书路径;
  • 垃圾回收建议定期执行,避免磁盘空间被占用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:09:13