Zot OCI Registry 部署与运维指南

Zot OCI Registry 部署与运维指南

本文档基于实际部署与排障经验整理,涵盖 Zot 的安装、权限配置、镜像推拉、存储清理以及从 Harbor 迁移的完整流程。


一、 部署架构与基础安装

1.1 架构说明

  • 后端:Zot 以纯 HTTP 运行在内网(如 5000 端口),负责镜像存储与核心逻辑。
  • 前端:生产环境建议通过 Nginx 或云负载均衡(CLB)实现 HTTPS 终止(TLS Termination),减轻 Zot 负担并解决浏览器剪贴板 API 限制。

1.2 安装 Zot

bash

# 下载 v2.1.22 二进制文件
wget -O /usr/bin/zot https://github.com/project-zot/zot/releases/download/v2.1.22/zot-linux-amd64
chmod +x /usr/bin/zot

1.3 配置 Systemd 服务

创建 /etc/systemd/system/zot.service:

[Unit]
Description=OCI Distribution Registry
Documentation=https://zotregistry.dev/
After=network.target auditd.service local-fs.target

[Service]
Type=notify
NotifyAccess=main
TimeoutStartSec=5min
ExecStart=/usr/bin/zot serve /etc/zot/config.json
Restart=on-failure
# 注意:若遇到 217/USER 报错,请确保此处的 User/Group 在系统中真实存在
User=zot
Group=zot
LimitNOFILE=500000
MemoryHigh=14G
MemoryMax=16G

[Install]
WantedBy=multi-user.target

二、 核心配置文件解析 (/etc/zot/config.json)

以下为经过优化的完整配置,涵盖了存储、认证、权限控制(按环境隔离)及扩展功能。

json

{
    "storage": {
        "rootDirectory": "/var/lib/registry",
        "commit": true,
        "dedupe": true,
        "gcInterval": "24h",
        "retention": {
            "policies": [
                {
                    "repositories": ["admin/**"],
                    "deleteUntagged": true,
                    "keepTags": [
                        {
                            "patterns": ".*",
                            "mostRecentlyPushedCount": 100
                        }
                    ]
                },
                {
                    "repositories": ["prod/**", "pre/**"],
                    "deleteUntagged": true,
                    "keepTags": [{"mostRecentlyPushedCount": 10}]
                },
                {
                    "repositories": ["dev/**", "test/**", "test02/**"],
                    "deleteUntagged": true,
                    "keepTags": [{"mostRecentlyPushedCount": 5}]
                },
                {
                    "repositories": ["**"],
                    "deleteUntagged": true,
                    "keepTags": [{"mostRecentlyPushedCount": 10}]
                }
            ]
        }
    },
    "http": {
        "address": "0.0.0.0",
        "port": "5000",
        "externalUrl": "https://registry.yourdomain.com",
        "compat": ["docker2s2"],
        "auth": {
            "htpasswd": {"path": "/etc/zot/htpasswd"}
        },
        "accessControl": {
            "adminPolicy": {
                "users": ["admin"],
                "actions": ["read", "create", "update", "delete"]
            },
            "repositories": {
                "prod/**": {
                    "policies": [
                        {"users": ["appuser"], "actions": ["read", "create", "update"]}
                    ]
                },
                "pre/**": {
                    "policies": [
                        {"users": ["appuser"], "actions": ["read", "create", "update"]}
                    ]
                },
                "test/**": {
                    "policies": [
                        {"users": ["appuser"], "actions": ["read", "create", "update"]}
                    ]
                },
                "dev/**": {
                    "policies": [
                        {"users": ["appuser"], "actions": ["read", "create", "update"]}
                    ]
                },
                "test02/**": {
                    "policies": [
                        {"users": ["appuser"], "actions": ["read", "create", "update"]}
                    ]
                }
            }
        }
    },
    "extensions": {
        "sync": {
            "enable": false
        },
        "search": {
            "enable": true,
            "cve": {"updateInterval": "2h"}
        },
        "ui": {"enable": true}
    },
    "log": {
        "level": "info",
        "output": "/var/log/zot/zot.log"
    }
}

2.1 避坑指南:配置注意事项

  1. adminPolicy 层级:adminPolicy 必须与 repositories 平级,放在 repositories 内部会导致 zot verify 报 invalid keys: adminpolicy 错误。
  2. keepTags Bug:若仅使用 patterns 会导致 Zot 崩溃,必须附带 mostRecentlyPushedCount 作为兜底。
  3. 拉取卡顿(Sync 扩展):按需代理同步(onDemand)会导致本地存在镜像时依然阻塞检查上游,建议直接设置 "sync": {"enable": false},将其作为纯私有仓库使用。
  4. externalUrl:配置 HTTPS 域名后,推拉镜像必须使用域名,如 docker push registry.yourdomain.com/...。

