Help us learn about your current experience with the documentation. Take the survey.

容器注册表元数据库

  • 层级:免费、专业、旗舰
  • 产品:GitLab 自管版

元数据库为容器注册表提供了多项增强功能,可以提升性能并添加新功能。 GitLab 自管版注册表元数据库功能的工作进展跟踪在 epic 5521 中。

默认情况下,容器注册表使用对象存储来持久化与容器镜像相关的元数据。 这种存储元数据的方法限制了数据访问的效率,特别是当涉及跨多个镜像的数据时,例如在列出标签时。 通过使用数据库来存储这些数据,许多新功能成为可能,包括在线垃圾回收, 它可以自动删除旧数据且实现零停机时间。

该数据库与注册表已使用的对象存储协同工作,但不会取代对象存储。 即使在对元数据库执行元数据导入后,您仍必须继续维护对象存储解决方案。

对于 Helm Charts 安装,请参阅 Helm Charts 文档中的管理容器注册表元数据库

增强功能

元数据库架构支持性能改进、错误修复和新功能, 这些在对象存储元数据架构中是不可用的。这些增强功能包括:

由于对象存储元数据架构的技术限制,新功能仅针对元数据库版本实现。 非安全性的错误修复可能仅限于元数据库版本。

已知限制

  • 现有注册表的元数据导入需要一段只读时间。
  • Geo 功能有限。其他功能在 epic 15325 中提出。
  • 升级版本时,必须手动运行注册表的常规架构和部署后数据库迁移。
  • 在多节点 Linux 包环境中,无法保证注册表升级期间零停机时间

元数据库功能支持

您可以将现有注册表的元数据导入元数据库,并使用在线垃圾回收。

某些启用数据库的功能仅对 GitLab.com 启用,并且注册表数据库的自动数据库配置不可用。 请查看反馈问题中的功能支持表, 了解与容器注册表数据库相关的功能状态。

为 Linux 包安装启用元数据库

先决条件:

根据您的情况选择相应的说明:

  • 新安装或首次启用容器注册表。
  • 将现有容器镜像元数据导入元数据库:
    • 一步导入。仅推荐用于相对较小的注册表或无需避免停机的情况。
    • 三步导入。推荐用于较大的容器注册表。

开始之前

  • 所有数据库连接值都是占位符。在完成任何步骤之前,您必须创建、验证您能够连接到并为注册表管理新的 PostgreSQL 数据库。
  • 启用数据库后,您必须继续使用它。数据库现在是注册表元数据的来源,在此之后禁用它会导致注册表无法看到在数据库活动期间写入的所有镜像。
  • 在导入步骤完成后,切勿运行离线垃圾回收。该命令与使用元数据库的注册表不兼容,可能会删除与标记镜像关联的数据。
  • 确认您没有自动化离线垃圾回收。
  • 您可以先减少注册表的存储以加快进程。
  • 如果可能,请备份您的容器注册表数据

新安装

先决条件:

要启用数据库:

  1. 通过添加数据库连接详细信息编辑 /etc/gitlab/gitlab.rb,但首先将元数据库设置为禁用

    registry['database'] = {
      'enabled' => false,
      'host' => '<registry_database_host_placeholder_change_me>',
      'port' => 5432, # 默认值,但如果您的数据库实例端口不同,请设置为相应端口。
      'user' => '<registry_database_username_placeholder_change_me>',
      'password' => '<registry_database_placeholder_change_me>',
      'dbname' => '<registry_database_name_placeholder_change_me>',
      'sslmode' => 'require', # 有关更多信息,请参阅 PostgreSQL 文档 https://www.postgresql.org/docs/16/libpq-ssl.html。
      'sslcert' => '</path/to/cert.pem>',
      'sslkey' => '</path/to/private.key>',
      'sslrootcert' => '</path/to/ca.pem>'
    }
  2. 保存文件并重新配置 GitLab

  3. 应用数据库迁移

  4. 通过编辑 /etc/gitlab/gitlab.rb 并将 enabled 设置为 true 来启用数据库:

    registry['database'] = {
      'enabled' => true,
      'host' => '<registry_database_host_placeholder_change_me>',
      'port' => 5432, # 默认值,但如果您的数据库实例端口不同,请设置为相应端口。
      'user' => '<registry_database_username_placeholder_change_me>',
      'password' => '<registry_database_placeholder_change_me>',
      'dbname' => '<registry_database_name_placeholder_change_me>',
      'sslmode' => 'require', # 有关更多信息,请参阅 PostgreSQL 文档 https://www.postgresql.org/docs/16/libpq-ssl.html。
      'sslcert' => '</path/to/cert.pem>',
      'sslkey' => '</path/to/private.key>',
      'sslrootcert' => '</path/to/ca.pem>'
    }
  5. 保存文件并重新配置 GitLab

