欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

docker使用registry搭建本地鏡像倉(cāng)庫(kù)實(shí)例詳解

 更新時(shí)間:2022年09月02日 15:56:21   作者:人生的哲理  
這篇文章主要介紹了docker使用registry搭建本地鏡像倉(cāng)庫(kù)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

一.系統(tǒng)環(huán)境

服務(wù)器版本docker軟件版本CPU架構(gòu)
CentOS Linux release 7.4.1708 (Core)Docker version 20.10.12x86_64

二.前言

在使用Docker拉取鏡像時(shí),Docker首先默認(rèn)從Docker Hub官方下載鏡像,很多時(shí)候我們的鏡像都是使用Dockerfile自定義私有鏡像,不對(duì)外公開(kāi),而且為了安全起見(jiàn),docker可能在內(nèi)網(wǎng)環(huán)境下運(yùn)行,所以我們有必要搭建一套docker本地私有鏡像倉(cāng)庫(kù),以供整個(gè)內(nèi)網(wǎng)集群環(huán)境使用。

搭建鏡像倉(cāng)庫(kù)主流的有兩種方法,一種是使用docker官方提供的registry鏡像搭建倉(cāng)庫(kù),簡(jiǎn)單快捷,但是功能有限;

另一種是使用harbor搭建本地鏡像倉(cāng)庫(kù),harbor功能更強(qiáng),使用范圍更廣,這里介紹使用registry搭建本地鏡像倉(cāng)庫(kù)。

使用harbor搭建本地鏡像倉(cāng)庫(kù)請(qǐng)查看http://www.dbjr.com.cn/article/244361.htm

三.使用registry搭建私有鏡像倉(cāng)庫(kù)

3.1 環(huán)境介紹

架構(gòu):k8smaster作為私有倉(cāng)庫(kù),k8sworker1作為docker客戶端

服務(wù)器操作系統(tǒng)版本CPU架構(gòu)進(jìn)程功能描述
k8smaster/192.168.110.137CentOS Linux release 7.4.1708 (Core)x86_64registryregistry鏡像倉(cāng)庫(kù)
k8sworker1/192.168.110.138CentOS Linux release 7.4.1708 (Core)x86_64dockerdocker客戶端

3.2 k8smaster節(jié)點(diǎn)配置鏡像倉(cāng)庫(kù)

