Docker Registry API best practice 【Docker Registry API 最佳实践】

news2024/9/21 4:23:50

文章目录

  • 1. 安装 docker
  • 2. 配置 docker
  • 4. 配置域名解析
  • 5. 部署 registry
  • 6. Registry API 管理
  • 7. 批量清理镜像
  • 8. 其他

👋 这篇文章内容:实现shell 脚本批量清理docker registry的镜像。

🔔:你可以在这里阅读:https://github.com/Ghostwritten/registry-clean.git

1. 安装 docker

  • docker 安装

2. 配置 docker

$ cat /etc/docker/daemon.json 
{
   "exec-opts": ["native.cgroupdriver=systemd"],
   "insecure-registries": ["registry.ghostwritten.com"],
   "live-restore": true,
   "log-driver": "json-file",
   "log-opts": {
     "max-size":  "100m",
     "max-file": "5"
    }
 }

# 配置代理
$ cat /usr/lib/systemd/system/docker.service.d/proxy.conf 
[Service]
Environment="HTTP_PROXY=http://192.168.21.101:7890"
Environment="HTTPS_PROXY=http://192.168.21.101:7890"
Environment="NO_PROXY=localhost,127.0.0.1,.coding.net,.tencentyun.com,.myqcloud.com,*.bsgchina.com"
$ systemctl daemon-reload && systemctl restart docker

4. 配置域名解析

服务端(192.168.21.2)配置

$ cat  /etc/unbound/unbound.conf
...
    local-data: "registry.ghostwritten.com A 192.168.21.25"
    local-data-ptr: "192.168.21.25 registry.ghostwritten.com"
....

$ systemctl restart unbound

客户端

$ cat /etc/resolv.conf 
# Generated by NetworkManager
nameserver 192.168.21.2

5. 部署 registry

测试删除镜像

$ docker run -tid --restart=always --name registry -p 80:5000 -e REGISTRY_COMPATIBILITY_SCHEMA1_ENABLED=true -e REGISTRY_STORAGE_DELETE_ENABLED=true -v /data/registry:/var/lib/registry registry:latest

6. Registry API 管理


$ curl  -q -s   'http://registry.ghostwritten.com/v2/registry/tags/list' | jq .
{
  "name": "registry",
  "tags": [
    "latest"
  ]
}

$ curl -I -X GET  'http://registry.ghostwritten.com/v2/registry/manifests/latest'
HTTP/1.1 200 OK
Content-Length: 6863
Content-Type: application/vnd.docker.distribution.manifest.v1+prettyjws
Docker-Content-Digest: sha256:f538bbbf8ff45e9872789dfcfbbcd48a44a9c87d21324595efb4df2e6b666c8c
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:f538bbbf8ff45e9872789dfcfbbcd48a44a9c87d21324595efb4df2e6b666c8c"
X-Content-Type-Options: nosniff
Date: Wed, 18 Sep 2024 09:02:51 GMT

通过API直接匹配标签删除不掉镜像
$ curl -I -X DELETE  http://registry.ghostwritten.com/v2/registry/manifests/latest
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Docker-Distribution-Api-Version: registry/2.0
X-Content-Type-Options: nosniff
Date: Wed, 18 Sep 2024 08:58:49 GMT
Content-Length: 98

#获取ID
$ docker inspect registry.ghostwritten.com/registry:latest | jq -r '.[0].RepoDigests[]' |grep registry.ghostwritten.com | awk -F '@' '{print $2}'
sha256:4d2514be50520c34f3b207fc03dd734a9b72403624d8572f8c40e9185575e453


$ curl -I -X GET  'http://registry.ghostwritten.com/v2/registry/manifests/sha256:4d2514be50520c34f3b207fc03dd734a9b72403624d8572f8c40e9185575e453'
HTTP/1.1 200 OK
Content-Length: 1363
Content-Type: application/vnd.docker.distribution.manifest.v2+json
Docker-Content-Digest: sha256:4d2514be50520c34f3b207fc03dd734a9b72403624d8572f8c40e9185575e453
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:4d2514be50520c34f3b207fc03dd734a9b72403624d8572f8c40e9185575e453"
X-Content-Type-Options: nosniff
Date: Wed, 18 Sep 2024 09:12:51 GMT



