当前位置: 代码网 > 服务器>服务器>云虚拟主机 > docker使用registry搭建本地镜像仓库实例详解

docker使用registry搭建本地镜像仓库实例详解

2024年05月21日 云虚拟主机 我要评论
一.系统环境服务器版本docker软件版本cpu架构centos linux release 7.4.1708 (core)docker version 20.10.12x86_64二.前言在使用do

一.系统环境

服务器版本docker软件版本cpu架构
centos linux release 7.4.1708 (core)docker version 20.10.12x86_64

二.前言

在使用docker拉取镜像时,docker首先默认从docker hub官方下载镜像,很多时候我们的镜像都是使用dockerfile自定义私有镜像,不对外公开,而且为了安全起见,docker可能在内网环境下运行,所以我们有必要搭建一套docker本地私有镜像仓库,以供整个内网集群环境使用。

搭建镜像仓库主流的有两种方法,一种是使用docker官方提供的registry镜像搭建仓库,简单快捷,但是功能有限;

另一种是使用harbor搭建本地镜像仓库,harbor功能更强,使用范围更广,这里介绍使用registry搭建本地镜像仓库。

使用harbor搭建本地镜像仓库请查看

三.使用registry搭建私有镜像仓库

3.1 环境介绍

架构:k8smaster作为私有仓库,k8sworker1作为docker客户端

服务器操作系统版本cpu架构进程功能描述
k8smaster/192.168.110.137centos linux release 7.4.1708 (core)x86_64registryregistry镜像仓库
k8sworker1/192.168.110.138centos linux release 7.4.1708 (core)x86_64dockerdocker客户端

3.2 k8smaster节点配置镜像仓库

拉取registry镜像

[root@k8smaster ~]# docker pull hub.c.163.com/library/registry:latest
latest: pulling from library/registry
25728a036091: pull complete 
0da5d1919042: pull complete 
e27a85fd6357: pull complete 
d9253dc430fe: pull complete 
916886b856db: pull complete 
digest: sha256:fce8e7e1569d2f9193f75e9b42efb07a7557fc1e9d2c7154b23da591e324f3d1
status: downloaded newer image for hub.c.163.com/library/registry:latest
hub.c.163.com/library/registry:latest
#registry镜像已经拉取下来
[root@k8smaster ~]# docker images
repository                                                        tag        image id       created          size
hub.c.163.com/library/registry                                    latest     751f286bc25e   4 years ago      33.2mb

查看registry镜像的端口:expose 5000/tcp 数据卷:volume [/var/lib/registry]

[root@k8smaster ~]# docker history hub.c.163.com/library/registry:latest
image          created       created by                                      size      comment
751f286bc25e   4 years ago   /bin/sh -c #(nop)  cmd ["/etc/docker/registr…   0b        
<missing>      4 years ago   /bin/sh -c #(nop)  entrypoint ["/entrypoint.…   0b        
<missing>      4 years ago   /bin/sh -c #(nop) copy file:7b57f7ab1a8cf85c…   155b      
<missing>      4 years ago   /bin/sh -c #(nop)  expose 5000/tcp              0b        
<missing>      4 years ago   /bin/sh -c #(nop)  volume [/var/lib/registry]   0b        
<missing>      4 years ago   /bin/sh -c #(nop) copy file:6c4758d509045dc4…   295b      
<missing>      4 years ago   /bin/sh -c #(nop) copy file:b99d4fe47ad1addf…   22.8mb    
<missing>      4 years ago   /bin/sh -c set -ex     && apk add --no-cache…   5.61mb    
<missing>      4 years ago   /bin/sh -c #(nop)  cmd ["/bin/sh"]              0b        
<missing>      4 years ago   /bin/sh -c #(nop) add file:89e72bfc19e81624b…   4.81mb    

创建registry容器,registry镜像生成容器作为私有仓库

-p 5000:5000做端口映射,物理机端口5000:容器端口5000

-v /docker/var/lib/registry:/var/lib/registry数据卷挂载,

物理机目录/docker/var/lib/registry:容器目录/var/lib/registry