现有注册表

您可以通过一步或三步导入现有的容器注册表元数据。 有几个因素会影响导入的持续时间:

  • 您现有注册表数据的大小。
  • 您的 PostgreSQL 实例的规格。
  • 运行的注册表实例数量。
  • 注册表、PostgreSQL 和您配置的对象存储之间的网络延迟。

元数据导入仅针对标记的镜像。未标记和未引用的清单以及仅由它们引用的层将被保留并变得不可访问。 未标记的镜像从未通过 GitLab UI 或 API 可见,但它们可能成为"悬空"状态并保留在后端。 导入到新注册表后,所有镜像都受到持续的在线垃圾回收约束,默认情况下删除任何保留超过 24 小时的未标记和未引用的清单和层。

根据您的注册表安装选择一步或三步方法。

一步导入

先决条件:

在导入期间,注册表必须关闭或保持 read-only 模式。 仅当您不需要在导入期间写入注册表且注册表包含相对较少数据时才选择此方法。

  1. database 部分添加到您的 /etc/gitlab/gitlab.rb 文件中,但首先将元数据库设置为禁用

    registry['database'] = {
      'enabled' => false, # 必须为 false!
      'host' => '<registry_database_host_placeholder_change_me>',
      'port' => 5432, # 默认值,但如果您的数据库实例端口不同,请设置为相应端口。
      'user' => '<registry_database_username_placeholder_change_me>',
      'password' => '<registry_database_placeholder_change_me>',
      'dbname' => '<registry_database_name_placeholder_change_me>',
      'sslmode' => 'require', # 有关更多信息,请参阅 PostgreSQL 文档 https://www.postgresql.org/docs/16/libpq-ssl.html。
      'sslcert' => '</path/to/cert.pem>',
      'sslkey' => '</path/to/private.key>',
      'sslrootcert' => '</path/to/ca.pem>'
    }
  2. 确保注册表设置为 read-only 模式。

    编辑您的 /etc/gitlab/gitlab.rb 并将 maintenance 部分添加到 registry['storage'] 配置中。 例如,对于使用 gs://my-company-container-registry 存储桶的 gcs 支持注册表, 配置可能如下:

    ## 对象存储 - 容器注册表
    registry['storage'] = {
      'gcs' => {
        'bucket' => '<my-company-container-registry>',
        'chunksize' => 5242880
      },
      'maintenance' => {
        'readonly' => {
          'enabled' => true # 必须设置为 true。
        }
      }
    }
  3. 保存文件并重新配置 GitLab

  4. 如果您尚未执行,请应用数据库迁移

  5. 运行以下命令:

    sudo gitlab-ctl registry-database import
  6. 如果命令成功完成,注册表现在已完全导入。您现在可以启用数据库, 在配置中关闭只读模式,并启动注册表服务:

    registry['database'] = {
      'enabled' => true, # 现在必须启用!
      'host' => '<registry_database_host_placeholder_change_me>',
      'port' => 5432, # 默认值,但如果您的数据库实例端口不同,请设置为相应端口。
      'user' => '<registry_database_username_placeholder_change_me>',
      'password' => '<registry_database_placeholder_change_me>',
      'dbname' => '<registry_database_name_placeholder_change_me>',
      'sslmode' => 'require', # 有关更多信息,请参阅 PostgreSQL 文档 https://www.postgresql.org/docs/16/libpq-ssl.html。
      'sslcert' => '</path/to/cert.pem>',
      'sslkey' => '</path/to/private.key>',
      'sslrootcert' => '</path/to/ca.pem>'
    }
    
    ## 对象存储 - 容器注册表
    registry['storage'] = {
      'gcs' => {
        'bucket' => '<my-company-container-registry>',
        'chunksize' => 5242880
      },
      'maintenance' => {
        'readonly' => {
          'enabled' => false
        }
      }
    }
  7. 保存文件并重新配置 GitLab

