HarborAPI实战:批量删除镜像的高效指南

HarborAPI实战:批量删除镜像的高效指南

在容器化部署日益普及的今天,Harbor作为企业级私有镜像仓库的核心组件,承担着镜像存储、分发与安全管理的重任。然而,随着项目迭代,镜像仓库中积累的冗余镜像不仅占用存储资源,还可能引发安全风险。手动逐个删除镜像效率低下,而Harbor提供的RESTful API为批量操作提供了可能。本文将围绕“实战使用HarborAPI批量删除镜像”,从环境准备、API调用、脚本编写到安全实践,提供一套完整的解决方案。

一、环境准备:Harbor API访问基础

1.1 确认Harbor版本与API支持

Harbor自v1.10版本起,提供了更完善的API接口(基于Swagger文档),支持镜像、项目、标签等资源的CRUD操作。需确保Harbor版本≥v1.10,并通过/api/v2.0/swagger访问API文档,确认DELETE /projects/{project_id}/repositories/{repository_name}/artifacts/{reference}接口可用。

1.2 获取API访问权限

Harbor API默认启用认证,需通过以下方式获取访问令牌:

  • Basic Auth:使用Harbor管理员账号的用户名:密码,经Base64编码后作为Authorization: Basic <token>
  • Bearer Token:通过Harbor UI生成个人访问令牌(PAT),或使用OAuth2流程获取JWT令牌。推荐PAT方式,因其更灵活且支持细粒度权限控制。

示例(生成Base64编码的Basic Auth):

  1. echo -n "admin:Harbor12345" | base64
  2. # 输出:YWRtaW46SGFyYm9yMTIzNDU=

1.3 测试API连通性

使用curl测试API是否可达:

  1. curl -X GET "https://<harbor-host>/api/v2.0/projects" \
  2. -H "Authorization: Basic YWRtaW46SGFyYm9yMTIzNDU=" \
  3. -H "accept: application/json"

若返回项目列表,则说明API可正常访问。

二、Harbor API核心:批量删除镜像的实现路径

2.1 理解镜像删除的API逻辑

Harbor中镜像的删除需通过以下步骤:

  1. 获取项目ID:通过项目名称查询项目ID。
  2. 列出镜像仓库:获取项目下的所有仓库(Repository)。
  3. 获取镜像标签:查询每个仓库下的所有标签(Artifact)。
  4. 删除指定标签:调用删除接口删除镜像。

2.2 分步实现:从查询到删除

步骤1:获取项目ID

  1. PROJECT_NAME="my-project"
  2. PROJECT_ID=$(curl -sX GET "https://<harbor-host>/api/v2.0/projects?name=$PROJECT_NAME" \
  3. -H "Authorization: Basic <token>" | jq -r '.[0].project_id')

步骤2:列出仓库并遍历

  1. REPOS=$(curl -sX GET "https://<harbor-host>/api/v2.0/projects/$PROJECT_ID/repositories" \
  2. -H "Authorization: Basic <token>" | jq -r '.[].name')
  3. for REPO in $REPOS; do
  4. # 步骤3:获取仓库下的标签
  5. ARTIFACTS=$(curl -sX GET "https://<harbor-host>/api/v2.0/projects/$PROJECT_ID/repositories/$REPO/artifacts" \
  6. -H "Authorization: Basic <token>" | jq -r '.[].tags[].name')
  7. for TAG in $ARTIFACTS; do
  8. # 步骤4:删除标签(镜像)
  9. REFERENCE="${REPO}:${TAG}"
  10. curl -X DELETE "https://<harbor-host>/api/v2.0/projects/$PROJECT_ID/repositories/$REPO/artifacts/$REFERENCE" \
  11. -H "Authorization: Basic <token>"
  12. done
  13. done

2.3 优化:批量删除的脚本实现