[root@k8smaster ~]# docker run -dit --restart=always --name=docker-registry -p 5000:5000 -v /docker/var/lib/registry:/var/lib/registry hub.c.163.com/library/registry:latest
3f8378272356bece1d690f16ad925bbd25a9ec12840d0612df2c45f84c27b3f5
[root@k8smaster ~]# docker ps 
container id   image                                                 command                  created         status         ports                                       names
3f8378272356   hub.c.163.com/library/registry:latest                 "/entrypoint.sh /etc…"   4 seconds ago   up 2 seconds   0.0.0.0:5000-&gt;5000/tcp, :::5000-&gt;5000/tcp   docker-registry

此时仓库下还没有任何文件

[root@k8smaster ~]# ls /docker/var/lib/registry

3.3 k8sworker1节点配置从私有仓库上传和拉取镜像

3.3.1 上传镜像到私有仓库

现在在k8sworker1配置docker客户端

查看现有的镜像,如果没有镜像,直接docker pull即可

[root@k8sworker1 ~]# docker images
repository                                                tag       image id       created         size
hub.c.163.com/library/wordpress                           latest    dccaeccfba36   4 years ago     406mb
hub.c.163.com/library/tomcat                              latest    72d2be374029   4 years ago     292mb
hub.c.163.com/library/mysql                               latest    9e64176cd8a2   4 years ago     407mb

docker tag对镜像进行重命名,命名格式为:私有仓库ip:端口/分类/镜像:镜像版本

[root@k8sworker1 ~]# docker tag hub.c.163.com/library/wordpress 192.168.110.137:5000/boke/wordpress:latest
[root@k8sworker1 ~]# docker tag hub.c.163.com/library/tomcat 192.168.110.137:5000/web/tomcat:v1
[root@k8sworker1 ~]# docker tag hub.c.163.com/library/mysql 192.168.110.137:5000/db/mysql:5.7

把我们命名好的镜像推送到k8smatser的仓库里,但是报错了,报错客户端的连接为https,但是服务器端返回的是http

[root@k8sworker1 ~]# docker push 192.168.110.137:5000/boke/wordpress:latest
the push refers to repository [192.168.110.137:5000/boke/wordpress]
get https://192.168.110.137:5000/v2/: http: server gave http response to https client

解决方式有两种:第一种修改/usr/lib/systemd/system/docker.service文件

[root@k8sworker1 ~]# systemctl status docker
● docker.service - docker application container engine
   loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   active: active (running) since 二 2022-01-04 10:53:14 cst; 7h ago
     docs: https://docs.docker.com
 main pid: 1039 (dockerd)
   memory: 1.2g
   cgroup: /system.slice/docker.service
           └─1039 /usr/bin/dockerd -h fd:// --containerd=/run/containerd/containerd.sock
#/usr/bin/dockerd有一个参数--insecure-registry用于指定不安全的仓库
[root@k8sworker1 ~]# /usr/bin/dockerd --help | grep insecure
      --insecure-registry list                  enable insecure registry communication
[root@k8sworker1 ~]# vim /usr/lib/systemd/system/docker.service
#修改内容如下:添加了私有仓库地址和端口  --insecure-registry 192.168.110.137:5000
[root@k8sworker1 ~]# cat /usr/lib/systemd/system/docker.service | grep insecure-registry
execstart=/usr/bin/dockerd --insecure-registry 192.168.110.137:5000 -h fd:// --containerd=/run/containerd/containerd.sock
#重新加载配置文件并重启docker
[root@k8sworker1 ~]# systemctl daemon-reload ; systemctl restart docker
[root@k8sworker1 ~]# systemctl status docker
● docker.service - docker application container engine
   loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   active: active (running) since 二 2022-01-04 17:57:26 cst; 14s ago
     docs: https://docs.docker.com
 main pid: 62817 (dockerd)
   memory: 49.0m
   cgroup: /system.slice/docker.service
           └─62817 /usr/bin/dockerd --insecure-registry 192.168.110.137:5000 -h fd:// --containerd=/run/containerd/containerd.sock
#此时,推送wordpress镜像到私有仓库成功
[root@k8sworker1 ~]# docker push 192.168.110.137:5000/boke/wordpress:latest
the push refers to repository [192.168.110.137:5000/boke/wordpress]
53e16fa1f104: pushed 
562dd11ed871: pushed 
......
ddd6dcab19ff: pushed 
2c40c66f7667: pushed 
latest: digest: sha256:ca4cf4692b7bebd81f229942c996b1c4e6907d6733e977e93d671a54b8053a22 size: 4078

