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 避坑指南:配置注意事项
adminPolicy层级:adminPolicy必须与repositories平级,放在repositories内部会导致zot verify报invalid keys: adminpolicy错误。keepTagsBug:若仅使用patterns会导致 Zot 崩溃,必须附带mostRecentlyPushedCount作为兜底。- 拉取卡顿(Sync 扩展):按需代理同步(
onDemand)会导致本地存在镜像时依然阻塞检查上游,建议直接设置"sync": {"enable": false},将其作为纯私有仓库使用。 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 |

浙公网安备 33010602011771号