Docker私有仓库Harbor部署与管理实战指南

Docker私有仓库Harbor部署与管理实战指南 我搞Docker到现在差不多快七年了前几年团队内部一直用一台破服务器当镜像仓库装的是最原始的registry每次推镜像全靠命令行权限全靠猜日志全靠缘分。后来镜像数量一多项目一多实在是扛不住了才下定决心把Harbor安排上。如果你也在准备搭私有仓库、或者已经搭了registry但觉得难用这篇Docker系列第五篇咱们就把Harbor从部署到日常管理完整过一遍把配置文件、HTTPS证书、镜像推送、权限分配、垃圾回收这些核心环节全说透包含我踩过的坑和排查思路属于直接能抄作业的那种。Harbor是什么简单说就是一个企业级的Docker镜像私有仓库开源免费基于原生的Docker Registry做了大量企业级增强带Web管理界面、支持多租户项目隔离、细粒度权限控制、镜像复制同步、漏洞扫描、垃圾回收、审计日志可以说生产环境里需要的功能它基本都齐了。适合中小团队自建CI/CD链路、内网离线部署、以及不想把代码和镜像扔到公共平台上的任何场景。1. 为什么选Harbor私有仓库的核心需求与方案对比1.1 Docker Hub的局限与自建仓库的必然性说到镜像仓库很多人第一反应是Docker Hub毕竟它是Docker官方的默认仓库用起来确实方便——docker pull nginx、docker push 你自己的账号/镜像名一条命令搞定。但在实际工作中尤其是公司内部项目完全依赖Docker Hub会踩到几个绕不开的坑第一网络问题。国内拉取Docker Hub镜像的速度大家都懂虽然可以配置镜像加速器但那只解决拉取的问题推送还是走公网速度慢不说动不动就超时断流。如果公司是纯内网环境Docker Hub根本访问不了这时候一个内网私有仓库是硬需求。第二隐私与安全。公司内部的业务镜像里往往包含代码、配置、甚至数据库连接字符串这些东西推到公共仓库等于裸奔。虽然可以建私有仓库但Docker Hub的私有仓库有数量限制免费的只有一个仓库大了还得付费镜像存储和下载流量都是成本。第三权限管理。Docker Hub的权限模型太粗了基本就是“公开/私有”二选一。但实际开发场景中可能测试人员只需要拉取权限开发人员需要推送权限运维需要管理整个仓库这种细粒度的权限控制Docker Hub给不了。所以我一直的建议是只要你不是一个人单干只要你的镜像要往生产环境部署那就老老实实搭一个私有仓库。这不是“要不要”的问题是“早晚要”的问题。越早搭后面迁移成本越低。1.2 从registry到Harbor为什么不用裸的Docker Registry很多新手会问既然Docker Registry是官方的直接用官方的registry镜像搭一个不就行了确实docker run -d -p 5000:5000 registry一行命令就能跑起来一个最简仓库我之前也这么干过。但用一段时间你就会发现裸registry就是一个“啥都没有的储物间”没有Web界面想看仓库里有哪些镜像只能通过API或者命令行工具体验极其原始。没有权限控制任何人只要能访问到端口就能随便推送和拉取镜像这在团队里是不可接受的。没有镜像清理能力删除镜像非常麻烦删除后占用的存储空间也不会自动释放。没有多项目隔离所有镜像堆在一起命名稍微不规范就乱了。Harbor就是在registry外面包了一层完整的企业级外壳底层存储依然是Docker Registry但上层补齐了管理、安全、多租户这些能力。所以我的结论很明确如果是自己测试玩用一个临时registry无所谓如果是团队使用、生产使用直接上Harbor省得后来再迁移。1.3 Harbor的核心组件与整体架构Harbor不是一个大单体它是由多个容器组件协作构成的理解这些组件是排查问题的基础。我用Harbor 2.x版本举例主要组件有这么几个nginx最外层的反向代理负责接收所有外部请求包括HTTPS终结、路由转发到各个组件。这也是为什么Harbor对外暴露的端口通常是80或443但内部各个组件用的都是独立端口比如core是8080registry是5000。harbor-core核心业务服务负责处理认证、用户管理、项目管理、配置管理等API请求是Harbor真正的大脑。harbor-portalWeb前端页面也就是你在浏览器里看到的那些管理界面。registry底层的镜像存储服务就是官方Docker Registry负责实际存储和分发镜像层。registryctlregistry的管理辅助进程主要配合做垃圾回收、配额管理等操作。harbor-dbPostgreSQL数据库保存用户、项目、权限、审计日志等元数据。harbor-jobservice异步任务服务负责执行镜像复制、配额检查、垃圾回收等定时或后台任务。redis缓存和任务队列支撑jobservice和core的一些高频读写。trivy可选镜像漏洞扫描器安装时可以通过--with-trivy启用定期扫描镜像漏洞并生成报告。harbor.yml配置里涉及的data_volume目录存放的是所有组件产生的数据包括数据库文件、镜像存储、证书、日志等。所以备份Harbor时最核心的就是把data_volume目录和harbor.yml一起备份。这个我后面还会详细讲。2. 部署前的环境准备版本选择、依赖安装与安装包获取2.1 服务器配置与操作系统要求Harbor官方推荐的最低配置是2核CPU、4GB内存、40GB磁盘但我实际用下来的建议是如果期望跑得舒服一点尤其是要启用漏洞扫描功能至少4核8GB内存起步。为什么因为Trivy漏洞扫描会拉起多个扫描任务占用CPU和内存都比较大再加上Harbor本身要跑八九个容器内存不够的话光系统OOM就能把你搞崩。操作系统方面Ubuntu、CentOS、Debian、Rocky Linux这些主流发行版都没问题。我这边主力环境是Ubuntu 22.04和Rocky Linux 9两个系统部署流程基本一致差异主要在于防火墙和selinux的处理方式。CentOS系要注意selinux如果不关nginx反代到registry的时候很可能出现权限问题表现为功能时好时坏非常诡异。磁盘方面请务必把/data或者你指定的数据目录放到数据盘上千万别跟系统盘挤在一起。镜像数据增长非常快一个包含多个环境的基础镜像动辄几百MB项目多了之后几个GB甚至几十GB都是很正常的。我自己就在这上面栽过跟头——当初图省事全放在系统盘结果系统盘满了Docker daemon直接罢工连日志都写不进去修起来特别痛苦。2.2 Docker与Docker Compose的准备工作Harbor的安装本质上是跑一个install.sh脚本脚本会自动生成docker-compose.yml并拉起所有服务所以前置条件是两个Docker和Docker Compose插件。Docker的安装这里不过多展开Ubuntu用apt install docker.io或者用官方源安装都行CentOS/Rocky建议用yum install -y docker-ce docker-ce-cli containerd.io。装完之后记得设置开机自启systemctl enable docker --now这步忘了的话服务器一重启Docker服务没起来Harbor各种容器全挂排查起来还挺迷惑。Docker Compose需要注意版本问题。Harbor 2.x要求Docker Compose V2版本也就是docker compose这种带空格的子命令形式。如果你系统里只有老版本的docker-compose建议先升级。验证方法很简单docker compose version只要输出类似Docker Compose version v2.x.x就可以。另外确认一下Docker版本尽量用20.10以上版本太老的版本和Harbor新版本兼容性不敢保证。补充一下安装这些组件后最好重启一次Docker服务确保当前内核配置和权限都生效了。很多人装完Docker直接装Harbor如果之前Docker daemon配置过实验性功能或者改了cgroup驱动可能会出现意想不到的启动问题。2.3 Harbor安装包下载与版本选择Harbor的发行版分为在线安装包和离线安装包两种。在线安装包体积小只有几十MB但安装过程中会去Docker Hub拉取需要的镜像离线安装包则是一个几百MB的大文件里面打包了所有必需的镜像和组件适合内网环境。我的建议是除非你的服务器能稳定快速访问Docker Hub否则直接下载离线安装包。原因很简单在线安装装到一半因为网络问题拉镜像失败然后反复重试这种经历我不想再来第二次。离线包一次下载完后面不管是安装还是重新安装速度都快且不受网络影响。下载地址在Harbor官方GitHub Release页面文件名类似harbor-offline-installer-v2.11.x.tgz。版本选择上我建议优先选最新的稳定版本但别追最新的rc或beta版。Harbor迭代速度还行但大版本之间配置格式有变化比如1.x和2.x的harbor.yml格式就不完全兼容。如果是从旧版本升级一定要先看官方升级文档别直接拿新包覆盖老数据。下载完解压并校验tar -zxvf harbor-offline-installer-v2.11.1.tgz cd harbor解压后目录里最重要的就是harbor.yml.tmpl模板文件第一次安装需要把它复制成harbor.yml再改配置cp harbor.yml.tmpl harbor.yml顺便说一下我习惯把Harbor安装包和配置文件都放在服务器固定目录里比如/opt/harbor并且在配置里显式记录版本号方便后续升级回滚的时候能快速找到对应版本。3. Harbor部署实操harbor.yml配置、HTTPS证书与安装启动3.1 harbor.yml核心配置项逐行拆解harbor.yml是整个部署过程中最关键的配置文件它决定了Harbor的访问方式、数据存储位置、默认密码、数据库配置等。下面我按配置顺序讲几个必须关注的点。首先是hostname。这个配置项决定了Harbor对外暴露的主机名或IP它会写进注册信息里也用于生成UI的访问地址。我这里说一下我的习惯如果只在内网用直接填服务器IP就行如果有域名和DNS填域名更好因为后面要配HTTPS证书证书的CN和SAN必须和hostname一致用IP的话证书还得带IP SAN。比如hostname: hub.example.com其次是HTTP与HTTPS配置。Harbor默认配置里http端口是80https配置被注释掉了。但生产环境强烈建议开启HTTPS后面讲证书怎么生成。如果暂时用HTTP测试需要把http.port改成你想用的端口比如8080避免和服务器上已有的nginx冲突。我在实际项目中就碰到过服务器上跑了个业务nginx占用了80端口Harbor配置没改安装后直接端口冲突服务起不来。再然后是harbor_admin_password这是初始管理员密码。模板里默认是Harbor12345务必安装前改掉别用默认密码上线这是最基础的安全意识。还有data_volume默认值是/data改成你自己的数据盘路径比如/data/harbor。数据库部分生产环境如果不想用内置的harbor-db容器可以通过database字段配置外部PostgreSQL但我个人建议第一次部署先别折腾外部数据库用内置的就好等规模大了再考虑拆分。内置数据库的数据在data_volume里跟着整体备份走反而省心。3.2 用OpenSSL生成自签名HTTPS证书HTTPS证书这块是很多新手卡住的地方但又是必须搞定的。如果你没有公司正规CA签发的证书自己用OpenSSL生成一个自签名证书是标准做法。步骤其实不复杂核心三步生成CA私钥和证书、用CA给Harbor域名签发证书、把证书放到指定目录。先生成CA私钥和自签名根证书mkdir -p /data/cert cd /data/cert # 生成CA私钥 openssl genrsa -out ca.key 4096 # 生成CA根证书 openssl req -x509 -new -nodes -sha512 -days 3650 \ -subj /CCN/STBeijing/LBeijing/Oexample/OUexample \ -key ca.key -out ca.crt然后生成Harbor服务端私钥并创建证书签名请求openssl genrsa -out hub.example.com.key 4096 openssl req -sha512 -new \ -subj /CCN/STBeijing/LBeijing/Oexample/OUexample \ -key hub.example.com.key -out hub.example.com.csr注意下面这步很容易被忽略但非常重要新建一个扩展文件把证书支持的域名和IP写进去尤其是你用IP访问的话必须加IP SAN否则浏览器会报证书无效cat v3.ext -EOF authorityKeyIdentifierkeyid,issuer basicConstraintsCA:FALSE keyUsage digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment subjectAltName alt_names [alt_names] DNS.1hub.example.com IP.1192.168.1.100 EOF最后用CA签发生效证书openssl x509 -req -sha512 -days 3650 \ -extfile v3.ext \ -CA ca.crt -CAkey ca.key -CAcreateserial \ -in hub.example.com.csr -out hub.example.com.crt生成好后在harbor.yml里把这些证书路径填进去https: port: 443 certificate: /data/cert/hub.example.com.crt private_key: /data/cert/hub.example.com.key这里有个经验之谈把证书和私钥放在harbor.yml的data_volume目录之外比如单独一个/data/cert这样以后升级Harbor或者清理数据目录时不容易误删证书。证书有效期我一般设置10年省得年年换。另外所有需要登录Harbor的机器都要把ca.crt加到系统信任列表里不然docker login会报证书不受信任。CentOS/Rocky放/etc/pki/ca-trust/source/anchors/然后执行update-ca-trustUbuntu放/usr/local/share/ca-certificates/然后执行update-ca-certificates。3.3 执行install.sh安装与验证服务状态配置好harbor.yml后直接执行安装脚本sudo ./install.sh如果只是基础安装不需要日志扫描等附加组件这个命令就够了。如果需要启用组件在后面加参数比如sudo ./install.sh --with-trivy这里说明一下install.sh的常用参数参数作用我的建议--with-trivy启用镜像漏洞扫描镜像多、安全要求高就启用吃内存--with-chartmuseum启用Helm Chart仓库用Kubernetes和Helm就启用否则不要--with-notary启用镜像签名校验安全要求极高才用日常团队没必要--with-clair旧版漏洞扫描组件新版本已经用trivy替代了别再选安装脚本执行过程中会依次加载镜像、生成docker-compose.yml、启动所有容器最后输出一个访问地址。安装完成后第一件事是看容器状态docker compose ps正常情况下会有八九个容器处于Running状态包括nginx、harbor-core、harbor-registry、harbor-db、harbor-jobservice、harbor-portal、redis、registryctl等。如果某个容器反复重启马上看日志docker compose logs -f 容器名比如harbor-core起不来多半是数据库连接或者配置问题nginx起不来大概率是端口冲突。这些排查思路后面我专门开一节讲。最后浏览器访问https://hub.example.com用admin和刚才配置的管理员密码登录。看到管理界面后整个部署流程就结束了。4. Harbor日常管理镜像推送、项目权限与存储治理4.1 创建项目并完成第一次镜像推送登录Harbor Web界面后先新建一个项目。这里要理解Harbor的项目这个概念项目是镜像隔离的基本单位相当于Docker Hub上的命名空间。比如你有个业务叫order-service可以建一个order-service项目之后所有这个业务的镜像都推到这个项目下。创建项目时有几个选项要说明一下公开/私有公开项目可以让所有登录用户拉取镜像适合放基础镜像私有项目只有项目成员才能访问适合放业务镜像。存储配额可以给每个项目设置存储上限防止某个项目把磁盘写爆。我建议默认都配上比如10GB或者按团队规模来。代理缓存这是Harbor 2.x新增的功能可以把Docker Hub或其它远程仓库设为代理源相当于给团队加了一层公共镜像缓存挺实用的但初次部署可以先不管。项目建好后在需要推送镜像的客户端机器上做两件事。第一步配置Docker信任Harbor地址。如果是自签名证书要先把CA证书加到系统信任如果不想配HTTPS而是用HTTP测试则需要在/etc/docker/daemon.json里加insecure-registries{ insecure-registries: [hub.example.com] }然后重启Dockersudo systemctl restart docker第二步登录并推送镜像docker login hub.example.com -u admin docker tag nginx:latest hub.example.com/library/nginx:1.25 docker push hub.example.com/library/nginx:1.25推送成功后在Harbor Web界面的项目里就能看到这个镜像了。这里有个细节镜像名里的library就是项目名Harbor要求推送的镜像路径必须是仓库地址/项目名/镜像名:标签的格式少一层都不行这是新手最容易报错的地方。4.2 用户管理与细粒度权限模型Harbor最吸引人的一点就是它的权限模型。在“系统管理→用户管理”里可以创建本地用户然后在每个项目里通过“成员”功能把用户加进去并分配角色。角色分为三种项目管理员拥有项目的全部权限包括管理成员、配置项目属性、删除镜像。开发者可以推送和拉取镜像但不能管理项目和成员。访客只能拉取镜像不能推送。这个模型非常贴合研发团队的实际情况运维当项目管理员开发当开发者测试和部署流水线用访客账号去拉镜像。你会发现权限隔离能省掉很多安全纠纷——以前用公共仓库的时候谁都能推镜像被覆盖了都不知道是谁干的。除了本地用户Harbor还支持LDAP/AD认证、OIDC单点登录这个在企业里很有用。我司就接入了公司的LDAP员工直接用企业账号登录Harbor用户管理成本几乎为零。如果你是LDAP环境可以参考官方文档在“系统管理→认证设置”里配置主要是填LDAP的URL、Base DN、搜索过滤条件这几项。另外强烈推荐使用机器人账号。机器人账号是Harbor 2.x的一个亮点它不是给人用的是给CI/CD流水线、脚本、部署工具用的。你可以在项目里创建一个机器人账号只赋予它拉取或推送的权限然后用这个账号在Jenkins、GitLab CI里执行docker login。好处是权限最小化且可以随时吊销比直接拿admin账号写死在流水线里安全一万倍。我见过有人把admin密码直接写在Jenkins里后面密码一改整个流水线全挂场面极其混乱。4.3 仓库复制多机房与备份的利器如果你有多个机房或者多套环境比如测试环境一套Harbor、生产环境一套Harbor镜像需要在它们之间同步Harbor的“复制管理”功能就是干这个的。复制分为基于推送模式和基于拉取模式两种。基于推送模式就是在源仓库配置一个复制规则把指定项目的镜像定时或实时推送到目标仓库基于拉取模式则是在目标仓库主动从源仓库拉取镜像。创建复制规则需要配置目标仓库在“系统管理→仓库管理”里新增一个目标填写对端Harbor的地址和认证信息。然后在“系统管理→复制管理”里新建规则选择要复制的项目、镜像过滤条件、触发方式手动、定时、事件驱动。我常用的做法是“事件驱动”即源仓库一有新镜像推送就自动同步到目标仓库这样两个机房的镜像始终一致。复制功能还有个隐藏用途跨境迁移和灾备。把镜像从旧Harbor复制到新Harbor然后切换DNS整个过程镜像无缝迁移业务不受影响。我做过一次老仓库到新仓库的迁移几百个镜像全靠复制任务跑完比手动拉推强太多。4.4 垃圾回收与存储配额管理镜像仓库用久了磁盘占用会越来越大但你会发现Web界面里删除镜像后磁盘空间并没有释放。这是Registry的存储机制决定的镜像的blob层被多个镜像共享删除一个镜像只是删除了元数据引用实际存储的blob还在。要真正释放空间必须执行垃圾回收Garbage Collection。Harbor的垃圾回收在“系统管理→垃圾回收”里可以手动执行也可以设置定时任务。执行时选“立即回收”Harbor会让registry进入只读模式清理未被引用的blob并把正则化后的blob写回存储。注意垃圾回收期间镜像存储不可写所以最好安排在业务低峰期执行。我一般设置为每周日凌晨3点自动执行并且提前一天检查磁盘使用量。另外我强烈建议启用项目的存储配额。在项目属性里设置配额后推送镜像超过配额就会被拒绝这样能有效防止镜像无限膨胀把磁盘打爆。我遇到过最离谱的一次是同事把一个大语言模型镜像推了十几次每个版本好几个GB磁盘直接爆掉所有服务跟着遭殃。有了配额这种问题至少能提前堵住。5. 常见问题与排查技巧实录5.1 报错“harbor happened in config validation”怎么办这个报错在安装阶段非常经典出现频率极高。原因通常是harbor.yml配置校验不通过install.sh直接退出提示类似 “Failed to load config file: ... happened in config validation”。很多人一看到这个英文就懵了其实处理思路很简单第一步看报错原文。install.sh会输出具体的校验错误比如证书文件路径不存在、端口配置格式错误、必填字段为空。最常见的是证书路径写错了或者yml缩进有问题导致解析失败。yml文件对缩进极其敏感少一个空格就可能出错。第二步确认harbor.yml没有语法错误。可以借助工具检查python3 -c import yaml; yaml.safe_load(open(harbor.yml))如果有语法问题Python会直接告诉你第几行出错。如果没有报错那就是业务逻辑层面的校验问题按报错提示逐条改。第三步改完配置后重新执行install.sh。注意install.sh如果之前已经执行到一半失败了可能需要先清理掉部分生成的容器和compose文件再重新安装否则会跟旧状态冲突。我通常的做法是sudo docker compose down -v sudo ./install.sh这里-v会连容器卷一起删掉所以如果你已经有数据了千万别随便加-v会连镜像数据一起没。首次安装失败重来可以用生产环境慎用。5.2 镜像推送失败HTTPS、权限与命名空间问题推送镜像时报错五花八门我整理几个高频场景。第一种报错是http: server gave HTTP response to HTTPS client。看名字就知道服务端是HTTP但docker客户端强制走HTTPS。解决方法就是在/etc/docker/daemon.json里把Harbor地址加入insecure-registries然后重启Docker。如果你已经配了HTTPS证书但客户端不认属于证书信任问题把CA根证书导入客户端系统信任列表即可。第二种报错是unauthorized: unauthorized to access repository: xxx, action: push。这说明docker login成功了但当前用户对这个项目没有推送权限。去Harbor Web界面的项目成员里检查一下该用户的角色如果开发者角色都没有那肯定推不了。有时候是机器人账号只给了拉取权限却拿去推送也会报这个错。第三种报错是428 Unknown Manifest或者manifests invalid之类的通常是镜像标签格式不对。记住镜像推送路径的完整格式是仓库地址/项目名/镜像名:标签比如hub.example.com/library/nginx:1.25。如果你写成了hub.example.com/nginx:1.25缺少项目名这一层Harbor会直接拒绝。还有一个比较容易忽略的问题如果你配了HTTPS但harbor.yml里的hostname是IP而你用域名访问证书校验会失败。反过来如果你用IP访问但证书里没加IP SAN同样会失败。所以证书生成时一定要把实际要用的DNS和IP都加进SAN扩展里前面生成证书那节已经写清楚了。5.3 容器反复重启、磁盘爆满与访问异常先说说容器反复重启的问题。Harbor装好后docker compose ps发现某个容器状态不正常最常见的是harbor-core或harbor-db。这时第一时间看日志docker compose logs --tail200 harbor-coreharbor-core启动异常通常是连不上数据库检查harbor-db是否正常以及harbor.yml里的数据库账号密码是否和初始化的数据库一致。如果数据库密码配置错了core会一直重试连接。磁盘爆满是个隐蔽问题。Harbor运行一段时间后日志文件、镜像层、数据库膨胀都会吃掉大量空间。我建议在服务器上写个简单的磁盘监控设定阈值超过80%就告警。检查空间用df -h du -sh /data/harbor/*如果发现是日志占了很多注意Harbor容器日志默认由Docker管理会写到/var/lib/docker/containers下时间长了可能非常大。可以配置Docker的log rotation来限制单容器日志大小这个在/etc/docker/daemon.json里加log-driver和log-opts配置即可但要注意改完后重启Docker才会生效。访问异常还有一种情况是Harbor的nginx端口被防火墙挡住。Ubuntu的ufw和CentOS/Rocky的firewalld默认都可能拦截非标准端口如果浏览器访问不了但本机curl能通基本都是防火墙问题。放行端口后立刻就好sudo firewall-cmd --permanent --add-port443/tcp sudo firewall-cmd --reload5.4 各组件日志位置与状态速查为了帮助你快速排查问题我把Harbor部署和日常管理中最常检查的内容整理成了一张速查表平时遇到问题照着查就行检查项命令/位置说明容器运行状态docker compose ps在/opt/harbor目录执行看所有组件状态Harbor组件日志docker compose logs -f 服务名服务名如harbor-core、nginx、registryDocker日志占用du -sh /var/lib/docker/containers日志过大时配置log rotation数据目录占用du -sh /data/harbor/*找出占用大头针对性清理Harbor版本/opt/harbor/harbor.yml加docker images确认当前版本升级前要核对数据库备份/data/harbor/database停止Harbor后备份该目录最稳妥配置备份harbor.yml和/data/harbor/secret恢复环境必备没备份等于白装这个表是浓缩了我这几年维护Harbor的经验。说句实在话Harbor这套东西本身部署一次并不难真正考验人的是后面年复一年的日常维护和问题排查。把上面这些命令练熟比背多少文档都管用。另外再说一个我吃过亏的地方Harbor备份别只备份数据库目录一定要把/data/harbor/secret和harbor.yml也备份好。secret里保存着各种密钥和证书如果服务器挂了你拿之前的数据库文件恢复到新机器但secret丢了harbor-core会起不来因为数据库里的密钥对不上。我第一次做灾备演练时就踩了这个坑后来学乖了备份永远是“harbor.yml 整个data_volume 证书目录”三件套一起走。还有个小技巧给Harbor所在服务器挂载一个独立的备份盘用定时任务把数据目录打包同步过去或者直接用定期快照功能。Harbor一旦跑起来它就是你们整个容器化体系的仓库中心重要性不亚于代码仓库该上的保障措施一样都不能少。现在每当我看到团队小伙伴能像用Docker Hub一样丝滑地推送和拉取镜像、权限还管得清清楚楚的时候回想当初搭Harbor那一下午的折腾完全值回票价。