$ curl -I -X DELETE  'http://registry.ghostwritten.com/v2/registry/manifests/sha256:4d2514be50520c34f3b207fc03dd734a9b72403624d
8572f8c40e9185575e453'
HTTP/1.1 202 Accepted
Docker-Distribution-Api-Version: registry/2.0
X-Content-Type-Options: nosniff
Date: Wed, 18 Sep 2024 09:12:59 GMT
Content-Length: 0

$ curl   -s   'http://registry.ghostwritten.com/v2/_catalog' | jq .
{
  "repositories": [
    "library/busybox",
    "registry"
  ]
}

$ curl  -q -s   'http://registry.ghostwritten.com/v2/registry/tags/list' | jq .
{
  "name": "registry",
  "tags": null
}

$ rm -rf  /data/registry/docker/registry/v2/repositories/registry
$ curl -q -s http://registry.ghostwritten.com/v2/_catalog | jq .
{
  "repositories": [
    "library/busybox"
  ]
}

推送镜像

$ docker push registry.ghostwritten.com/registry:latest
The push refers to repository [registry.ghostwritten.com/registry]
3715a40eaff0: Layer already exists 
e48d56ef719d: Layer already exists 
1670fc7fdd22: Layer already exists 
f3965cc04390: Layer already exists 
d62a02444d39: Layer already exists 
latest: digest: sha256:4d2514be50520c34f3b207fc03dd734a9b72403624d8572f8c40e9185575e453 size: 1363

查询镜像标签

$ curl  -q -s   'http://registry.ghostwritten.com/v2/registry/tags/list' | jq .
{
  "name": "registry",
  "tags": [
    "latest"
  ]
}

7. 批量清理镜像

首先,这是一个清理的演示,先批量推送镜像入库。未来应对可能存在各类情况。

  • 有没有项目名的镜像
  • 多个标签的镜像
$ cat registry-images-push.sh
docker push  registry.ghostwritten.com/demo/nginx:1.26
docker push  registry.ghostwritten.com/demo/nginx:latest
docker push registry.ghostwritten.com/library/busybox:1.36.1
docker push registry.ghostwritten.com/registry:latest
docker push registry.ghostwritten.com/library/busybox:1.35.0

推送镜像入库。

$ sh registry-images-push.sh

要删除的镜像我们存放到 registry-images-clean.txt 文件中。我们会检验以下几类删除场景。

  • 删除有个多个标签的镜像检验是否会误删除;
  • 删除没有项目名的镜像;
  • 删除不存在的镜像。
$ cat registry-images-clean.txt
registry.ghostwritten.com/library/busybox:1.36.1
registry.ghostwritten.com/registry:latest
registry.ghostwritten.com/demo/nginx:1.26
registry.ghostwritten.com/demo/nginx:noexist

这个脚本的目的是从Docker注册表中批量删除镜像。在执行脚本之前,必须创建一个名为images.txt的文件,其中应该包含计划删除的映像的名称。例如,文件中的一个条目可能如下所示:registry.demo.com/library/nginx:latest。

$ cat registry-images-clean.sh 
#!/bin/bash

# Script Name: registry-images-clean.sh
# Author: ghostwritten
# Date: 2024-9-18
# Description: This script is designed to facilitate the batch deletion of images from a Docker registry. Prior to executing the script, you must create a file named images.txt, which should contain the names of the images scheduled for deletion. For example, an entry in the file might look like: registry.demo.com/library/nginx:latest. 

name=`basename $0 .sh`

action=$1


