docker部署私有化镜像仓库

news2024/11/17 9:49:17

     为什么要部署私有化:

        1.防止镜像因为内存不够被驱逐

        2.方便内网服务器复用

部署步骤:

  1.         
    docker pull registry
    // 如果嫌麻烦,也可以去我的资源里面去拿现成的,docker load -i registry.tar 到自己的docker里。
    
    """
        如果速度很慢,就修改/etc/docker/daemon.json中的参数,仓库镜像改成阿里云
      "registry-mirrors": [
        "https://3laho3y3.mirror.aliyuncs.com"
      ]
        修改完之后restart才能生效: systemctl restart docker 
    """
  2. 查看docker images 确保镜像已经拿到
  3. 启动容器

    docker run -p 5000:5000 -v /images:/var/lib/registry --restart=always -d --name registry registry:latest
  4. 验证仓库是否能正常通信
  5. 将本地需要上传到私有化hub的image打上tag并push到hub中
    1. python_base_v1.3:latest  是我本地的镜像
    2. docker tag python_base_v1.3:latest 0.0.0.0:5000/python_base_v1.3:latest;docker push 0.0.0.0:5000/python_base_v1.3:latest你会发现这里可能会报错。解决方案来了:vim  /etc/docker/daemon.json
      
      {
          "exec-opts": [
              "native.cgroupdriver=cgroupfs"
           ],
          "bip": "172.12.0.1/24",
          "allow-nondistributable-artifacts": [],
          "registry-mirrors": [
              "https://3laho3y3.mirror.aliyuncs.com"
          ],
          "insecure-registries": ["0.0.0.0:5000"]
      }

      最后再重启一下docker systemctl restart docker

    3. 查看一下/images 也就是你指定的宿主机镜像存储文件夹,发现已经完成了
    4. 最后就可以删掉本地的镜像,pull一下私有化仓库的了
      docker python_base_v1.3:latest
      docker rmi 0.0.0.0:5000/python_base_v1.3:latest
      docker pull 0.0.0.0:5000/python_base_v1.3:latest

     

 TIP:

停掉并删掉私有化hub:

      docker container stop registry && docker container rm -v 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"
        #registry_data_dir = "/var/lib/docker/volumes/f0b0376abb44166e8c409c71d4b11acf2263a6a02d28204c407ee8f950ea006d/_data/docker/registry/v2"
        registry_data_dir = "/images/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()

 

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

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

相关文章

Django搭建图书管理系统02:创建并配置APP功能模块

📁 创建APP **Django中的APP(应用程序)是将功能模块组织在一起的单位,每个APP通常负责处理特定的功能。**开发者可以将不同功能的模块放在不同的app中, 方便代码的复用。app就是项目的基石,因此开发博客的第一步就是创…

[C++] C++11新特性介绍 分析(2): lambda表达式、function包装器、bind()接口

文章目录 [toc] C11**lambda 表达式**lambda 表达式lambda 表达式底层 包装器 functionfunction 包装普通可调用对象function 包装类内成员函数 bind()bind() 使用 及 功能1. 调整参数位置2. 绑定参数 C11 上一篇介绍C11常用的新特性只介绍了一部分. 本篇文章继续分析介绍. l…

Linux简介与安装

文章目录 前言一、Linux简介1.Linux是什么2.学完Linux后能做什么 二、Linux安装1.安装方式介绍2.安装Linux3.网卡设置4.安装SSH连接工具5. Linux目录结构 总结 前言 为了巩固所学的知识,作者尝试着开始发布一些学习笔记类的博客,方便日后回顾。当然&…

括号生成(力扣)递归 JAVA

目录 题目描述:纯递归解法:递归 回溯: 题目描述: 数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。 示例 1: 输入:n 3 输出&#xff1a…

《手把手教你》系列基础篇之1-python+ selenium自动化测试-环境搭建(详细)

1.环境搭建 基于python3和selenium3做自动化测试,俗话说:工欲善其事必先利其器;没有金刚钻就不揽那瓷器活,磨刀不误砍柴工,因此你必须会搭建基本的开发环境,掌握python基本的语法和一个IDE来进行开发&…

modelscope魔塔初探--TTS

官网 step1 可以选择指定模型&#xff0c;对于多情感的模型&#xff0c;还可以通过标签实现语气情感 from modelscope.outputs import OutputKeys from modelscope.pipelines import pipeline from modelscope.utils.constant import Taskstext <speak><emotion …

Springboot实现热部署

目录 1、问题阐述 2、实现方式 3、开始配置 3.1在pom.xml中添加依赖 3.2devtools配置 3.3修改IDEA配置 3.4测试一下 1、问题阐述 在实际项目开发过程中&#xff0c;每次修改代码就得将项目重启&#xff0c;重新部署&#xff0c;对于一些大型应用来说&#xff0c;重启时…

