momo's Blog.

清理docker registry中的镜像

字数统计: 679阅读时长: 3 min
2021/07/07 Share

前言

公司的镜像仓库要满了, 需要清理一些已经不会在需要的镜像

使用脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/bin/bash
set -eo pipefail

CMD=$0

function isTruthy {
local arg=$1

if [[ "$arg" = true ]] || [[ "$arg" = "true" ]] || [[ "$arg" -eq 1 ]]; then
echo "true"
fi

}

if [[ ${TRACE} ]] && [[ $(isTruthy "$TRACE") ]]; then
set -x
fi


function usage {
cat <<EOU
Usage:
$CMD REGISTRY_BASE_URL ACTION [OPTIONS..]
Actions:
- list list repos
- list REPO list tags for repo
- delete REPO TAG delete tag for repo
Example:
List all repos
/$ $CMD https://registry.my.domain list
List tags for one repo
/$ $CMD https://registry.my.domain list some-repo
Delete tag for a repo
/$ $CMD https://registry.my.domain delete some-repo some-tag
EOU
exit 1
}



[ $# -lt 2 ] && usage

set +e
PROTO="$(echo $1 | grep :// | sed -e's,^\(.*://\).*,\1,g')"
set -e

[ -z "$PROTO" ] && >&2 echo "ERROR: Must have protocol in registry url" && usage

# remove the protocol
REG="$(echo ${1/$PROTO/})"
shift
ACTION="$1"
shift

CREDS=""
DOCKER_CONFIG="$HOME/.docker/config.json"

if [[ ${BASIC_AUTH} ]]; then
CREDS="Authorization: Basic $(echo -n $BASIC_AUTH|base64)"
elif [[ -f "$DOCKER_CONFIG" ]]; then
AUTH_INFO=$(jq -r '.auths["'$REG'"].auth' < "$DOCKER_CONFIG")
if [ "$AUTH_INFO" = "null" ]; then
AUTH_INFO=$(jq -r '.auths."'$PROTO$REG'".auth' < "$DOCKER_CONFIG")
if [ "$AUTH_INFO" = "null" ]; then
echo "ERROR: Failed to retrieve credentials from $DOCKER_CONFIG for ${REG}!"
exit 4
fi
fi
CREDS="Authorization: Basic $AUTH_INFO"
fi

SEC_FLAG=""

if [[ ${INSECURE_REGISTRY} ]] && [[ $(isTruthy "$INSECURE_REGISTRY") ]]; then
SEC_FLAG="-k"
fi

function curlCmd {
curl "$SEC_FLAG" --header "$CREDS" $*
}



case "$ACTION" in
list)
if [ $# -eq 1 ]; then
repo=${1}
if [ -n "$repo" ]; then
curlCmd -s "$PROTO$REG/v2/$repo/tags/list" | jq -r '.tags|.[]'
fi
else
curlCmd -s "$PROTO$REG/v2/_catalog?n=500" | jq -r '.repositories|.[]'
fi

;;
delete)
repo=$1
tag=$2
response=$(curlCmd -v -s -H "Accept:application/vnd.docker.distribution.manifest.v2+json" "$PROTO$REG/v2/$repo/manifests/$tag" 2>&1)
digest=$(echo "$response" | grep -i "< Docker-Content-Digest:"|awk '{print $3}' || echo "")
[ -z "$digest" ] &&
response=$(curlCmd -v -s -H "Accept:application/vnd.oci.image.manifest.v1+json" "$PROTO$REG/v2/$repo/manifests/$tag" 2>&1) &&
digest=$(echo "$response" | grep -i "< Docker-Content-Digest:"|awk '{print $3}')
digest=${digest//[$'\t\r\n']}
echo "DIGEST: $digest"
result=$(curlCmd -s -o /dev/null -w "%{http_code}" -H "Accept:application/vnd.docker.distribution.manifest.v2+json" -X DELETE "$PROTO$REG/v2/$repo/manifests/$digest")
if [ "$result" -eq 202 ]; then
echo "Successfully deleted"
exit 0
else
echo "Failed to delete: $result"
exit 3
fi
;;
esac

用法

1
2
3
4
5
6
7
8
9
10
11
12
13
Usage:
$CMD REGISTRY_BASE_URL ACTION [OPTIONS..]
Actions:
- list list repos
- list REPO list tags for repo
- delete REPO TAG delete tag for repo
Example:
List all repos
/$ $CMD https://registry.my.domain list
List tags for one repo
/$ $CMD https://registry.my.domain list some-repo
Delete tag for a repo
/$ $CMD https://registry.my.domain delete some-repo some-tag

开启api接口删除的功能

config.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
version: 0.1
log:
fields:
service: registry
storage:
filesystem:
rootdirectory: /var/lib/registry
maxthreads: 100
// 新增
delete:
enabled: true
http:
addr: :5000
headers:
X-Content-Type-Options: [nosniff]

查找镜像

1
2
// 过滤出不需要的版本
BASIC_AUTH=a:dwadad ./docker_reg_tool.sh https://docker-registry.dawdawdawd.com list dwadwad/server | grep dddd-1.12

删除镜像

1
BASIC_AUTH=a:dwadad ./docker_reg_tool.sh https://docker-registry.dawdawdawd.com  list dwadwad/server | grep dddd-1.12 | xargs -I {} ./docker_reg_tool.sh https://docker-registry.dawdawdawd.com  delete dwadwad/server {}

手动垃圾回收

1
bin/registry garbage-collect  /etc/docker/registry/config.yml

删除完成以后, 记得关闭接口删除的功能,以防研发等其他人员通过接口误删除镜像.

参考文档

CATALOG
  1. 1. 前言
  2. 2. 使用脚本
    1. 2.1. 用法
    2. 2.2. 开启api接口删除的功能
    3. 2.3. 查找镜像
    4. 2.4. 删除镜像
    5. 2.5. 手动垃圾回收
  3. 3. 参考文档