images_list() {


image_repos=`cat registry-images-clean.txt  | awk -F '/' '{print $1}' |  uniq`

for image_repo in $image_repos
do 
 repositories=$(curl -q -s http://${image_repo}/v2/_catalog | jq -r '.repositories[]')

 if [[ -n $repositories ]] ; then
  echo "$image_repo 镜像仓库列表:"

  for repo in $repositories; do

    tags=$(curl -q -s http://${image_repo}/v2/${repo}/tags/list | jq -r '.tags[]')

    if [ -z "$tags" ]; then
        echo "  No tags found"
    else
        for tag in $tags; do
            echo "  $repo:$tag"
        done
    fi
  done
 else
   echo "$image_repo 镜像仓库是空库."
 fi
done

}

images_rm() {

while IFS= read -r line
do
    image_repo=$(echo "$line" | awk -F '/' '{print $1}')
    
    image_project=$(echo "$line" | awk -F '/' '{ if (NF > 2) print $(NF-1) "/"; else print "" }')


    image_name=$(echo "$line" | awk -F '/' '{print $NF}' | awk -F ':' '{print $1}')
    
    image_tag=$(echo "$line" | awk -F '/' '{print $NF}' | awk -F ':' '{print $2}')


    response=$(curl -s "http://${image_repo}/v2/${image_project}${image_name}/tags/list")
    if echo "$response" | jq -e ".tags | index(\"${image_tag}\")" > /dev/null; then
       echo "镜像 ${image_project}${image_name}:${image_tag} 存在,准备删除..."

       source_data=`docker inspect registry | jq -r '.[0].Mounts[] | select(.Type == "bind") | .Source'`
       MANIFEST_DIGEST=`ls ${source_data}/docker/registry/v2/repositories/${image_project}${image_name}/_manifests/tags/${image_tag}/index/sha256/`

       curl -s -I -X DELETE  "http://${image_repo}/v2/${image_project}${image_name}/manifests/sha256:${MANIFEST_DIGEST}" 2>&1 > /dev/null

    
      response=$(curl -s "http://${image_repo}/v2/${image_project}${image_name}/tags/list")
      if ! echo "$response" | jq -e '.tags | length > 0' > /dev/null; then
         rm -rf ${source_data}/docker/registry/v2/repositories/${image_project}${image_name}
      fi
    else
       echo "镜像 ${image_repo}/${image_project}${image_name}:${image_tag} 不存在。"
fi


done < registry-images-clean.txt


docker exec registry  bin/registry garbage-collect /etc/docker/registry/config.yml  >> /dev/null
docker restart registry


}

case $action in
 l|ls)
        images_list
        ;;
 d|rm)
        images_rm
        ;;
 *)
        echo "Usage: $name [ls|rm]"
        exit 1
        ;;
esac
exit 0

首先,检查当前registry镜像仓库有哪些镜像。

$ sh registry-images-clean.sh ls
registry.ghostwritten.com 镜像仓库列表:
  demo/nginx:latest
  demo/nginx:1.26
  library/busybox:1.35.0
  library/busybox:1.36.1
  registry:latest
registest.bsgchina.com 镜像仓库是空库.

现在,我们开始删除 registry-images-clean.txt 的镜像。

$  registry-images-clean.sh rm
镜像 library/busybox:1.36.1 存在,准备删除...
镜像 registry:latest 存在,准备删除...
镜像 demo/nginx:1.26 存在,准备删除...
镜像 registry.ghostwritten.com/demo/nginx:noexist 不存在。
镜像 demo/nginx:noexist 存在,准备删除...

执行结束后,再次检查镜像仓库列表。

sh registry-images-clean.sh ls
registry.ghostwritten.com 镜像仓库列表:
  demo/nginx:latest
  library/busybox:1.35.0
registest.bsgchina.com 镜像仓库是空库.

8. 其他

  • 除了通过API 查看registry镜像列表,你可以部署一个 registry UI 查看镜像。
  • 另外,当你想要迁移一套具有自己镜像介质的镜像仓库。你可以参考这篇不需要推拉镜像的镜像仓库迁移教程。