您现在可以使用元数据库进行所有操作!

三步导入

先决条件:

按照本指南导入现有的容器注册表元数据。 此方法推荐用于较大的元数据集,或者如果您尝试在完成导入时最小化停机时间。

用户报告第一步导入以每小时 2 到 4 TB 的速度完成。 以较慢的速度,超过 100TB 数据的注册表可能需要超过 48 小时。

预导入仓库(第一步)

对于较大的实例,此命令可能需要数小时到数天才能完成,具体取决于您的注册表大小。 在第一步完成期间,您可以继续正常使用注册表。

目前还不可能 重新启动导入,因此重要的是让导入运行完成。 如果您必须停止操作,您必须重新启动此步骤。

  1. database 部分添加到您的 /etc/gitlab/gitlab.rb 文件中,但首先将元数据库设置为禁用

    registry['database'] = {
      'enabled' => false, # 必须为 false!
      'host' => '<registry_database_host_placeholder_change_me>',
      'port' => 5432, # 默认值,但如果您的数据库实例端口不同,请设置为相应端口。
      'user' => '<registry_database_username_placeholder_change_me>',
      'password' => '<registry_database_placeholder_change_me>',
      'dbname' => '<registry_database_name_placeholder_change_me>',
      'sslmode' => 'require', # 有关更多信息,请参阅 PostgreSQL 文档 https://www.postgresql.org/docs/16/libpq-ssl.html。
      'sslcert' => '</path/to/cert.pem>',
      'sslkey' => '</path/to/private.key>',
      'sslrootcert' => '</path/to/ca.pem>'
    }
  2. 保存文件并重新配置 GitLab

  3. 如果您尚未执行,请应用数据库迁移

  4. 运行第一步开始导入:

    sudo gitlab-ctl registry-database import --step-one

您应该尝试尽快安排以下步骤,以减少所需的停机时间。 理想情况下,在第一步完成后不到一周。在第一步和第二步之间写入注册表的任何新数据, 都会导致第二步花费更多时间。

导入所有仓库数据(第二步)

此步骤要求注册表关闭或设置为 read-only 模式。 在执行第二步时,请留出足够的停机时间。

  1. 确保注册表设置为 read-only 模式。

    编辑您的 /etc/gitlab/gitlab.rb 并将 maintenance 部分添加到 registry['storage'] 配置中。例如,对于使用 gs://my-company-container-registry 存储桶的 gcs 支持注册表,配置可能如下:

    ## 对象存储 - 容器注册表
    registry['storage'] = {
      'gcs' => {
        'bucket' => '<my-company-container-registry>',
        'chunksize' => 5242880
      },
      'maintenance' => {
        'readonly' => {
          'enabled' => true # 必须设置为 true。
        }
      }
    }
  2. 保存文件并重新配置 GitLab

  3. 运行导入的第二步:

    sudo gitlab-ctl registry-database import --step-two
  4. 如果命令成功完成,所有镜像现在已完全导入。您现在可以启用数据库, 在配置中关闭只读模式,并启动注册表服务:

    registry['database'] = {
      'enabled' => true, # 必须设置为 true!
      'host' => '<registry_database_host_placeholder_change_me>',
      'port' => 5432, # 默认值,但如果您的数据库实例端口不同,请设置为相应端口。
      'user' => '<registry_database_username_placeholder_change_me>',
      'password' => '<registry_database_placeholder_change_me>',
      'dbname' => '<registry_database_name_placeholder_change_me>',
      'sslmode' => 'require', # 有关更多信息,请参阅 PostgreSQL 文档 https://www.postgresql.org/docs/16/libpq-ssl.html。
      'sslcert' => '</path/to/cert.pem>',
      'sslkey' => '</path/to/private.key>',
      'sslrootcert' => '</path/to/ca.pem>'
    }
    
    ## 对象存储 - 容器注册表
    registry['storage'] = {
      'gcs' => {
        'bucket' => '<my-company-container-registry>',
        'chunksize' => 5242880
      },
      'maintenance' => { # 此部分可以删除。
        'readonly' => {
          'enabled' => false
        }
      }
    }
  5. 保存文件并重新配置 GitLab

