ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Zot 高可用集群实战指南:三节点从零跑通

Zot 高可用集群实战指南:三节点从零跑通

Zot 高可用集群实战指南:三节点从零跑通

【免费下载链接】zotzot - A scale-out production-ready vendor-neutral OCI-native container image/artifact registry (purely based on OCI Distribution Specification)项目地址: https://gitcode.com/GitHub_Trending/zo/zot

单节点镜像仓库宕机,CI 流水线超时。Zot 集群模式解决的就是它:节点横向扩展、Redis 共享会话、HAProxy 统一入口,单点掉线服务不断。下面带你完成 Zot 高可用部署,三台机器从零搭起。

🧭 架构全景:请求是怎么流过去的

先别急着敲命令,花一分钟把链路在脑子里过一遍。一次docker pull的完整路径是:客户端打到 HAProxy 的 8080 端口,它按balance roundrobin把请求分给三台 Zot 节点之一;节点本身是无状态的——登录会话放在 Redis 里(这就是 Zot Redis 会话存储的意义),blob 数据放在共享存储上。所以"在 A 节点登录、从 B 节点拉镜像"照样能走通。

说白了,容器镜像仓库高可用的本质是:Zot 节点只是可随意增删的计算层,真正让它变成一个"集群"的,是后面两块共享底座——Redis 管状态,共享存储管数据。任何节点挂了,请求会被 HAProxy 转给活着的节点,客户端无感知,故障转移的全部秘密就在这。记住这条链路:客户端 → HAProxy → 任一 Zot 节点 → Redis/共享存储,后面所有步骤都围绕它展开。

📋 动手前,先过一遍这份清单

照着勾,全打上勾再动手,能省掉后面大部分返工:

  • 3 台服务器(4C8G 起步)——挂掉一台还剩两台,多数派冗余的基本盘
  • 每台 ≥50GB 可用磁盘——镜像层很占地方,别等推镜像才想起扩容
  • 节点间延迟 <10ms,互通 8081~8083 与 6379 端口——健康检查的超时阈值是毫秒级
  • Docker 20.10+(或 Podman 3.0+)——容器化部署,升级回滚最干净
  • HAProxy 2.0+——对 HTTP 长连接友好,check能自动摘除挂掉的节点
  • Redis 6.0+——会话与缓存的共享存储,多节点变"一个服务"的关键
  • 仓库代码拉到本地——examples/里的 haproxy.cfg 和配置样例可以直接复用
git clone https://gitcode.com/GitHub_Trending/zo/zot cd zot

🚀 从 0 跑通三节点:四步走

第一步:起 Redis,会话存储的公共底座

这步在干什么:给三个 Zot 节点准备同一个 Redis,Zot Redis 会话存储全靠它,后面登录态互通就依赖这里。

docker run -d --name zot-redis -p 6379:6379 \ redis:6 --requirepass "your-password"

常见报错:节点侧connection refused—— 先确认防火墙放行了 6379;另外配了--requirepass之后,节点配置里的 url 要写成redis://:your-password@host:6379,否则认证过不去。

第二步:起 3 个 Zot 节点,三节点最小配置怎么填

这步在干什么:三台节点跑同一份配置的"API 副本",差别只在端口和数据目录。