参考:

  • Open Container Initiative Distribution Specification
  • https://docs.docker.com/registry/#introduction
  • https://github.com/Ghostwritten/registry-clean.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2144909.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《深度学习》—— PyTorch的神经网络模块中常用的损失函数

文章目录 前言一、回归模型中常用的损失函数1、平均绝对误差损失&#xff08;L1Loss&#xff09;2、均方误差损失&#xff08;MSELoss也称L2Loss&#xff09;3、SmoothL1Loss 二、分类模型中常用的损失函数1、负对数似然损失&#xff08;NLLLoss&#xff09;2、二元交叉熵损失&…

XML映射器-动态sql

01-动态sql 1.实现动态条件SQL 第一种方法在sql语句中加入where 11其他条件都加and就行,这样就可以根据if条件来判断要传递的参数可以有几个 第二种方法用where标签给if语句包起来 where标签的作用如下图 第三种方法用trim标签解释如下图 用choose也可以实现条件查询如下图,…

【数据结构与算法 | 灵神题单 | 自底向上DFS篇】力扣508, 1026, 951

1. 力扣508&#xff1a;出现次数最多的子树元素和 1.1 题目&#xff1a; 给你一个二叉树的根结点 root &#xff0c;请返回出现次数最多的子树元素和。如果有多个元素出现的次数相同&#xff0c;返回所有出现次数最多的子树元素和&#xff08;不限顺序&#xff09;。 一个结…

在Ubuntu中编译含有JSON的文件出现报错

在ubuntu中进行JSON相关学习的时候&#xff0c;我发现了一些小问题&#xff0c;决定与大家进行分享&#xff0c;减少踩坑时候出现不必要的时间耗费 截取部分含有JSON部分的代码进行展示 char *str "{ \"title\":\"JSON Example\", \"author\&…

Web植物管理系统-下位机部分

本节主要展示上位机部分&#xff0c;采用BSP编程&#xff0c;不附带BSP中各个头文件的说明&#xff0c;仅仅是对main逻辑进行解释 main.c 上下位机通信 通过串口通信&#xff0c;有两位数据验证头&#xff08;verify数组中保存对应的数据头 0xAA55) 通信格式 上位发送11字节…

保护您的企业免受网络犯罪分子侵害的四个技巧

在这个日益数字化的时代&#xff0c;小型企业越来越容易受到网络犯罪的威胁。网络犯罪分子不断调整策略&#xff0c;并使用人工智能来推动攻击。随着技术的进步&#xff0c;您的敏感数据面临的风险也在增加。 风险的不断增大意味着&#xff0c;做好基本工作比以往任何时候都更…

Java--stream流、方法引用

Stream流 - Stream流的好处 - 直接阅读代码的字面意思即可完美展示无关逻辑方式的语义 - Stream流把真正的函数式编程风格引入到Java中 - 代码简洁 - Stream流的三类方法 - 获取Stream流 - 创建一条流水线,并把数据放到流水线上准备进行操作 - 中间方法 - 流水线上的操作 - 一次…

【代码随想录训练营第42期 Day60打卡 - 图论Part10 - Bellman_ford算法系列运用

目录 一、Bellman_ford算法的应用 二、题目与题解 题目一&#xff1a;卡码网 94. 城市间货物运输 I 题目链接 题解&#xff1a;队列优化Bellman-Ford算法&#xff08;SPFA&#xff09; 题目二&#xff1a;卡码网 95. 城市间货物运输 II 题目链接 题解&#xff1a; 队列优…

MySQL高阶1783-大满贯数量

