• # 我实践:用docker registry API 获取清单并删除某仓库某tag镜像


    我实践:用docker registry API 获取清单并删除某仓库某tag镜像


    参考:

    官方文档:https://docs.docker.com/registry/spec/api/#detail
    民间博客:https://blog.csdn.net/weixin_34210740/article/details/90620559

    1 登录方式实践

    curl 参数说明:

    -s 静默

    -H 设置请求头

    -X 请求方法

    -I 仅显示请求头

    -v 显示详细信息,包含请求头与结果

    1.1 用header的方式登录

    1. 对用户名密码进行base64编码
    echo -n "${DOCKER_REPO_USER}:${DOCKER_REPO_PASSWORD}" | base64
    dWZpcGY6MTIzNDU2
    
    • 1
    • 2
    1. 加入到header实现登录
    [root@v-192-168-11-81-deploy:~/deploy-bmp/deploy]# curl  -s -H "Authorization: Basic dWZpcGY6MTIzNDU2"  https://${DOCKER_REPO}/v2/
    {}
    
    • 1
    • 2

    1.2 用用户名密码的方式登录

    [root@v-192-168-11-81-deploy:~/deploy-bmp/deploy]# curl  -s -u ${DOCKER_REPO_USER}:${DOCKER_REPO_PASSWORD}  https://${DOCKER_REPO}/v2/
    {}
    
    • 1
    • 2

    2 列出镜像仓库

    [root@v-192-168-11-81-deploy:~/deploy-bmp/deploy]# curl -s -H "Authorization: Basic dWZpcGY6MTIzNDU2"  https://${DOCKER_REPO}/v2/_catalog
    {"repositories":["ufipf/datakit","ufipf/datakit-zzxia","ufipf/fluentd-gcl","ufipf/gc-agent-service","ufipf/gc-app-service","ufipf/gc-apply-service","ufipf/gc-attachment-service","ufipf/gc-auth-service","ufipf/gc-batch-service","ufipf/gc-certify-service","ufipf/gc-claim-service","ufipf/gc-client-app-service","ufipf/gc-client-service","ufipf/gc-config","ufipf/gc-endorse-service","ufipf/gc-finance-service","ufipf/gc-gateway","ufipf/gc-message-service","ufipf/gc-monitor","ufipf/gc-party-service","ufipf/gc-payment-service","ufipf/gc-platform-node","ufipf/gc-platform-service","ufipf/gc-policy-service","ufipf/gc-product-service","ufipf/gc-public-service","ufipf/gc-registry","ufipf/gc-renewal-service","ufipf/gc-report-service","ufipf/gc-sentinel-service","ufipf/gc-system-service","ufipf/gc-thirdparty-service","ufipf/gc-travel-service","ufipf/gc-workflow-manage-service","ufipf/gc-workflow-service","ufipf/my-oracle-java-8","ufipf/nacos-server","ufipf/neo4j","ufipf/rabbitmq","ufipf/redis","ufipf/sentinel-dashboard"]}
    
    • 1
    • 2

    3 列出指定镜像仓库的tag

    [root@v-192-168-11-81-deploy:~/deploy-bmp/deploy]# curl -u ${DOCKER_REPO_USER}:${DOCKER_REPO_PASSWORD} -s -X GET https://${DOCKER_REPO}/v2/ufipf/gc-gateway/tags/list | jq .tags[]
    "latest"
    "2022.06.21.185554"
    "2022.08.12.171408"
    "2022.07.22.180130"
    "2022.08.11.153751"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4 找出指定镜像仓库指定tag的【镜像manifest digest】及【镜像blob digest】

    约定简称:

    【镜像manifest digest】 :镜像摘要,就是【TAG】,是关联名称
    【镜像blob digest】 :镜像blob摘要,就是【IMAGE ID】,是关联实体

    • API有如下header(详细请看我的另一篇文章:https://blog.csdn.net/zhf_sy/article/details/126558336):
      -u ${DOCKER_REPO_USER}:${DOCKER_REPO_PASSWORD}  \
      -H 'Accept: application/vnd.docker.distribution.manifest.list.v2+json'  \
      -H 'Accept: application/vnd.docker.distribution.manifest.v1+prettyjws'  \
      -H 'Accept: application/json'  \
      -H 'Accept: application/vnd.docker.distribution.manifest.v2+json'  \
    
    • 1
    • 2
    • 3
    • 4
    • 5

    但实际使用只有一个看起来有用,用-H 'Accept: application/vnd.docker.distribution.manifest.v2+json'这一个就好了,其他感觉没啥用(具体看我的另一篇文章测试结果:https://blog.csdn.net/zhf_sy/article/details/126558336)

    • 执行结果如下:
    [root@v-192-168-11-81-deploy:~/deploy-bmp/deploy]# curl -s -v -X GET  \
    >   -u ${DOCKER_REPO_USER}:${DOCKER_REPO_PASSWORD}  \
    >   -H 'Accept: application/vnd.docker.distribution.manifest.v2+json'  \
    >   https://${DOCKER_REPO}/v2/ufipf/gc-gateway/manifests/2022.06.21.185554
    * About to connect() to docker-repo port 5000 (#0)
    *   Trying 192.168.11.79...
    * Connected to docker-repo (192.168.11.79) port 5000 (#0)
    * Initializing NSS with certpath: sql:/etc/pki/nssdb
    *   CAfile: /etc/pki/tls/certs/ca-bundle.crt
      CApath: none
    * SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    * Server certificate:
    * 	subject: E=admin@zjlh.lan,CN=zjlh.lan,OU=IT,O=ZJLH,ST=GuangDong,C=CN
    * 	start date: 3月 09 10:07:59 2022 GMT
    * 	expire date: 3月 09 10:07:59 2023 GMT
    * 	common name: zjlh.lan
    * 	issuer: E=admin@zzxia.vip,CN=ZZXIA-ROOT-CA,OU=GGBang,O=ZZXIA,L=GuangZhou,ST=GuangDong,C=CN
    * Server auth using Basic with user 'ufipf'
    > GET /v2/ufipf/gc-gateway/manifests/2022.06.21.185554 HTTP/1.1
    > Authorization: Basic dWZpcGY6MTIzNDU2
    > User-Agent: curl/7.29.0
    > Host: docker-repo:5000
    > Accept: application/vnd.docker.distribution.manifest.v2+json
    > 
    < HTTP/1.1 200 OK
    < Content-Length: 2419
    < Content-Type: application/vnd.docker.distribution.manifest.v2+json
    < Docker-Content-Digest: sha256:aae88d1f9b7f666c9c8f9751142302ec025921656fcbafc6e6890e8bd96541d6   #--- 这个是镜像摘要【TAG】(header-->Docker-Content-Digest)
    < Docker-Distribution-Api-Version: registry/2.0
    < Etag: "sha256:aae88d1f9b7f666c9c8f9751142302ec025921656fcbafc6e6890e8bd96541d6"
    < X-Content-Type-Options: nosniff
    < Date: Wed, 24 Aug 2022 08:33:55 GMT
    < 
    {
       "schemaVersion": 2,
       "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
       "config": {
          "mediaType": "application/vnd.docker.container.image.v1+json",
          "size": 5992,
          "digest": "sha256:398435b7803045ffceced9cb02c1f4d4136fb3e257c005e866760d09cff7886c"         #--- 这个是镜像ID【IMAGE ID】,即镜像blob摘要(config-->digest)
       },
       "layers": [
          {
             "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
             "size": 52472066,
             "digest": "sha256:7448db3b31eb523ef8dd3651601d4c2abad0d7a6a12b9c9e85f55ed9dad0ab8e"
          },
          {
             "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
             "size": 19192681,
             "digest": "sha256:c36604fa79391bd9451d544c5503da6b56125d5178f56b2b1559d02055b708d1"
          },
          {
             "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
             "size": 43159118,
             "digest": "sha256:29e8ef0e3340ebc06839633b3f6fcdf562469e5c66973c99b46330d426cbf6c1"
          },
          {
             "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
             "size": 599182,
             "digest": "sha256:a0c934d2565ddc9598089e06006d5a358db0b659c6a23c7619c04aa145966c10"
          },
          {
             "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
             "size": 215,
             "digest": "sha256:a360a17c9cab11fa222d7fd12996ae2581bc3372ec55a4ac3d670dba2961993b"
          },
          {
             "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
             "size": 240,
             "digest": "sha256:cfcc996af805c1a734f60578932d6136bf727650456a1636aaacff6f2733a80c"
          },
          {
             "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
             "size": 131618577,
             "digest": "sha256:2cf01472420269093f2df54934448c1897eed7a8f0ec8f2056b6d67cb012fb78"
          },
          {
             "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
             "size": 289664,
             "digest": "sha256:4bc402a00dfed189b43794282aaa5d84a3b9b548bc81d901a5a2c85721c855de"
          },
          {
             "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
             "size": 177,
             "digest": "sha256:fb198956117173922602260f3d31f7b17004b4b2c327ca287150c23324379183"        #--- `layers`摘要
          },
          {
             "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
             "size": 49553405,
             "digest": "sha256:**29914e67f49a**4e89b92f18cf83c47dc2db6ab62f1d90ef7a57bb4a62f969669f"    #--- `layers`摘要
          }
       ]
    * Connection #0 to host docker-repo left intact
    }
    
    • 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
    • 拉取镜像指定tag,查看摘要(用以对比)
    [root@v-192-168-11-81-deploy:~/deploy-bmp/deploy]# docker pull  ${DOCKER_REPO}/ufipf/gc-gateway:2022.06.21.185554
    2022.06.21.185554: Pulling from ufipf/gc-gateway
    7448db3b31eb: Already exists 
    c36604fa7939: Already exists 
    29e8ef0e3340: Already exists 
    a0c934d2565d: Already exists 
    a360a17c9cab: Already exists 
    cfcc996af805: Already exists 
    2cf014724202: Already exists 
    4bc402a00dfe: Already exists 
    fb1989561171: Pull complete                                                                  #--- 与上面的`layers`倒数第二个对应
    29914e67f49a: Pull complete                                                                  #--- 与上面的`layers`最后一个对应
    Digest: sha256:aae88d1f9b7f666c9c8f9751142302ec025921656fcbafc6e6890e8bd96541d6              #--- 镜像ID【IMAGE ID】
    Status: Downloaded newer image for docker-repo:5000/ufipf/gc-gateway:2022.06.21.185554
    docker-repo:5000/ufipf/gc-gateway:2022.06.21.185554
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 显示镜像指定tag的摘要与ID(用以对比)
    [root@v-192-168-11-81-deploy:~/deploy-bmp/deploy]# docker image ls --digests
    REPOSITORY                                         TAG                 DIGEST                                                                    IMAGE ID            CREATED             SIZE
    docker-repo:5000/ufipf/gc-gateway              2022.06.21.185554   sha256:aae88d1f9b7f666c9c8f9751142302ec025921656fcbafc6e6890e8bd96541d6   398435b78030        2 months ago        699MB
    
    # 这个结果与上面对比,可以看到对应关系
    
    • 1
    • 2
    • 3
    • 4
    • 5

    5 删除指定镜像仓库指定tag的manifest(就是TAG)

    # DELETE`/v2//manifests/`
    
    [root@v-192-168-11-81-deploy:~/deploy-bmp/deploy]# curl -s -I -X DELETE  \
    >   -u ${DOCKER_REPO_USER}:${DOCKER_REPO_PASSWORD}  \
    >   https://${DOCKER_REPO}/v2/ufipf/gc-gateway/manifests/sha256:aae88d1f9b7f666c9c8f9751142302ec025921656fcbafc6e6890e8bd96541d6
    
    # 202 成功
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    6 删除指定镜像指定tag的blob(就是TAG对应的镜像实体:IMAGE ID)

    一般需要先删blob,再删manifest,否则先删除manifest可能或找不到这个镜像的blob信息了,但是,可以通过docker exec -ti docker_registry_srv registry garbage-collect /etc/docker/registry/config.yml清理掉没有TAG关联的镜像blob实体(这里假设我们的docker registry仓库运行在docker容器docker_registry_srv)。

    我们在日常使用中一般也只删除manifest(就是TAG),删除blob实体(就是TAG对应的镜像实体:IMAGE ID)通过docker exec -ti docker_registry_srv registry garbage-collect /etc/docker/registry/config.yml方式实现,因为这样可以避免多个TAG关联同一个blob镜像实体时,删除blob实体,造成其他关联TAG不可用,!!!切记!!!

    # DELETE`/v2//blobs/`
    
    [root@v-192-168-11-81-deploy:~]# curl  -v -s -X DELETE  \
    >   -u ${DOCKER_REPO_USER}:${DOCKER_REPO_PASSWORD}  \
    >   -H 'Accept: application/vnd.docker.distribution.manifest.v2+json'  \
    >   https://${DOCKER_REPO}/v2/ufipf/gc-gateway/blobs/sha256:398435b7803045ffceced9cb02c1f4d4136fb3e257c005e866760d09cff7886c
    * About to connect() to docker-repo port 5000 (#0)
    *   Trying 192.168.11.79...
    * Connected to docker-repo (192.168.11.79) port 5000 (#0)
    * Initializing NSS with certpath: sql:/etc/pki/nssdb
    *   CAfile: /etc/pki/tls/certs/ca-bundle.crt
      CApath: none
    * SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    * Server certificate:
    * 	subject: E=admin@zjlh.lan,CN=zjlh.lan,OU=IT,O=ZJLH,ST=GuangDong,C=CN
    * 	start date: 3月 09 10:07:59 2022 GMT
    * 	expire date: 3月 09 10:07:59 2023 GMT
    * 	common name: zjlh.lan
    * 	issuer: E=admin@zzxia.vip,CN=ZZXIA-ROOT-CA,OU=GGBang,O=ZZXIA,L=GuangZhou,ST=GuangDong,C=CN
    * Server auth using Basic with user 'ufipf'
    > DELETE /v2/ufipf/gc-gateway/blobs/sha256:398435b7803045ffceced9cb02c1f4d4136fb3e257c005e866760d09cff7886c HTTP/1.1
    > Authorization: Basic dWZpcGY6MTIzNDU2
    > User-Agent: curl/7.29.0
    > Host: docker-repo:5000
    > Accept: application/vnd.docker.distribution.manifest.v2+json
    > 
    < HTTP/1.1 202 Accepted
    < Content-Length: 0
    < Docker-Distribution-Api-Version: registry/2.0
    < X-Content-Type-Options: nosniff
    < Date: Fri, 26 Aug 2022 08:08:18 GMT
    < Content-Type: text/plain; charset=utf-8
    < 
    * Connection #0 to host docker-repo left intact
    
    • 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

    7 验证删除

    # 再次查询仓库中镜像tag列表
     curl -u ${DOCKER_REPO_USER}:${DOCKER_REPO_PASSWORD} -s -X GET https://${DOCKER_REPO}/v2/ufipf/gc-agent-service/tags/list | jq .tags[]
    "latest"
    "2022.07.12.174242"
    "2022.07.07.094332"
    "2022.07.12.173118"
    "2022.07.25.104848"
    
    # 已从清单删除
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    8 最后

    这里有用bash shell实现的仓库管理,你可以看看【https://gitee.com/zhf_sy/zzxia-op-super-invincible-lollipop/tree/develop/op】下的docker-registry-manage.sh

    img

    爱你!

  • 相关阅读:
    计算机视觉与深度学习(线性分类器、全连接神经网络)
    大家一起来学习如何使用spring.factories
    网页使用之如何返回json/xml
    Linux:给openlab搭建web网站
    CF837G Functions On The Segments
    Python 解释器配置需要注意什么?
    解读LangChain
    21天学会C++:Day12----初始化列表
    使用javascript slice函数实现模拟分页
    案例!快看!电力行业利用IBPS低代码应用开发平台做好数据治理工作
  • 原文地址:https://blog.csdn.net/zhf_sy/article/details/126558517