三、 用户与权限管理

3.1 生成认证文件

bash

# 生成管理员密码
htpasswd -bnB admin passwd > /etc/zot/htpasswd
# 生成应用账户密码
htpasswd -bnB appuser passwd >> /etc/zot/htpasswd

3.2 验证与启动

bash

# 校验配置文件语法和逻辑
zot verify /etc/zot/config.json

# 启动服务
systemctl daemon-reload
systemctl restart zot
systemctl status zot

3.3 权限矩阵

账户 权限范围 允许操作
admin 全局 (**) read, create, update, delete
appuser 仅限五个环境 read, create, update (无 delete)

四、 镜像推拉与保留策略

4.1 推送镜像

因为配置了 "compat": ["docker2s2"],可以直接使用 Docker 推送:

bash

docker tag clickhouse:26.9.8.3 192.168.1.200:5000/prod/clickhouse:26.9.8.3
docker push 192.168.1.200:5000/prod/clickhouse:26.9.8.3

4.2 自动清理策略 (Retention)

  • 管理员仓库 (appuseradmin/**):全部保留。
  • 生产/预发 (prod/**, pre/**):保留最近推送的 10 个 Tag。
  • 开发/测试 (dev/**, test/**, test02/**):保留最近推送的 5 个 Tag。
  • 其他兜底:保留最近推送的 10 个 Tag。
    注:多条件并列时(如保留10个且24小时内),采用“或”关系,范围取并集。

五、 迁移指南:从 Harbor 同步至 Zot

弃用 skopeo sync 的原因:在处理 --scoped 或路径拼接时极易发生 invalid reference format 错误。推荐使用脚本调用 Harbor API 配合 skopeo copy 批量同步。

5.1 修正依赖问题

Skopeo 默认会检查镜像信任策略,需要创建 /etc/containers/policy.json:

json

{
    "default": [
        {
            "type": "insecureAcceptAnything"
        }
    ]
}

5.2 批量同步脚本 (Shell)

创建 sync_harbor.sh,自动遍历 Harbor dev 项目并推送到 Zot 的 dev 命名空间:

bash

#!/bin/bash
HARBOR_URL="https://192.168.1.252:8443"
HARBOR_PROJ="dev"
HARBOR_USER="appuser"
HARBOR_PASS="passwd"
ZOT_URL="192.168.1.200:5000"
ZOT_USER="appuser"
ZOT_PASS="passwd"

PAGE=1
while true; do
    # 获取仓库列表 (需安装 jq)
    REPOS=$(curl -sk -u "$HARBOR_USER:$HARBOR_PASS" "$HARBOR_URL/api/v2.0/projects/$HARBOR_PROJ/repositories?page=$PAGE&page_size=100" | jq -r '.[].name')
    
    [ -z "$REPOS" ] && break

    for REPO_FULL in $REPOS; do
        # 去掉前缀,提取纯净仓库名
        REPO_NAME=$(echo "$REPO_FULL" | sed "s|^${HARBOR_PROJ}/||")
        
        echo ">>> Syncing: $REPO_NAME"
        
        skopeo --insecure-policy copy \
            --all \
            --src-creds="$HARBOR_USER:$HARBOR_PASS" \
            --dest-creds="$ZOT_USER:$ZOT_PASS" \
            --src-tls-verify=false \
            --dest-tls-verify=false \
            "docker://$HARBOR_URL/$HARBOR_PROJ/$REPO_NAME" \
            "docker://$ZOT_URL/$HARBOR_PROJ/$REPO_NAME"
    done
    ((PAGE++))
done

六、 常见问题排查 (Troubleshooting)

现象 根本原因 解决方案
start job failed ... status=1 配置了无效字段(如 adminPolicy 位置错) 使用 zot verify 检查,修正 JSON 层级
manifest invalid Docker 清单格式不支持 配置中添加 "compat": ["docker2s2"]
pull 时直接卡住 开启了 onDemand 同步代理,阻塞校验 关闭 extensions.sync
Web UI 复制按钮失效 浏览器 HTTP 安全上下文限制 配置 HTTPS 或手动从 F12 元素提取
Most popular 和 Recently 内容一样 镜像下载量/星标为 0,导致排序退化 正常现象,随使用频率增加会分离
用 curl -u 可以,UI 看不到 UI 未处于管理员登录状态 重新登录或在控制台检查 Session
posted @ 2026-10-20 14:11  蒲公英PGY  阅读(7)  评论(0)    收藏  举报