题目 找出每一个球员赢得大满贯比赛的次数。结果不包含没有赢得比赛的球员的ID 。 结果集 无顺序要求 。 准备数据 Create table If Not Exists Players (player_id int, player_name varchar(20)); Create table If Not Exists Championships (year int, Wimbledon int, F…

Unity 高亮插件HighlightPlus介绍

仅对官方文档进行了翻译 注意:官方文档本身就落后实际,但对入门仍很有帮助,核心并没有较大改变,有的功能有差异,以实际为准.(目前我已校正了大部分差异,后续我会继续维护该文档) 为什么为该插件做翻译?功能强大,使用简单,且还在维护. 基于此版本的内置渲染管线文档 快速开始…

C语言之预处理详解(完结撒花)

目录 前言 一、预定义符号 二、#define 定义常量 三、#define定义宏 四、宏与函数的对比 五、#和## 运算符 六、命名约定 七、#undef 八、条件编译 九、头文件的包含 总结 前言 本文为我的C语言系列的最后一篇文章&#xff0c;主要讲述了#define定义和宏、#和##运算符、各种条件…

9.18作业

提示并输入一个字符串&#xff0c;统计该字符串中字母、数字、空格、其他字符的个数并输出 代码展示 #include <iostream>using namespace std;int main() {string str;int countc 0; // 字母计数int countn 0; // 数字计数int count 0; // 空格计数int counto 0;…

IEEE-754 32位十六进制数 转换为十进制浮点数

要将 IEEE-754 32位十六进制数 转换为 十进制浮点数&#xff0c;可以使用LabVIEW中的 Type Cast 函数。以下是一些具体步骤&#xff0c;以及相关实例的整理&#xff1a; 实现步骤&#xff1a; 输入十六进制数&#xff1a;在LabVIEW中&#xff0c;首先需要创建一个输入控制器&am…

2024最新软件测试面试题【1000道题含答案】

1、自动化代码中,用到了哪些设计模式? 单例设计模式 工厂模式PO设计模式数据驱动模式面向接口编程设计模式 2、什么是断言( Assert) ? 断言Assert用于在代码中验证实际结果是不是符合预期结果&#xff0c;如果测试用例执行失败会抛出异常并提供断言日志 3、什么是web自动化…

C++之继承(通俗易懂版)

前言&#xff1a;我们都知道C是一门支持过程化编程&#xff0c;面向对象的高级语言&#xff0c;既然是面向对象的语言&#xff0c;那么对于对象而言&#xff0c;对象会有很多中相同的属性&#xff0c;举个例子:你和你老师&#xff0c;你们都有着共同的属性和身份&#xff0c;例…

Longman Dictionary of Contemporary English (朗文当代高级英语辞典)

Longman Dictionary of Contemporary English {朗文当代高级英语辞典} 1. Longman Dictionary of Contemporary English1.1. school References 1. Longman Dictionary of Contemporary English https://www.ldoceonline.com/ 1.1. school https://www.ldoceonline.com/dicti…

C++: 高效使用智能指针的8个建议

前言&#xff1a;智能指针是C11的新特性&#xff0c;它基于RAII实现&#xff0c;可以自动管理内存资源&#xff0c;避免内存泄漏的发生&#xff0c;但是智能指针也并不是万能的&#xff0c;如果不正确使用智能指针&#xff0c;也会导致内存泄漏的发生&#xff0c;因此&#xff…

嵌入式人工智能项目及人工智能应用项目——大合集列表查阅

本文的项目合集列表可能更新不及时&#xff08;会及时更新&#xff09;&#xff0c;可查阅实时更新的链接如下。 嵌入式人工智能及人工智能应用项目合集实时更新链接如下&#xff1a; 阿齐嵌入式人工智能及人工智能应用项目合集 (kdocs.cn)https://www.kdocs.cn/l/cc97tuieys4…

MacOS安装MAT教程

MAT下载地址MAT下载地址MAT下载地址MAT下载地址 如果不知道你的芯片类型, 可以执行如下命令 uname -m

Fiddler抓包工具实战

文章目录 &#x1f7e2; Fiddler入门到精通&#x1f449;主要功能&#x1f449;使用场景 &#x1f7e2; 一、Fiddler抓包和F12抓包对比&#x1f7e2; 二、Fiddler的核心功能&#x1f7e2; 三、Fiddler的工作原理&#x1f7e2; 四、Fiddler功能配置使用&#x1f449;规则设置&am…