第二种方式是修改/etc/docker/daemon.json

#新增"insecure-registries":["192.168.110.137:5000"]
[root@k8sworker1 ~]# cat /etc/docker/daemon.json
{ 
"registry-mirrors": ["https://frz7i079.mirror.aliyuncs.com"],
"insecure-registries":["192.168.110.137:5000"]
}
[root@k8sworker1 ~]# systemctl restart docker
[root@k8sworker1 ~]# cat /etc/docker/daemon.json
{ 
"registry-mirrors": ["https://frz7i079.mirror.aliyuncs.com"],
"insecure-registries":["192.168.110.137:5000"]
}
#推送tomcat镜像到私有仓库成功
[root@k8sworker1 ~]# docker push 192.168.110.137:5000/web/tomcat:v1
the push refers to repository [192.168.110.137:5000/web/tomcat]
f79699072473: pushed 
......
fe40be59465f: pushed 
cf4ecb492384: pushed 
v1: digest: sha256:6241d7435b5c4e9d54be7d61e834836a71b1934b5403e01eff8768f0e2bcf210 size: 3045
[root@k8sworker1 ~]# docker push 192.168.110.137:5000/db/mysql:5.7
the push refers to repository [192.168.110.137:5000/db/mysql]
8129a85b4056: pushed 
......
295d6a056bfd: pushed 
5.7: digest: sha256:c0806ac73235043de2a6cb4738bb2f6a74f71d9c7aa0f19c8e7530fd6c299e75 size: 2617

查看私有仓库里的镜像

[root@k8sworker1 ~]# curl 192.168.110.137:5000/v2/_catalog
{"repositories":["boke/wordpress","db/mysql","web/tomcat"]}

查看某个镜像的版本

[root@k8sworker1 ~]# curl 192.168.110.137:5000/v2/boke/wordpress/tags/list
{"name":"boke/wordpress","tags":["latest"]}

安装jq

[root@k8sworker1 ~]# yum -y install jq
已加载插件:fastestmirror
base                                                                                                         ......
已安装:
  jq.x86_64 0:1.6-2.el7                                                                                                                                                                                          
作为依赖被安装:
  oniguruma.x86_64 0:6.8.2-1.el7                                                                                                                                                                                 
完毕!

使用脚本查看私有仓库里的镜像