您现在可以使用元数据库进行所有操作!

导入剩余数据(第三步)

即使注册表现在完全使用数据库来存储其元数据,它还不能访问任何可能未使用的层 blob, 从而阻止这些 blob 被在线垃圾回收器删除。

要完成该过程,运行迁移的最后一步:

sudo gitlab-ctl registry-database import --step-three

该命令成功完成后,注册表元数据现在已完全导入数据库。

导入后

导入后可能需要大约 48 小时才能看到您的注册表存储减少。 这是在线垃圾回收的正常和预期部分,因为此延迟确保在线垃圾回收不会干扰镜像推送。 查看监控在线垃圾回收部分,了解如何监控在线垃圾回收器的进度和健康状况。

数据库迁移

您必须在每次 GitLab 升级后手动执行数据库迁移。在升级后自动化数据库迁移的支持在 issue 8670 中提出。

容器注册表支持两种类型的迁移:

  • 常规架构迁移:必须在部署新应用程序代码之前运行的数据库结构更改,也称为部署前迁移。这些应该快速(不超过几分钟)以避免部署延迟。

  • 部署后迁移:可以在应用程序运行时运行的数据库结构更改。用于较长的操作,如在大型表上创建索引,避免启动延迟和延长的升级停机时间。

默认情况下,注册表同时应用常规架构和部署后迁移。 为了减少升级期间的停机时间,您可以跳过部署后迁移,并在应用程序启动后手动应用它们。

应用数据库迁移

要在应用程序启动之前应用常规架构和部署后迁移:

  1. 运行数据库迁移:

    sudo gitlab-ctl registry-database migrate up

要跳过部署后迁移:

  1. 仅运行常规架构迁移:

    sudo gitlab-ctl registry-database migrate up --skip-post-deployment

    作为 --skip-post-deployment 标志的替代方案,您还可以将 SKIP_POST_DEPLOYMENT_MIGRATIONS 环境变量设置为 true

    SKIP_POST_DEPLOYMENT_MIGRATIONS=true sudo gitlab-ctl registry-database migrate up
  2. 启动应用程序后,应用任何待处理的部署后迁移:

    sudo gitlab-ctl registry-database migrate up

migrate up 命令提供了一些额外的标志,可用于控制迁移的应用方式。 运行 sudo gitlab-ctl registry-database migrate up --help 了解详情。

在线垃圾回收监控

导入过程后的初始在线垃圾回收运行持续时间根据导入的镜像数量而异。 在此期间,您应该监控在线垃圾回收的效率和健康状况。

监控数据库性能

完成导入后,预计数据库会经历一段高负载期,因为垃圾回收队列正在清空。 这种高负载是由在线垃圾回收器处理排队任务的大量单独数据库调用引起的。

定期检查 PostgreSQL 和注册表日志中的任何错误或警告。在注册表日志中, 特别注意按 component=registry.gc.* 过滤的日志。

跟踪指标

使用 Prometheus 和 Grafana 等监控工具来可视化和跟踪垃圾回收指标, 重点关注前缀为 registry_gc_* 的指标。这些包括标记为删除的对象数量、 成功删除的对象数量、运行间隔和持续时间。 有关如何启用 Prometheus 的信息,请参见启用注册表调试服务器

队列监控

通过计算 gc_blob_review_queuegc_manifest_review_queue 表中的行数来检查队列的大小。 最初预计会有较大的队列,行数与导入的 blob 和清单的数量成正比。队列应该随时间减少, 表明垃圾回收正在成功审查作业。