拉取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鏡像已經(jīng)拉取下來(lái)
[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 數(shù)據(jù)卷: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    

創(chuàng)建registry容器,registry鏡像生成容器作為私有倉(cāng)庫(kù)

-p 5000:5000做端口映射,物理機(jī)端口5000:容器端口5000

-v /docker/var/lib/registry:/var/lib/registry數(shù)據(jù)卷掛載,

物理機(jī)目錄/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

此時(shí)倉(cāng)庫(kù)下還沒(méi)有任何文件

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

3.3 k8sworker1節(jié)點(diǎn)配置從私有倉(cāng)庫(kù)上傳和拉取鏡像

3.3.1 上傳鏡像到私有倉(cāng)庫(kù)

現(xiàn)在在k8sworker1配置docker客戶端

查看現(xiàn)有的鏡像,如果沒(méi)有鏡像,直接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對(duì)鏡像進(jìn)行重命名,命名格式為:私有倉(cāng)庫(kù)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的倉(cāng)庫(kù)里,但是報(bào)錯(cuò)了,報(bào)錯(cuò)客戶端的連接為HTTPS,但是服務(wù)器端返回的是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有一個(gè)參數(shù)--insecure-registry用于指定不安全的倉(cāng)庫(kù)
[root@k8sworker1 ~]# /usr/bin/dockerd --help | grep insecure
      --insecure-registry list                  Enable insecure registry communication
[root@k8sworker1 ~]# vim /usr/lib/systemd/system/docker.service
#修改內(nèi)容如下:添加了私有倉(cāng)庫(kù)地址和端口  --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
#此時(shí),推送wordpress鏡像到私有倉(cāng)庫(kù)成功
[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鏡像到私有倉(cāng)庫(kù)成功
[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

查看私有倉(cāng)庫(kù)里的鏡像

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

查看某個(gè)鏡像的版本

[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                                                                                                                                                                                 
完畢!

使用腳本查看私有倉(cāng)庫(kù)里的鏡像

[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 從私有倉(cāng)庫(kù)里拉取鏡像

從私有倉(cāng)庫(kù)里拉取鏡像

[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客戶端上傳鏡像之后,倉(cāng)庫(kù)文件夾里已經(jīng)存在鏡像了

[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

使用腳本刪除私有倉(cāng)庫(kù)里的鏡像(腳本在附錄里)

#給腳本授予可執(zhí)行權(quán)限
[root@k8smaster ~]# chmod +x delete_docker_registry_image
#設(shè)置私有倉(cāng)庫(kù)的鏡像文件夾
[root@k8smaster ~]# export REGISTRY_DATA_DIR=/docker/var/lib/registry/docker/registry/v2/
#刪除私有倉(cāng)庫(kù)的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客戶端查看發(fā)現(xiàn)私有倉(cāng)庫(kù)里的wordpress鏡像已經(jīng)被刪除了
[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

四.附錄:刪除私有倉(cāng)庫(kù)鏡像的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搭建本地鏡像倉(cāng)庫(kù)實(shí)例詳解的詳細(xì)內(nèi)容,更多關(guān)于docker registry搭建本地鏡像倉(cāng)庫(kù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 如何隔離docker容器中的用戶的方法

    如何隔離docker容器中的用戶的方法

    這篇文章主要介紹了如何隔離docker容器中的用戶的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • docker logs命令的使用及說(shuō)明

    docker logs命令的使用及說(shuō)明

    這篇文章主要介紹了docker logs命令的使用及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • ubuntu如何查看docker容器占用的磁盤(pán)空間

    ubuntu如何查看docker容器占用的磁盤(pán)空間

    這篇文章主要介紹了ubuntu如何查看docker容器占用的磁盤(pán)空間問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • Docker安裝Nginx教程實(shí)現(xiàn)圖例講解

    Docker安裝Nginx教程實(shí)現(xiàn)圖例講解

    這篇文章主要介紹了Docker安裝Nginx教程圖例講解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 阿里云系統(tǒng)安裝docker的操作記錄

    阿里云系統(tǒng)安裝docker的操作記錄

    這篇文章主要介紹了阿里云系統(tǒng)安裝docker,阿里云里面的Redis鏡像最新版也就到6.0,為了安裝最新的7.2的redis 只能用本地window 安裝DockerDesktop,然后安裝最新的redis 把鏡像導(dǎo)出來(lái),再導(dǎo)入到云服務(wù),需要的朋友可以參考下
    2024-07-07
  • Docker可視化面板Portainer的實(shí)現(xiàn)

    Docker可視化面板Portainer的實(shí)現(xiàn)

    Portainer是一個(gè)免費(fèi)的容器管理工具,支持Docker環(huán)境的可視化管理,通過(guò)Portainer,用戶可以輕松地在Windows或Linux容器中部署服務(wù),大大簡(jiǎn)化了Docker容器的管理工作,感興趣的可以了解一下
    2024-11-11
  • Google和Facebook不使用Docker的原理解析

    Google和Facebook不使用Docker的原理解析

    這篇文章主要介紹了Google和Facebook不使用Docker的原理解析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-05-05
  • Docker服務(wù)的重啟服務(wù)命令詳解(systemctl restart docker)

    Docker服務(wù)的重啟服務(wù)命令詳解(systemctl restart docker)

    這篇文章主要介紹了Docker服務(wù)的重啟服務(wù)命令(systemctl restart docker),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Docker安裝配置RabbitMQ的實(shí)現(xiàn)步驟

    Docker安裝配置RabbitMQ的實(shí)現(xiàn)步驟

    RabbitMQ是基于AMQP的一款消息管理系統(tǒng)。AMQP(Advanced?Message?Queuing?Protocol),是一個(gè)提供消息服務(wù)的應(yīng)用層標(biāo)準(zhǔn)高級(jí)消息隊(duì)列協(xié)議,其中RabbitMQ就是基于這種協(xié)議的一種實(shí)現(xiàn)
    2021-11-11
  • docker-compose部署zabbix+grafana的實(shí)現(xiàn)

    docker-compose部署zabbix+grafana的實(shí)現(xiàn)

    這篇文章主要介紹了docker-compose部署zabbix+grafana的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-11-11

最新評(píng)論