{ "storage": { "rootDirectory": "/tmp/zot" }, "http": { "port": "8080", "auth": { "sessionDriver": { // 会话存进 Redis,跨节点登录态互通 "name": "redis", "url": "redis://redis-host:6379", "keyprefix": "zotsession" } } } }

存成本地zot-config.json,三个节点一次性起完(单机演示可以全跑在一台机器上,端口用 8081~8083 区分;生产才真正分到三台):

for i in 1 2 3; do docker run -d --name zot-node$i -p 808$i:8080 \ -v $PWD/zot-config.json:/etc/zot/config.json \ -v $PWD/data/node$i:/tmp/zot \ ghcr.io/project-zot/zot-linux-amd64:latest done

常见报错:open /tmp/zotpasswd: no such file or directory—— 官方样例配置自带 htpasswd 认证,用htpasswd -bc生成文件挂进容器,或从自己的配置副本里去掉htpasswd块。

注意这里:上面是本地盘快速版,三个节点其实是三套独立仓库,能做负载分摊,但数据互不可见。要数据真正一致,把storageDriver指到共享存储(如 S3),仓库里就有现成样例 examples/config-s3.json。

第三步:挂 HAProxy,Zot HAProxy 配置核心就三行

这步在干什么:HAProxy 当统一入口,Zot 多节点搭建里它负责轮询分发和健康检查。

配置核心其实三行:backend 里balance roundrobin做轮询,然后每个节点一条server zotN 127.0.0.1:808N check——check是健康检查,节点挂掉会被自动摘出轮转,这是 Zot 故障转移能生效的前提。

docker run -d --name haproxy -p 8080:8080 \ -v ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg \ haproxy:2.4

常见报错:入口 503 —— 有后端被判定 DOWN,逐个docker logs zot-nodeN看,九成是端口号写错或配置文件没挂对。

第四步:端到端冒烟,一条 curl 验证整条链路

这步在干什么:从 HAProxy 入口连打 6 次,确认"入口 → 节点"链路全通,且轮询真的在动。

for i in 1 2 3 4 5 6; do curl -s http://127.0.0.1:8080/v2/_catalog done

6 次都返回{"repositories":[]}即通过。冒烟不是走个过场:_catalog是 v2 API 的最小请求,它能通,说明路由、会话初始化都没问题。注意别直接打 8081~8083 验收——那绕过了负载均衡,验不出集群行为。

常见报错:502 —— 一个后端都连不上,docker ps确认节点容器真的活着,端口映射是 8080 而不是别的。

✅ 上线前,打勾确认这 3 件事

这是验收清单,不是教程:三项全过,再对外提供服务。

# ① 故障转移:停一个节点,入口必须仍可用 docker stop zot-node2 && curl -s http://127.0.0.1:8080/v2/_catalog # ② 负载均匀:发 30 次请求,再核对各节点计数 for i in $(seq 30); do curl -s -o /dev/null http://127.0.0.1:8080/v2/; done # ③ 数据一致性(共享存储配置下):直连 node1 推镜像后,从入口查 curl -s http://127.0.0.1:8080/v2/_catalog
  • ① 预期:输出仍是{"repositories":...}而不是 502/503;验完记得docker start zot-node2拉回来。
  • ② 预期:HAProxy stats 或各节点访问日志里,三个 backend 计数各约 1/3;偏差大就查balance策略和会话粘滞设置。
  • ③ 预期:catalog 里出现刚推的镜像名(如my-app)。本地盘快速配置下这条不成立,属预期内,别当成 bug 排查。

🛠 跑起来之后:运维 Q&A

三个节点都亮起来只是开始,后面这张表覆盖 90% 的日常。接 Prometheus 时,给每个节点配置加上这段:

{ "extensions": { "metrics": { "enable": true, "prometheus": { "path": "/metrics" } } } }
问题处理方式关键命令
扩容一个新节点同一份配置部署 node4 → 本地 haproxy.cfg 副本加一行server zot4 127.0.0.1:8084 check→ 让 HAProxy 生效docker restart haproxy(生产建议走 stats socket 平滑 reload)
接 Prometheus 监控每个节点启用 metrics 扩展,scrape 各节点的/metrics端点curl -s 127.0.0.1:8081/metrics \| head
503 / 故障转移不生效先看 HAProxy 日志确认哪个 backend 被摘,再查该节点的端口、配置、磁盘docker logs haproxy,再docker logs zot-node2
换节点后登录态失效多半是 sessionDriver 没指到同一个 Redis,核对各节点url与keyprefix完全一致逐台检查自己那份配置副本里的keyprefix
节点存储异常查 rootDirectory 可写性与磁盘水位docker exec zot-node1 df -h /tmp/zot

延伸阅读

  • examples/cluster/haproxy.cfg:完整 HAProxy 参考配置——要调超时、健康检查参数时翻它,比凭记忆改省事。
  • examples/config-s3.json:共享存储配置样例——让多节点数据真正一致的那一步,照着改storageDriver即可。
  • test/blackbox/sync_replica_cluster.bats:副本集群同步的黑盒测试——想做跨机房容灾、用同步替代共享存储时,这是现成的验收脚本参考。

接下来把各节点的/metrics接进 Prometheus + Grafana,十分钟就能盯住整个集群的负载和错误率。

【免费下载链接】zotzot - A scale-out production-ready vendor-neutral OCI-native container image/artifact registry (purely based on OCI Distribution Specification)项目地址: https://gitcode.com/GitHub_Trending/zo/zot

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进