前几天写了kubernetes CD 使用Jenkins的文章,其中获取镜像列表是调用的HarborAPI接口,在镜像比较多的情况下接口响应时间比较长,导致整体体验很差。

之前没有清理过Harbor镜像,这里简单的写个Shell脚本轮询删除各个项目下的镜像

环境信息

  • Harbor V1.6 from Kubernetes部署
  • Shell
  • Crontab

脚本需求

  1. 一键删除
  2. 可指定保留近多少天的版本
  3. 可指定最低保留多少个版本

实现

思路

  • Harbor镜像总共分为几层
    • 项目 -> 镜像仓库 -> 镜像标签
  • 使用for循环嵌套逐层获取
  • 判断镜像标签的创建时间,并排序去除需保留的版本号数量,然后再删除

Harbor 接口

  • $Address/api/projects # 获取项目列表
  • $Address/api/search?q=$Project # 获取项目中的镜像仓库列表
  • $Address/api/repositories/$Project/$repo/tags # 获取镜像仓库中的镜像标签列表

脚本

#!/bin/bash

#保留近多少天的版本
DeleteDate=$(date -d '-180day' +%s)
#保留近多少个版本
DeleteVersion=80

#Harbor账户
User="harbor:***"
#Harbor地址
Address="https://harbor.***.net"

LogFile="/tmp/harbor-image-delete.log"

Projects=$(curl -s -u $User -X GET -H "Content-Type: application/json" "$Address/api/projects" |jq .[].name | sed ':a;N;s/"//g;ta')
for Project in $Projects
do
#获取项目下的所有镜像信息
Items=$(curl -s -u $User -X GET -H "Content-Type: application/json" "$Address/api/search?q=$Project" | jq .repository[].repository_name | sed ':a;N;s/"//g;ta')
#Items="ai/chat"
#获取所有tag并删除掉最近$DeleteVersion个版本号
for Item in $Items
do
Tags=$(curl -s -u $User -X GET -H "Content-Type: application/json" "$Address/api/repositories/${Item}/tags"|jq -c ".[] | {name:.name,created:.created}" |awk -F'"|T' '{print $8,$0}' | sort -r | awk '{print $2}' | sed "1,${DeleteVersion}d" )

#如果获取到的tags数量为0就退出循环
[ -n "$Tags" ] || continue

#判断tag创建时间
for Tag in $Tags
do
TagName=$(echo $Tag | awk -F'"' '{print $4}')
TagDate=$(date -d `echo $Tag|awk -F'"|T' '{print $8}'` +%s)
[[ $TagDate < $DeleteDate ]] || continue
# 超过$DeleteDate时间的就删除
echo "`date +%F-%T` ${Item} $Tag delete" | tee -a $LogFile
curl -s -u $User -X DELETE -H "Content-Type: application/json" "$Address/api/repositories/${Item}/tags/$TagName"
done
done
done

## Harbor v1.6版本 还需登录harbor-registry容器执行GC回收操作
PodName=$(kubectl -n harbor get po |grep registry|awk '{print $1}')
kubectl -n harbor exec $PodName -it registry garbage-collect /etc/registry/config.yml

删除Charts的脚本

#!/bin/bash

#保留近180天的版本
DeleteDate=$(date -d '-180day' +%s)
#保留近60个版本
DeleteVersion=80

#Harbor账户
User="harbor:***"
#Harbor地址
Address="https://harbor.***.net"

LogFile="/tmp/harbor-charts-delete.log"

Projects=$(curl -s -u $User -X GET -H "Content-Type: application/json" "$Address/api/projects" |jq .[].name | sed ':a;N;s/"//g;ta')
for Project in $Projects
do
#获取项目下的所有Charts信息
Items=$(curl -s -u $User -X GET -H "Content-Type: application/json" "$Address/api/chartrepo/$Project/charts" |jq .[].Name | sed ':a;N;s/"//g;ta')
#获取所有tag并删除掉最近$DeleteVersion个版本号
for Item in $Items
do
Tags=$(curl -s -u $User -X GET -H "Content-Type: application/json" "$Address/api/chartrepo/${Project}/charts/${Item}"|jq -c ".[] | {name:.version,created:.created}" |awk -F'"|T' '{print $8,$0}' | sort -r | awk '{print $2}' | sed "1,${DeleteVersion}d" )

#如果获取到的tags数量为0就退出循环
[ -n "$Tags" ] || continue

#判断tag创建时间
for Tag in $Tags
do
TagName=$(echo $Tag | awk -F'"' '{print $4}')
TagDate=$(date -d `echo $Tag|awk -F'"|T' '{print $8}'` +%s)
[[ $TagDate < $DeleteDate ]] || continue
# 超过$DeleteDate时间的就删除
echo "`date +%F-%T` ${Item} $Tag delete" | tee -a $LogFile
curl -s -u $User -X DELETE -H "Content-Type: application/json" "$Address/api/chartrepo/${Project}/charts/${Item}/${TagName}"
done
done
done