SELECT COUNT(*) FROM gc_blob_review_queue;
SELECT COUNT(*) FROM gc_manifest_review_queue;

解释队列大小:

  • 缩小的队列:表示垃圾回收正在成功处理任务。

  • 接近零的 gc_manifest_review_queue:大多数标记为可能删除的镜像已被审查并分类为仍在使用或已删除。

  • 逾期任务:通过运行以下查询检查逾期的 GC 任务:

    SELECT COUNT(*) FROM gc_blob_review_queue WHERE review_after < NOW();
    SELECT COUNT(*) FROM gc_manifest_review_queue WHERE review_after < NOW();

    大量逾期任务表示存在问题。只要队列大小随时间减少且逾期任务数量接近零,较大的队列大小就不必担心。 大量逾期任务应促使紧急检查日志。

检查 GC 日志中指示 blob 仍在使用的消息,例如 msg=the blob is not dangling, 这意味着它们不会被删除。

调整 blob 间隔

如果您的 gc_blob_review_queue 大小较大,并且您想要增加垃圾回收 blob 或清单工作器运行之间的频率, 请将您的间隔配置从默认值(5s)更新为 1s

registry['gc'] = {
  'blobs' => {
    'interval' => '1s'
  },
  'manifests' => {
    'interval' => '1s'
  }
}

导入负载清除后,您应该长期微调这些设置,以避免对数据库和注册表实例造成不必要的 CPU 负载。 您可以逐渐增加间隔到一个平衡性能和资源使用的值。

验证数据一致性

为了确保导入后的数据一致性,使用 crane validate 工具。此工具检查容器注册表中的所有镜像层和清单是否可访问且正确链接。 通过运行 crane validate,您确认注册表中的镜像是完整和可访问的,确保导入成功。

审查清理策略

如果您的镜像大部分都已标记,垃圾回收不会显著减少存储空间,因为它只删除未标记的镜像。

实施清理策略以删除不需要的标签,这最终会导致镜像通过垃圾回收被删除并恢复存储空间。

使用元数据库进行备份

如果您已为容器注册表元数据配置了自己的数据库, 您必须手动管理备份。gitlab-backup 不会备份元数据库。

启用元数据库后,备份必须像以前一样捕获注册表使用的对象存储,同时还要捕获数据库。 对象存储和数据库的备份应该协调进行,以尽可能接近地捕获注册表的状态。 要恢复注册表,您必须同时应用这两个备份。

降级注册表

要在导入完成后将注册表降级到以前的版本, 您必须恢复到所需版本的备份才能降级。

使用 Geo 的数据库架构

将 GitLab Geo 与容器注册表一起使用时,您必须为每个站点的注册表配置单独的数据库和 对象存储堆栈。到容器注册表的 Geo 复制使用从注册表通知生成的事件, 而不是通过数据库复制。

先决条件

每个 Geo 站点需要一个单独的、站点特定的:

  1. 用于容器注册表数据库的 PostgreSQL 实例。
  2. 用于容器注册表的对象存储实例。
  3. 配置为使用这些站点特定资源的容器注册表。

此图说明了数据流和基本架构:

flowchart TB
    subgraph "主站点"
        P_Rails[GitLab Rails]
        P_Reg[容器注册表]
        P_RegDB[(注册表数据库)]
        P_Obj[(对象存储)]
        P_Reg --> P_RegDB
        P_RegDB --> P_Obj
    end

    subgraph "辅助站点"
        S_Rails[GitLab Rails]
        S_Reg[容器注册表]
        S_RegDB[(注册表数据库)]
        S_Obj[(对象存储)]
        S_Reg --> S_RegDB
        S_RegDB --> S_Obj
    end

    P_Reg -- "通知" --> P_Rails
    P_Rails -- "事件" --> S_Rails
    S_Rails --> S_Reg

    classDef primary fill:#d1f7c4
    classDef secondary fill:#b8d4ff

    class P_Rails,P_Reg,P_MainDB,P_RegDB,P_Obj primary
    class S_Rails,S_Reg,S_MainDB,S_RegDB,S_Obj secondary