[root@k8sworker1 ~]# cat list_images_from_registries.sh
#!/bin/bash 
file=$(mktemp) 
curl -s $1:5000/v2/_catalog | jq | egrep -v '\{|\}|\[|]' | awk -f\" '{print $2}' &gt; $file 
while read aa ; do 
tag=($(curl -s $1:5000/v2/$aa/tags/list | jq | egrep -v '\{|\}|\[|]|name' | awk -f\" '{print $2}')) 
        for i in ${tag[*]} ; do 
                echo $1:5000/${aa}:$i 
        done 
done &lt; $file 
rm -rf $file
[root@k8sworker1 ~]# bash list_images_from_registries.sh 192.168.110.137
192.168.110.137:5000/boke/wordpress:latest
192.168.110.137:5000/db/mysql:5.7
192.168.110.137:5000/web/tomcat:v1

先使用docker rmi 删除刚才修改的本地镜像

[root@k8sworker1 ~]# docker images
repository                                                tag       image id       created         size

3.3.2 从私有仓库里拉取镜像

从私有仓库里拉取镜像

[root@k8sworker1 ~]# docker pull 192.168.110.137:5000/boke/wordpress:latest
latest: pulling from boke/wordpress
21f90b3df721: pull complete 
13ce341a48bc: pull complete 
......
500c148f4d2b: pull complete 
digest: sha256:ca4cf4692b7bebd81f229942c996b1c4e6907d6733e977e93d671a54b8053a22
status: downloaded newer image for 192.168.110.137:5000/boke/wordpress:latest
192.168.110.137:5000/boke/wordpress:latest
[root@k8sworker1 ~]# docker pull 192.168.110.137:5000/web/tomcat:v1
v1: pulling from web/tomcat
a2149b3f2ac2: pull complete 
......
8dbb09972def: pull complete 
digest: sha256:6241d7435b5c4e9d54be7d61e834836a71b1934b5403e01eff8768f0e2bcf210
status: downloaded newer image for 192.168.110.137:5000/web/tomcat:v1
192.168.110.137:5000/web/tomcat:v1
[root@k8sworker1 ~]# docker images
repository                                                tag       image id       created         size
192.168.110.137:5000/boke/wordpress                       latest    dccaeccfba36   4 years ago     406mb
192.168.110.137:5000/web/tomcat                           v1        72d2be374029   4 years ago     292mb

从docker客户端上传镜像之后,仓库文件夹里已经存在镜像了

[root@k8smaster ~]# ls /docker/var/lib/registry
docker
[root@k8smaster ~]# ls /docker/var/lib/registry/docker/
registry
[root@k8smaster ~]# ls /docker/var/lib/registry/docker/registry/
v2
[root@k8smaster ~]# ls /docker/var/lib/registry/docker/registry/v2/
blobs  repositories
[root@k8smaster ~]# ls /docker/var/lib/registry/docker/registry/v2/repositories/
boke  db  web
[root@k8smaster ~]# ls /docker/var/lib/registry/docker/registry/v2/repositories/boke/
wordpress
[root@k8smaster ~]# ls /docker/var/lib/registry/docker/registry/v2/repositories/boke/wordpress/
_layers  _manifests  _uploads

使用脚本删除私有仓库里的镜像(脚本在附录里)

#给脚本授予可执行权限
[root@k8smaster ~]# chmod +x delete_docker_registry_image
#设置私有仓库的镜像文件夹
[root@k8smaster ~]# export registry_data_dir=/docker/var/lib/registry/docker/registry/v2/
#删除私有仓库的wordpress镜像
[root@k8smaster ~]# ./delete_docker_registry_image -i boke/wordpress:latest
info     [2022-01-04 19:56:08,375]  deleting /docker/var/lib/registry/docker/registry/v2/blobs/sha256/46/4676067592f277e1723e4ab4c588603df0b3dea762e22c354f7ada29b391cf10
.......
info     [2022-01-04 19:56:08,412]  deleting /docker/var/lib/registry/docker/registry/v2/repositories/boke/wordpress
#在docker客户端查看发现私有仓库里的wordpress镜像已经被删除了
[root@k8sworker1 ~]# bash list_images_from_registries.sh 192.168.110.137
192.168.110.137:5000/db/mysql:5.7
192.168.110.137:5000/web/tomcat:v1

四.附录:删除私有仓库镜像的python脚本

[root@k8smaster ~]# cat delete_docker_registry_image
#!/usr/bin/env python
"""
usage:
shut down your registry service to avoid race conditions and possible data loss
and then run the command with an image repo like this:
delete_docker_registry_image.py --image awesomeimage --dry-run
"""
import argparse
import json
import logging
import os
import sys
import shutil
import glob
logger = logging.getlogger(__name__)
def del_empty_dirs(s_dir, top_level):
    """recursively delete empty directories"""
    b_empty = true
    for s_target in os.listdir(s_dir):
        s_path = os.path.join(s_dir, s_target)
        if os.path.isdir(s_path):
            if not del_empty_dirs(s_path, false):
                b_empty = false
        else:
            b_empty = false
    if b_empty:
        logger.debug("deleting empty directory '%s'", s_dir)
        if not top_level:
            os.rmdir(s_dir)
    return b_empty
def get_layers_from_blob(path):
    """parse json blob and get set of layer digests"""
    try:
        with open(path, "r") as blob:
            data_raw = blob.read()
            data = json.loads(data_raw)
            if data["schemaversion"] == 1:
                result = set([entry["blobsum"].split(":")[1] for entry in data["fslayers"]])
            else:
                result = set([entry["digest"].split(":")[1] for entry in data["layers"]])
                if "config" in data:
                    result.add(data["config"]["digest"].split(":")[1])
            return result
    except exception as error:
        logger.critical("failed to read layers from blob:%s", error)
        return set()
def get_digest_from_blob(path):
    """parse file and get digest"""
    try:
        with open(path, "r") as blob:
            return blob.read().split(":")[1]
    except exception as error:
        logger.critical("failed to read digest from blob:%s", error)
        return ""
def get_links(path, _filter=none):
    """recursively walk `path` and parse every link inside"""
    result = []
    for root, _, files in os.walk(path):
        for each in files:
            if each == "link":
                filepath = os.path.join(root, each)
                if not _filter or _filter in filepath:
                    result.append(get_digest_from_blob(filepath))
    return result
class registrycleanererror(exception):
    pass
class registrycleaner(object):
    """clean registry"""
    def __init__(self, registry_data_dir, dry_run=false):
        self.registry_data_dir = registry_data_dir
        if not os.path.isdir(self.registry_data_dir):
            raise registrycleanererror("no repositories directory found inside " \
                                       "registry_data_dir '{0}'.".
                                       format(self.registry_data_dir))
        self.dry_run = dry_run
    def _delete_layer(self, repo, digest):
        """remove blob directory from filesystem"""
        path = os.path.join(self.registry_data_dir, "repositories", repo, "_layers/sha256", digest)
        self._delete_dir(path)
    def _delete_blob(self, digest):
        """remove blob directory from filesystem"""
        path = os.path.join(self.registry_data_dir, "blobs/sha256", digest[0:2], digest)
        self._delete_dir(path)
    def _blob_path_for_revision(self, digest):
        """where we can find the blob that contains the json describing this digest"""
        return os.path.join(self.registry_data_dir, "blobs/sha256",
                            digest[0:2], digest, "data")
    def _blob_path_for_revision_is_missing(self, digest):
        """for each revision, there should be a blob describing it"""
        return not os.path.isfile(self._blob_path_for_revision(digest))
    def _get_layers_from_blob(self, digest):
        """get layers from blob by digest"""
        return get_layers_from_blob(self._blob_path_for_revision(digest))
    def _delete_dir(self, path):
        """remove directory from filesystem"""
        if self.dry_run:
            logger.info("dry_run: would have deleted %s", path)
        else:
            logger.info("deleting %s", path)
            try:
                shutil.rmtree(path)
            except exception as error:
                logger.critical("failed to delete directory:%s", error)
    def _delete_from_tag_index_for_revision(self, repo, digest):
        """delete revision from tag indexes"""
        paths = glob.glob(
            os.path.join(self.registry_data_dir, "repositories", repo,
                         "_manifests/tags/*/index/sha256", digest)
        )
        for path in paths:
            self._delete_dir(path)
    def _delete_revisions(self, repo, revisions, blobs_to_keep=none):
        """delete revisions from list of directories"""
        if blobs_to_keep is none:
            blobs_to_keep = []
        for revision_dir in revisions:
            digests = get_links(revision_dir)
            for digest in digests:
                self._delete_from_tag_index_for_revision(repo, digest)
                if digest not in blobs_to_keep:
                    self._delete_blob(digest)
            self._delete_dir(revision_dir)
    def _get_tags(self, repo):
        """get all tags for given repository"""
        path = os.path.join(self.registry_data_dir, "repositories", repo, "_manifests/tags")
        if not os.path.isdir(path):
            logger.critical("no repository '%s' found in repositories directory %s",
                             repo, self.registry_data_dir)
            return none
        result = []
        for each in os.listdir(path):
            filepath = os.path.join(path, each)
            if os.path.isdir(filepath):
                result.append(each)
        return result
    def _get_repositories(self):
        """get all repository repos"""
        result = []
        root = os.path.join(self.registry_data_dir, "repositories")
        for each in os.listdir(root):
            filepath = os.path.join(root, each)
            if os.path.isdir(filepath):
                inside = os.listdir(filepath)
                if "_layers" in inside:
                    result.append(each)
                else:
                    for inner in inside:
                        result.append(os.path.join(each, inner))
        return result
    def _get_all_links(self, except_repo=""):
        """get links for every repository"""
        result = []
        repositories = self._get_repositories()
        for repo in [r for r in repositories if r != except_repo]:
            path = os.path.join(self.registry_data_dir, "repositories", repo)
            for link in get_links(path):
                result.append(link)
        return result
    def prune(self):
        """delete all empty directories in registry_data_dir"""
        del_empty_dirs(self.registry_data_dir, true)
    def _layer_in_same_repo(self, repo, tag, layer):
        """check if layer is found in other tags of same repository"""
        for other_tag in [t for t in self._get_tags(repo) if t != tag]:
            path = os.path.join(self.registry_data_dir, "repositories", repo,
                                "_manifests/tags", other_tag, "current/link")
            manifest = get_digest_from_blob(path)
            try:
                layers = self._get_layers_from_blob(manifest)
                if layer in layers:
                    return true
            except ioerror:
                if self._blob_path_for_revision_is_missing(manifest):
                    logger.warn("blob for digest %s does not exist. deleting tag manifest: %s", manifest, other_tag)
                    tag_dir = os.path.join(self.registry_data_dir, "repositories", repo,
                                           "_manifests/tags", other_tag)
                    self._delete_dir(tag_dir)
                else:
                    raise
        return false
    def _manifest_in_same_repo(self, repo, tag, manifest):
        """check if manifest is found in other tags of same repository"""
        for other_tag in [t for t in self._get_tags(repo) if t != tag]:
            path = os.path.join(self.registry_data_dir, "repositories", repo,
                                "_manifests/tags", other_tag, "current/link")
            other_manifest = get_digest_from_blob(path)
            if other_manifest == manifest:
                return true
        return false
    def delete_entire_repository(self, repo):
        """delete all blobs for given repository repo"""
        logger.debug("deleting entire repository '%s'", repo)
        repo_dir = os.path.join(self.registry_data_dir, "repositories", repo)
        if not os.path.isdir(repo_dir):
            raise registrycleanererror("no repository '{0}' found in repositories "
                                       "directory {1}/repositories".
                                       format(repo, self.registry_data_dir))
        links = set(get_links(repo_dir))
        all_links_but_current = set(self._get_all_links(except_repo=repo))
        for layer in links:
            if layer in all_links_but_current:
                logger.debug("blob found in another repository. not deleting: %s", layer)
            else:
                self._delete_blob(layer)
        self._delete_dir(repo_dir)
    def delete_repository_tag(self, repo, tag):
        """delete all blobs only for given tag of repository"""
        logger.debug("deleting repository '%s' with tag '%s'", repo, tag)
        tag_dir = os.path.join(self.registry_data_dir, "repositories", repo, "_manifests/tags", tag)
        if not os.path.isdir(tag_dir):
            raise registrycleanererror("no repository '{0}' tag '{1}' found in repositories "
                                       "directory {2}/repositories".
                                       format(repo, tag, self.registry_data_dir))
        manifests_for_tag = set(get_links(tag_dir))
        revisions_to_delete = []
        blobs_to_keep = []
        layers = []
        all_links_not_in_current_repo = set(self._get_all_links(except_repo=repo))
        for manifest in manifests_for_tag:
            logger.debug("looking up filesystem layers for manifest digest %s", manifest)
            if self._manifest_in_same_repo(repo, tag, manifest):
                logger.debug("not deleting since we found another tag using manifest: %s", manifest)
                continue
            else:
                revisions_to_delete.append(
                    os.path.join(self.registry_data_dir, "repositories", repo,
                                 "_manifests/revisions/sha256", manifest)
                )
                if manifest in all_links_not_in_current_repo:
                    logger.debug("not deleting the blob data since we found another repo using manifest: %s", manifest)
                    blobs_to_keep.append(manifest)
                layers.extend(self._get_layers_from_blob(manifest))
        layers_uniq = set(layers)
        for layer in layers_uniq:
            if self._layer_in_same_repo(repo, tag, layer):
                logger.debug("not deleting since we found another tag using digest: %s", layer)
                continue
            self._delete_layer(repo, layer)
            if layer in all_links_not_in_current_repo:
                logger.debug("blob found in another repository. not deleting: %s", layer)
            else:
                self._delete_blob(layer)
        self._delete_revisions(repo, revisions_to_delete, blobs_to_keep)
        self._delete_dir(tag_dir)
    def delete_untagged(self, repo):
        """delete all untagged data from repo"""
        logger.debug("deleting utagged data from repository '%s'", repo)
        repositories_dir = os.path.join(self.registry_data_dir, "repositories")
        repo_dir = os.path.join(repositories_dir, repo)
        if not os.path.isdir(repo_dir):
            raise registrycleanererror("no repository '{0}' found in repositories "
                                       "directory {1}/repositories".
                                       format(repo, self.registry_data_dir))
        tagged_links = set(get_links(repositories_dir, _filter="current"))
        layers_to_protect = []
        for link in tagged_links:
            layers_to_protect.extend(self._get_layers_from_blob(link))
        unique_layers_to_protect = set(layers_to_protect)
        for layer in unique_layers_to_protect:
            logger.debug("layer_to_protect: %s", layer)
        tagged_revisions = set(get_links(repo_dir, _filter="current"))
        revisions_to_delete = []
        layers_to_delete = []
        dir_for_revisions = os.path.join(repo_dir, "_manifests/revisions/sha256")
        for rev in os.listdir(dir_for_revisions):
            if rev not in tagged_revisions:
                revisions_to_delete.append(os.path.join(dir_for_revisions, rev))
                for layer in self._get_layers_from_blob(rev):
                    if layer not in unique_layers_to_protect:
                        layers_to_delete.append(layer)
        unique_layers_to_delete = set(layers_to_delete)
        self._delete_revisions(repo, revisions_to_delete)
        for layer in unique_layers_to_delete:
            self._delete_blob(layer)
            self._delete_layer(repo, layer)
    def get_tag_count(self, repo):
        logger.debug("get tag count of repository '%s'", repo)
        repo_dir = os.path.join(self.registry_data_dir, "repositories", repo)
        tags_dir = os.path.join(repo_dir, "_manifests/tags")
        if os.path.isdir(tags_dir):
            tags = os.listdir(tags_dir)
            return len(tags)
        else:
            logger.info("tags directory does not exist: '%s'", tags_dir)
            return -1
def main():
    """cli entrypoint"""
    parser = argparse.argumentparser(description="cleanup docker registry")
    parser.add_argument("-i", "--image",
                        dest="image",
                        required=true,
                        help="docker image to cleanup")
    parser.add_argument("-v", "--verbose",
                        dest="verbose",
                        action="store_true",
                        help="verbose")
    parser.add_argument("-n", "--dry-run",
                        dest="dry_run",
                        action="store_true",
                        help="dry run")
    parser.add_argument("-f", "--force",
                        dest="force",
                        action="store_true",
                        help="force delete (deprecated)")
    parser.add_argument("-p", "--prune",
                        dest="prune",
                        action="store_true",
                        help="prune")
    parser.add_argument("-u", "--untagged",
                        dest="untagged",
                        action="store_true",
                        help="delete all untagged blobs for image")
    args = parser.parse_args()
    handler = logging.streamhandler()
    handler.setformatter(logging.formatter(u'%(levelname)-8s [%(asctime)s]  %(message)s'))
    logger.addhandler(handler)
    if args.verbose:
        logger.setlevel(logging.debug)
    else:
        logger.setlevel(logging.info)
    # make sure not to log before logging is setup. that'll hose your logging config.
    if args.force:
        logger.info(
            "you supplied the force switch, which is deprecated. it has no effect now, and the script defaults to doing what used to be only happen when force was true")
    splitted = args.image.split(":")
    if len(splitted) == 2:
        image = splitted[0]
        tag = splitted[1]
    else:
        image = args.image
        tag = none
    if 'registry_data_dir' in os.environ:
        registry_data_dir = os.environ['registry_data_dir']
    else:
        registry_data_dir = "/opt/registry_data/docker/registry/v2"
    try:
        cleaner = registrycleaner(registry_data_dir, dry_run=args.dry_run)
        if args.untagged:
            cleaner.delete_untagged(image)
        else:
            if tag:
                tag_count = cleaner.get_tag_count(image)
                if tag_count == 1:
                    cleaner.delete_entire_repository(image)
                else:
                    cleaner.delete_repository_tag(image, tag)
            else:
                cleaner.delete_entire_repository(image)
        if args.prune:
            cleaner.prune()
    except registrycleanererror as error:
        logger.fatal(error)
        sys.exit(1)
if __name__ == "__main__":
    main()

以上就是docker使用registry搭建本地镜像仓库实例详解的详细内容,更多关于docker registry搭建本地镜像仓库的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com