特征选择算法 | Matlab实现基于ReliefF特征选择算法的回归数据特征选择 ReliefF

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 特征选择算法 | Matlab实现基于ReliefF特征选择算法的回归数据特征选择 ReliefF 部分源码 %--------------------

五分钟就可以安装MySQL

目录 ⛈️一.什么是MySQL ⛈️二.为什么要使用MySQL ⛈️三.MySQL有什么优点 ⛈️四.官网&#xff1a; ⛈️五.下载 ⛈️六.安装 ⛈️七.查看 ⛈️八.修改密码 一.什么是MySQL MySQL是一种开源的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;它使用结…

【Python编程系列】1、Python安装

Python安装 1、下载安装包 官网地址:https://www.python.org/ 进入后,在Downloads菜单下选择python运行的系统环境: 以Windows系统为例,进入后,选择合适的版本下载: 2、安装Python软件包 双击可执行文件exe: 弹出安装窗口后: 我们一般选择"Install Now"的…

Linux 配置dns覆盖默认127.0.0.53

Linux dns默认127.0.0.53&#xff0c;在/etc/resolve.conf中存在 nameserver 127.0.0.53&#xff0c;手动修改无果&#xff0c;每次重启依旧127.0.0.53&#xff0c;因为这是系统生成的文件&#xff0c;resolvectl命令来查dns的配置。 要修改dns&#xff0c;先暂停dns服务&…

6 JSR303校验

6.1 加入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId> </dependency> 6.2 在实体类上加注解 在实体类上加入Validated注解。并且在属性上方加入Emall(messag…

Selenium自动化测试技巧

目录 前言&#xff1a; Selenium自动化 跨浏览器测试中的Selenium 利用正确的定位器 数据驱动的测试 不要依赖特定的驱动程序 选择器顺序 使用PageObjects设计模式 提倡wait避免sleep 关闭Firebug起始页 前言&#xff1a; Selenium是一个广泛使用的自动化测试框架&a…

Android11 Settings加载流程

一、系统设置首页(一级菜单)&#xff1a; 1、Settings 之所以要在此定义空的Activity&#xff0c;是为了外部应用能直接跳转到XX_SettingsActivity界面&#xff0c;因为如果只是fragment的话&#xff0c;外部是没法跳转到fragment界面的&#xff0c;跳转到XX_SettingsActivit…

【无公网IP】在外Windows远程连接MongoDB数据库

文章目录 前言1. 安装数据库2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射2.3 测试随机公网地址远程连接 3. 配置固定TCP端口地址3.1 保留一个固定的公网TCP端口地址3.2 配置固定公网TCP端口地址3.3 测试固定地址公网远程访问 转载自cpolar极点云文章&#xff1a;公网远程…

Camera API1 使用说明

Camera API2 使用说明 目录 一、开启相机 1.1创建项目 1.2注册权限 1.3配置相机特性要求 1.4 获取摄像头的个数 1.5 根据 ID 获取 CameraInfo facing 1.6 开启相机 1.7 关闭相机 二、预览 2.1认识 Parameters 2.2 设置预览尺寸 2.3添加预览 Surface 2.4 开启和关…

高级篇九、性能分析工具的使用

目录 2、查看系统性能参数3、统计SQL的查询成本&#xff1a;last_query_cost4、 定位执行慢的 SQL&#xff1a;慢查询日志4.1 开启慢查询日志参数4.2 查看慢查询数目4.3 案例演示 2、查看系统性能参数 在MySQL中&#xff0c;可以使用 SHOW STATUS 语句查询一些MySQL数据库服务…

【C++】STL——list介绍及使用

&#x1f680; 作者简介&#xff1a;一名在后端领域学习&#xff0c;并渴望能够学有所成的追梦人。 &#x1f681; 个人主页&#xff1a;不 良 &#x1f525; 系列专栏&#xff1a;&#x1f6f8;C &#x1f6f9;Linux &#x1f4d5; 学习格言&#xff1a;博观而约取&#xff0…

安装Anaconda

一、Anaconda简介 Anaconda&#xff0c;一个开源的Python发行版本&#xff0c;可用于管理Python及其相关包&#xff0c;包含了conda、Python等180多个科学包及其依赖项。当我们需要不同的Pytorch版本的时候&#xff0c;不需要卸载重新安装&#xff0c;可以通过Anaconda创建不同…

短视频抖音账号矩阵系统源码---功能架构示例1

一、短视频账号矩阵系统源码开发服务器集群化处理开发成本更低&#xff08;前提&#xff09; 什么是集群化处理视频内存内耗&#xff1f;集群化处理视频内存内耗是指通过建立集群系统&#xff0c;将视频处理任务分配给多个计算节点进行并行处理&#xff0c;以减少单个计算节点…