在每个站点使用单独的数据库实例,因为:

  1. 主 GitLab 数据库作为只读复制到辅助站点。
  2. 无法为注册表数据库选择性地禁用此复制。
  3. 容器注册表需要对其数据库的写入访问权限。
  4. 同构设置确保 Geo 站点之间的最大对等性。

恢复为对象存储元数据

完成元数据导入后,您可以将注册表恢复为使用对象存储元数据。

当您恢复为对象存储元数据时,在导入完成和此恢复操作之间添加或删除的任何容器镜像、标签或仓库都不可用。

要恢复为对象存储元数据:

  1. 恢复迁移前拍摄的备份

  2. 将以下配置添加到您的 /etc/gitlab/gitlab.rb 文件中:

    registry['database'] = {
      'enabled' => false,
    }
  3. 保存文件并重新配置 GitLab

故障排除

错误:there are pending database migrations

如果注册表已更新并且有待处理的架构迁移, 注册表无法启动,并显示以下错误消息:

FATA[0000] configuring application: there are pending database migrations, use the 'registry database migrate' CLI command to check and apply them

要解决此问题,请按照应用数据库迁移的步骤操作。

错误:offline garbage collection is no longer possible

如果注册表使用元数据库并且您尝试运行 离线垃圾回收, 注册表失败并显示以下错误消息:

ERRO[0000] this filesystem is managed by the metadata database, and offline garbage collection is no longer possible, if you are not using the database anymore, remove the file at the lock_path in this log message lock_path=/docker/registry/lockfiles/database-in-use

您必须:

  • 停止使用离线垃圾回收。
  • 如果您不再使用元数据库,请删除错误消息中显示的 lock_path 处的指示锁定文件。 例如,删除 /docker/registry/lockfiles/database-in-use 文件。

错误:cannot execute <STATEMENT> in a read-only transaction

注册表可能无法应用数据库迁移 并显示以下错误消息:

err="ERROR: cannot execute CREATE TABLE in a read-only transaction (SQLSTATE 25006)"

此外,如果您尝试运行 在线垃圾回收, 注册表可能失败并显示以下错误消息:

error="processing task: fetching next GC blob task: scanning GC blob task: ERROR: cannot execute SELECT FOR UPDATE in a read-only transaction (SQLSTATE 25006)"

您必须通过检查 PostgreSQL 控制台中的 default_transaction_read_onlytransaction_read_only 的值来验证只读事务是否被禁用。 例如:

# SHOW default_transaction_read_only;
 default_transaction_read_only
 -------------------------------
 on
(1 row)

# SHOW transaction_read_only;
 transaction_read_only
 -----------------------
 on
(1 row)

如果这些值中的任何一个设置为 on,您必须禁用它:

  1. 编辑您的 postgresql.conf 并设置以下值:

    default_transaction_read_only=off
  2. 重启您的 Postgres 服务器以应用这些设置。

  3. 如果适用,请尝试再次应用数据库迁移

  4. 重启注册表 sudo gitlab-ctl restart registry

错误:cannot import all repositories while the tags table has entries

如果您尝试导入现有注册表元数据并遇到以下错误:

ERRO[0000] cannot import all repositories while the tags table has entries, you must truncate the table manually before retrying,
see https://docs.gitlab.com/ee/administration/packages/container_registry_metadata_database.html#troubleshooting
common_blobs=true dry_run=false error="tags table is not empty"

当注册表数据库的 tags 表中存在现有条目时会发生此错误, 这可能发生在您:

  • 尝试一步导入并遇到错误。
  • 尝试三步导入过程并遇到错误。
  • 故意停止导入过程。
  • 在任何上述操作后尝试再次运行导入。
  • 针对错误的配置文件运行导入。