将上述逻辑封装为Shell脚本(harbor_bulk_delete.sh),支持按项目、仓库或标签过滤:

  1. #!/bin/bash
  2. HARBOR_HOST="your.harbor.host"
  3. TOKEN="Basic $(echo -n "admin:Harbor12345" | base64)"
  4. PROJECT_NAME="my-project"
  5. # 获取项目ID
  6. PROJECT_ID=$(curl -sX GET "https://$HARBOR_HOST/api/v2.0/projects?name=$PROJECT_NAME" \
  7. -H "Authorization: $TOKEN" | jq -r '.[0].project_id')
  8. # 列出仓库
  9. REPOS=$(curl -sX GET "https://$HARBOR_HOST/api/v2.0/projects/$PROJECT_ID/repositories" \
  10. -H "Authorization: $TOKEN" | jq -r '.[].name')
  11. for REPO in $REPOS; do
  12. # 获取标签并删除(示例:删除所有标签)
  13. ARTIFACTS=$(curl -sX GET "https://$HARBOR_HOST/api/v2.0/projects/$PROJECT_ID/repositories/$REPO/artifacts" \
  14. -H "Authorization: $TOKEN" | jq -r '.[].tags[].name')
  15. for TAG in $ARTIFACTS; do
  16. REFERENCE="${REPO}:${TAG}"
  17. echo "Deleting $REFERENCE..."
  18. curl -X DELETE "https://$HARBOR_HOST/api/v2.0/projects/$PROJECT_ID/repositories/$REPO/artifacts/$REFERENCE" \
  19. -H "Authorization: $TOKEN" -sSf > /dev/null
  20. done
  21. done

三、进阶实践:安全与效率提升

3.1 权限控制与最小化原则

  • 使用PAT而非管理员账号:为脚本创建专用服务账号,仅授予项目删除权限。
  • 限制API访问范围:通过Harbor的系统配置认证设置API白名单。

3.2 错误处理与日志记录

在脚本中添加错误捕获:

  1. if ! curl -X DELETE "https://$HARBOR_HOST/api/v2.0/projects/$PROJECT_ID/repositories/$REPO/artifacts/$REFERENCE" \
  2. -H "Authorization: $TOKEN" -sSf > /dev/null; then
  3. echo "Error deleting $REFERENCE" >> delete_errors.log
  4. fi

3.3 性能优化:并行删除

使用xargsGNU parallel加速删除:

  1. curl -sX GET "https://$HARBOR_HOST/api/v2.0/projects/$PROJECT_ID/repositories" \
  2. -H "Authorization: $TOKEN" | jq -r '.[].name' | \
  3. xargs -I {} sh -c '
  4. REPO="$1"
  5. ARTIFACTS=$(curl -sX GET "https://$HARBOR_HOST/api/v2.0/projects/$PROJECT_ID/repositories/$REPO/artifacts" \
  6. -H "Authorization: $TOKEN" | jq -r ".[].tags[].name")
  7. for TAG in $ARTIFACTS; do
  8. REFERENCE="${REPO}:${TAG}"
  9. curl -X DELETE "https://$HARBOR_HOST/api/v2.0/projects/$PROJECT_ID/repositories/$REPO/artifacts/$REFERENCE" \
  10. -H "Authorization: $TOKEN" -sSf > /dev/null || echo "Failed: $REFERENCE" >> delete_errors.log
  11. done
  12. ' _ {}

四、常见问题与解决方案

4.1 权限不足(403 Forbidden)

  • 原因:账号无项目删除权限或PAT过期。
  • 解决:在Harbor UI中检查账号角色,重新生成PAT。

4.2 镜像未删除(200 OK但镜像仍存在)

  • 原因:Harbor的垃圾回收(GC)未运行,删除的镜像标记为软删除
  • 解决:手动触发GC:
    1. curl -X POST "https://<harbor-host>/api/v2.0/system/gc/schedule" \
    2. -H "Authorization: Basic <token>"

4.3 批量删除效率低

  • 优化:减少API调用次数,例如先获取所有待删除镜像的ID,再批量提交删除请求(需Harbor支持批量API)。

五、总结与最佳实践

  1. 环境准备:确认Harbor版本、获取API令牌、测试连通性。
  2. 分步实现:通过项目ID→仓库→标签的路径定位镜像。
  3. 脚本封装:使用Shell或Python编写可复用的删除脚本。
  4. 安全与效率:控制权限、记录日志、并行处理。
  5. 后续维护:定期运行GC,监控存储使用情况。

通过Harbor API批量删除镜像,不仅能释放存储资源,还能提升仓库管理的自动化水平。建议将脚本纳入CI/CD流程,例如在构建失败时自动清理旧镜像,实现资源的高效利用。