要解决此问题,您必须删除 tags 表中的现有条目。 您必须在您的 PostgreSQL 实例上手动截断该表:

  1. 编辑 /etc/gitlab/gitlab.rb 并确保元数据库禁用

    registry['database'] = {
      'enabled' => false,
      'host' => '<registry_database_host_placeholder_change_me>',
      'port' => 5432, # 默认值,但如果您的数据库实例端口不同,请设置为相应端口。
      'user' => '<registry_database_username_placeholder_change_me>',
      'password' => '<registry_database_placeholder_change_me>',
      'dbname' => '<registry_database_name_placeholder_change_me>',
      'sslmode' => 'require', # 有关更多信息,请参阅 PostgreSQL 文档 https://www.postgresql.org/docs/16/libpq-ssl.html。
      'sslcert' => '</path/to/cert.pem>',
      'sslkey' => '</path/to/private.key>',
      'sslrootcert' => '</path/to/ca.pem>'
    }
  2. 使用 PostgreSQL 客户端连接到您的注册表数据库。

  3. 截断 tags 表以删除所有现有条目:

    TRUNCATE TABLE tags RESTART IDENTITY CASCADE;
  4. 截断 tags 表后,尝试再次运行导入过程。

错误:database-in-use lockfile exists

如果您尝试导入现有注册表元数据并遇到以下错误:

|  [0s] step two: import tags failed to import metadata: importing all repositories: 1 error occurred:
    * could not restore lockfiles: database-in-use lockfile exists

此错误意味着您之前已导入注册表并完成了导入所有 仓库数据(第二步),并且 database-in-use 存在于注册表文件系统中。 如果您遇到此问题,不应再次运行导入程序。

如果您必须继续,您必须从文件系统中手动删除 database-in-use 锁定文件。 该文件位于 /path/to/rootdirectory/docker/registry/lockfiles/database-in-use

错误:pre importing all repositories: AccessDenied:

导入现有注册表 并使用 AWS S3 作为存储后端时,您可能会收到 AccessDenied 错误:

/opt/gitlab/embedded/bin/registry database import --step-one /var/opt/gitlab/registry/config.yml
  [0s] step one: import manifests
  [0s] step one: import manifests failed to import metadata: pre importing all repositories: AccessDenied: Access Denied

确保执行命令的用户具有 正确的权限范围

由于元数据管理问题导致注册表无法启动

注册表可能因以下错误而无法启动:

错误:registry filesystem metadata in use, please import data before enabling the database

当您的配置中启用了数据库 registry['database'] = { 'enabled' => true} 但您尚未将现有注册表元数据导入元数据库时,会发生此错误。

错误:registry metadata database in use, please enable the database

当您已完成将现有注册表元数据导入元数据库, 但您尚未在配置中启用数据库时,会发生此错误。

检查或创建锁定文件时出现问题

如果您遇到以下任何错误:

  • could not check if filesystem metadata is locked
  • could not check if database metadata is locked
  • failed to mark filesystem for database only usage
  • failed to mark filesystem only usage

注册表无法访问配置的 rootdirectory。如果您之前有正常工作的注册表,则不太可能发生此错误。 查看错误日志以查找任何配置错误问题。

删除标签后存储使用量未减少

默认情况下,在线垃圾回收器仅在所有关联标签被删除后 48 小时才开始删除未引用的层。 此延迟确保垃圾回收器不会干扰长时间运行或中断的镜像推送,因为层在关联到镜像和标签之前就被推送到注册表。

错误:permission denied for schema public (SQLSTATE 42501)

在注册表迁移期间,您可能会收到以下错误之一:

  • ERROR: permission denied for schema public (SQLSTATE 42501)
  • ERROR: relation "public.blobs" does not exist (SQLSTATE 42P01)

这些类型的错误是由于 PostgreSQL 15+ 中的更改,出于安全原因,该更改删除了 public 架构上的默认 CREATE 权限。 默认情况下,在 PostgreSQL 15+ 中,只有数据库所有者可以在 public 架构中创建对象。

要解决此错误,运行以下命令为注册表用户提供注册表数据库的所有者权限:

ALTER DATABASE <registry_database_name> OWNER TO <registry_user>;

这为注册表用户提供了成功创建表和运行迁移所需的权限。