恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
Harbor私有镜像仓库实战:安装配置与运维踩坑全程解析
首页
资讯中心
/
Harbor私有镜像仓库实战:安装配置与运维踩坑全程解析
Harbor私有镜像仓库实战:安装配置与运维踩坑全程解析
发布时间:2026/10/17 23:35:57
做容器化折腾了几年镜像仓库这东西真的是绕不开的一环。团队内部自己搭一个私有镜像源早期图省事直接起一个裸的Registry后面项目多了、人多了权限、复用、清理、安全扫描全都成了问题。这时候把Harbor搬出来基本属于“早迁早省心”的解法。Harbor是一个开源的私有容器镜像仓库核心功能不光是存镜像、拉镜像而是把镜像管理做成了企业级基于角色的权限控制、项目级隔离、镜像复制同步、漏洞扫描、回收机制、审计日志这些全都有。你在它的Web界面上点几下就能完成过去要写一堆脚本才能搞定的事情。这篇文章我就把从零安装到配置落地、再到日常运维踩坑的完整过程都梳理一遍适配的场景是内网环境自建私有仓库目标读者是刚开始搭建容器基础设施的同学以及在选型阶段想搞清楚Harbor到底值不值得上的运维和开发人员。1. Harbor是什么为什么不是直接裸跑一个Registry1.1 裸Docker Registry的痛点先说说为什么很多人最后从裸Registry迁到了Harbor。Docker官方提供的Registry镜像是很好用一条docker run -d -p 5000:5000 registry就能跑一个私有仓库出来推镜像、拉镜像都没问题。但你真的用起来就会发现它几乎就是一个“存镜像的硬盘”什么都不管。最明显的痛点是没有权限体系。裸Registry可以配一个简单的htpasswd账号认证但所有账号进去都是一样的权限没有项目隔离没有只读和读写区分。开发环境、测试环境、生产环境的镜像全都堆在同一个命名空间里推错、误删、覆盖是常有的事。其次是镜像多了以后管理特别费劲没有Web界面去浏览标签列表没有可视化的磁盘占用统计清理旧版本全靠自己写脚本调Registry的API。再有就是安全层面的缺失镜像推上去是什么就是什么没有漏洞扫描没有镜像签名校验。你可能会说项目小的时候这些都不是问题。但对一个团队而言从第一天就把权限边界、命名规范、回收机制定好后面能省掉大量沟通成本。Harbor正是为了解决这些问题出现的。1.2 Harbor补齐的企业级能力Harbor本质上还是基于Docker Distribution做的二次封装数据面没有另起炉灶但控制面和运维面补得非常全多项目多仓库每个项目是独立的命名空间项目之间互相隔离可以在项目级别分配开发者、维护者、只读者等角色。RBAC权限模型用户、项目、角色三层结构清晰还能对接企业里的LDAP/AD统一认证不用每个系统单独维护账号。镜像复制支持从另一个Harbor实例或远端Registry定时同步镜像多机房、主备容灾场景直接可以用。漏洞扫描内置Trivy扫描器可以对镜像做CVE漏洞检测在Web界面上直接看到哪些镜像有高危漏洞。垃圾回收与配额可以设置项目配额防止有人一次性推几百GB镜像把磁盘塞满也能定期执行GC把悬空的镜像层清掉。审计与操作日志谁在什么时间推了什么镜像、删了什么标签都有记录出问题的时候能回溯。这些能力听起来花哨实际落地的时候每一个都对应真实的场景需求。权限模型解决的是“谁能动生产镜像”复制解决的是“两个机房怎么保持镜像一致”GC解决的是“磁盘满了怎么办”。所以Harbor不是一个玩具级的Registry套壳而是把容器镜像当成正经资产来管理的一套系统。2. 安装前的环境盘点与依赖准备2.1 硬件和系统约束先对齐Harbor本身由一堆容器组成核心组件包括nginx、core、registry、portal、数据库和Redis选装组件还有Trivy扫描器、Chartmuseum等。这意味着你不需要额外装什么复杂的运行时只要机器上有Docker Compose就能把它拉起来但硬件上还是有一些底线要守。我自己常用的最低配置是2核4G这是在只跑核心组件、不启用Trivy扫描的前提下。如果开了漏洞扫描Trivy需要下载漏洞数据库并且要周期更新CPU和内存占用都会上来4核8G会更舒服。磁盘方面别抠门镜像仓库是吃磁盘的大户至少要预留出你所规划的镜像容量两倍以上的空间因为镜像层在GC之前不会自动释放。系统方面CentOS 7.9、Ubuntu 20.04/22.04、Debian 11/12我都部署过没有遇到什么兼容性问题。内核版本建议不低于3.10Docker版本的新旧影响反而更大。还有一点要提前规划存储路径。Harbor默认把数据放在宿主机的/data目录下包含数据库文件、镜像存储、证书等等。如果系统盘不大务必在安装前把数据目录挂到独立的数据盘甚至在harbor.yml里显式修改data_volume的路径。这事越早做越好因为中途挪数据虽然可行但每次都要停服务、打包、搬运、再起来风险不比一次全新安装小。2.2 Docker与Docker Compose的装法Harbor官网给的依赖要求是Docker Engine 17.06以上、Docker Compose 1.18以上但这个门槛偏低。实际部署中我建议直接用较新的版本比如Docker 20.10以上、Compose V2插件因为新版本的网络、存储驱动更稳定Harbor后期的版本也逐渐面向新版Compose做适配。这里有个容易踩坑的点旧版docker-compose是Python写的独立二进制新版是Docker的插件命令变成了docker compose。Harbor的install.sh脚本在检测Compose时两种写法它都能认但对Compose文件的格式兼容性会有差异。建议统一用新版避免在两台机器上分别用不同方式安装导致行为不一致。确认Docker已经安装后跑一下docker --version docker compose version两条命令都能正常回显版本号就说明基础环境OK。如果docker compose提示找不到命令检查Docker是否带了Compose插件或者自己单独装一个兼容版本。内网环境装Docker时尤其注意别从乱七八糟的源拉安装包用系统官方源或者你所在企业内部的软件源装完顺手把镜像加速地址配好后面拉Harbor的基础镜像会顺畅很多。2.3 下载安装包的正确姿势Harbor提供在线安装包和离线安装包两种形式。在线安装包很小只有几MB因为它不打包镜像运行install.sh时实时从Docker Hub拉取组件镜像。离线安装包则把所有组件镜像都打包在一个tgz里体积通常在几百MB到1GB左右。我更推荐离线包。原因是install.sh执行期间要从外网拉好几个镜像包括goharbor/portal、goharbor/core、goharbor/registry等等网络一波动安装就失败失败的现场还特别难排查。离线包下载的时候虽然慢一点但下载过程可控、可校验拷到服务器上解压后基本一次就能装好。在公司内网搭Harbor的场景下你后面还要往里面推内部镜像说明机器本身和外部网络的隔离要求可能比较严格离线包天然更契合这种环境。下载解压后目录结构大概是harbor/ ├── harbor.yml.tmpl ├── install.sh ├── common.sh └── harbor.v2.11.0.tar.gzharbor.yml.tmpl是配置模板不能直接拿来用需要cp一份改成harbor.yml再编辑。install.sh是安装入口common.sh里有一堆公共函数和变量。整个过程其实就是编辑一个YAML配置然后跑一条脚本剩下的交给脚本自动化完成逻辑并不复杂难点全在配置的正确性和环境的前置条件上。3. 配置harbor.yml这一步决定成败3.1 配置项逐段拆解Harbor的配置文件是harbor.yml整个安装的核心就是把这份配置写对。打开模板文件开头就是hostname和http.port两个最基础也最关键的项目。hostname: reg.example.com http: port: 80 https: port: 443 certificate: /your/certificate/path private_key: /your/private/key/path harbor_admin_password: Harbor12345 database: password: root123 max_idle_conns: 50 max_open_conns: 100 data_volume: /data/harborhostname的取值要特别注意。它不只是一个展示用的名字而是会被写入Harbor内部配置并且在生成的访问URL、Registry的endpoint、复制任务的目标地址里都会被引用。如果你打算用IP访问这里就填IP打算用域名访问这里就填完整域名。别小看这一项填错了后面推镜像时会发现Registry地址和登录地址对不上。harbor_admin_password是管理员初始密码至少要8位且包含大小写字母和数字。database.password是Harbor内部PostgreSQL数据库的密码也一并改掉。这里提个醒很多安装教程会告诉你用默认密码先跑起来但生产环境如果还留着默认密码等于把仓库管理权限敞开给别人非常危险。3.2 证书与HTTPS的取舍模板里默认开的是HTTPS需要指定证书和私钥路径。如果你在内网环境没有正式签发的证书又不打算自己维护CA最简单的方式是先把HTTPS整段注释掉用HTTP方式跑起来。http: port: 80 # https: # port: 443 # certificate: /your/certificate/path # private_key: /your/private/key/path但要知道Docker客户端在默认情况下只允许通过HTTPS访问Registry你用了HTTP之后必须在每台要拉镜像的机器上把Harbor地址加入insecure-registries白名单否则会报“HTTP protocol is not allowed”或者证书校验错误。这个方案适合内网开发和测试环境正式环境还是建议走HTTPS哪怕是自己签的CA也比明文HTTP强。还有个折中方案就是在Harbor前面再放一层Nginx对外暴露HTTPS由Nginx终结SSL然后把请求转发给Harbor的HTTP端口。这种方式在已经有统一网关的公司里很常见可以复用现有的证书管理体系不用在Harbor容器里单独维护证书。3.3 数据目录规划data_volume这一项默认是/data我建议显式改成自己规划好的路径。比如我有一次部署时把系统盘和数据盘分开数据盘挂载在/data/harbor配置就写成data_volume: /data/harborHarbor会把数据库、镜像存储、相关日志都放进这个目录。安装前要确认目录存在并且Docker进程有权限写入。最好的做法是提前建好目录并调整属主sudo mkdir -p /data/harbor sudo chown -R 1000:1000 /data/harbor为什么是1000这个UID因为Harbor容器内部默认以UID 1000的用户运行宿主机目录属主如果不匹配容器写数据时会遇到权限拒绝现象就是页面能打开但推镜像报权限错误或者数据库起不来。这个坑我在第一次部署时踩过一次排查了半天才发现只是目录属主不对。4. 执行安装与初始化流程4.1 运行install.sh的完整过程配置写好后进入解压出来的Harbor目录直接执行安装脚本sudo ./install.sh脚本会先做环境检查确认Docker和Compose存在然后加载harbor.yml里的参数接着用Docker Compose把服务全部拉起。整个过程大概一两分钟取决于机器性能和镜像加载速度。安装完成的标志是最后出现“Harbor has been installed and started successfully”的提示。如果想启用Trivy漏洞扫描可以在安装时加上--with-trivy参数sudo ./install.sh --with-trivyTrivy组件会额外占几个GB的磁盘空间用于存储漏洞库但带来的价值是能直接在Harbor界面看到每个镜像的安全扫描结果。生产环境我建议开至少要知道自己推上去的镜像有没有已知的严重漏洞。4.2 验证服务状态安装脚本跑完不代表万事大吉我一般会再做两步验证。第一步是看容器状态sudo docker compose ps正常情况下能看到nginx、core、portal、registry、db、redis等若干容器都是Up状态。如果某个容器反复重启基本可以确定是配置或者目录权限的问题这时候去看对应容器的日志比盲目重装有效得多。第二步是用浏览器访问http://服务器IP能看到Harbor的登录页面。默认管理员账号是admin密码是你在harbor.yml里设置的harbor_admin_password。首次登录后建议立即到“个人中心”里改掉密码也可以顺便把“管理员”这个账号的二次认证开起来虽然内网环境不一定需要但多一层保护总归是好的。4.3 首次登录与基础配置登录进去之后别急着推镜像有几个基础配置值得先花几分钟设置。在“系统管理”的“配置管理”里有一个“仓库读写权限”的选项默认情况下项目和镜像都允许所有人读取。内网环境想收紧访问控制的话可以把“自动创建项目”关掉避免任何人随便建项目。项目配额也建议先设好按团队实际需求给每个项目限制容量防止镜像无限堆积。用户管理这块Harbor默认支持本地用户也可以对接LDAP。如果团队规模不大本地账号完全够用为每个成员建一个账号然后按项目分配“开发者”或“维护者”角色就行。“开发者”能推送镜像“维护者”能管理项目成员“只读者”只能拉取查看。生产镜像的项目建议只分配“只读者”给大部分成员把“维护者”留给负责人和运维。5. 客户端接入让Docker能推拉镜像5.1 配置insecure-registriesHarbor装好了接下来要解决的是客户端能不能正常访问。如果你用的是HTTP方式或者自签名的HTTPS证书那么每台需要推拉镜像的机器都得在Docker配置里放行这个地址。编辑/etc/docker/daemon.json{ insecure-registries: [192.168.1.100] }如果有多个Registry地址就写成数组形式。改完一定要重启Dockersudo systemctl restart docker这里有个容易犯的错daemon.json是严格的JSON格式少一个逗号、多一个引号都会导致Docker起不来。改完后先用python3 -m json.tool /etc/docker/daemon.json验证一下格式再重启服务。别问我为什么知道问就是我曾因为一个多余逗号把自己锁在门外过。5.2 创建项目和机器人账号Harbor的项目等同于镜像仓库的一级命名空间。在Web界面点“新建项目”填一个项目名称比如library或者按业务线命名的backend、frontend。项目建好后镜像的完整地址就是服务器IP/项目名/镜像名:标签。推送镜像不一定非要直接用个人账号Harbor支持创建“机器人账号”。这个功能相当实用它生成一对长期有效的账号密码专门给CI/CD流水线用权限可以精确到单个项目而且密钥可以随时重置。生产线上的Jenkins、GitLab Runner这些自动化工具用机器人账号比用管理员账号安全得多管理员密码就算泄露也不会牵连到整个Harbor。5.3 推送镜像的完整命令演示在客户端机器上先登录Harbordocker login 192.168.1.100输入用户名和密码后会提示Login Succeeded。然后给本地镜像打标签再推送docker tag myapp:latest 192.168.1.100/library/myapp:v1.0 docker push 192.168.1.100/library/myapp:v1.0其它机器拉取时同样需要先配置insecure-registries然后执行docker pull 192.168.1.100/library/myapp:v1.0这套流程本身不复杂难点在于让团队每个人都按统一规范来操作。我会在Harbor的项目介绍页面上写清楚镜像命名规范和推送命令示例这样新成员看一眼就能上手省得每次都要在群里问“镜像地址到底怎么写”。6. 常见问题排查与运维心得6.1 页面打不开和端口占用这类是Harbor装完遇到最多的故障。先说页面打不开先确认容器是否都在正常运行docker compose ps看状态再看宿主机防火墙有没有放行端口很多云主机默认安全组没放行80端口页面当然访问不了。排查顺序应该是容器状态 → 防火墙 → 端口监听。端口冲突也是高频问题。Harbor默认占用80端口如果机器上已经有Nginx或者其它Web服务启动时就会因为端口被占用而失败。查看监听端口可以用sudo ss -lntp | grep :80 如果确实被占了可以在harbor.yml里把HTTP端口改成别的端口比如8080。但要注意改完端口后镜像仓库地址里也要带上端口浏览器访问时要写http://192.168.1.100:8080Docker客户端登录时要写docker login 192.168.1.100:8080。6.2 推送失败的身份与网络问题推送镜像时报unauthorized: authentication required第一反应应该是账号权限。检查你在Harbor里有没有该项目对应角色的权限机器人和个人账号都要确认。如果用户名密码看着没问题但就是推不上去看一下是不是开了“自动创建项目”但项目名带了大写字母Harbor的项目名强制小写大写在登录时会提示项目不存在。还有一种情况是客户端能登录、能拉取镜像但一推送就超时。这种多半是网络层面的原因比如大镜像跨网段传输被防火墙拦了或者Harbor所在服务器带宽跑满了。可以在Harbor服务器上看着docker compose logs -f core和registry的日志推送时如果日志里有大量重试基本可以确定是吞吐或网络问题。6.3 备份恢复和升级路径Harbor的数据分布在数据库和镜像存储里备份时两个都要考虑。最简单粗暴的方式是直接停服复制整个data_volume目录sudo docker compose down tar czf harbor-data-$(date %F).tar.gz /data/harbor sudo docker compose up -d停服备份的好处是数据一致性好缺点是会有短暂的服务中断。如果你要求不中断那就用数据库原生的备份方式把Harbor的PostgreSQL dump出来镜像存储用docker registry的API做在线导出。但这类操作复杂度高日常小规模部署没必要这么折腾定时全量备份定期演练恢复就够了。升级Harbor版本时我的惯例是先备份再下载新版本安装包然后把旧版的harbor.yml里你有改动的配置项搬到新模板里最后运行./install.sh。Harbor官方也提供了upgrade.sh脚本可以保留现有数据原地升级。但无论如何升级前一定要把数据备份做好容器应用升级失败想回滚不是手滑点两下那么简单。6.4 磁盘空间与日志管理运行一段时间后最容易被忽视的就是磁盘占用。Harbor的日志默认也在data_volume下长时间不管会积累大量访问和操作日志。建议配置一下宿主机上的日志轮转比如用logrotate定期清理或者定期手动清理/data/harbor/log目录下过期的日志文件。镜像存储的膨胀速度取决于团队的使用习惯。有人喜欢每个镜像都打一个latest标签每次构建都覆盖推送这种情况下不会产生太多冗余但如果是每个版本都保留镜像时间一长旧版本的无效层会越堆越多。这时候可以定期在Harbor界面上执行垃圾回收把没有被标签引用的镜像层清理掉。注意GC操作会占用一定资源建议在业务低峰期执行而且GC完成后磁盘空间不会立刻全部释放需要等一段时间的清理收敛。我自己在实操中的体会是Harbor从部署到稳定运行最花时间的往往不是安装那几十分钟而是之后把权限模型、命名规范、备份策略这些运维细节一点点打磨顺。这份工作做得好不好直接决定了团队每天推拉镜像的体验。如果你也正在搭建私有仓库建议你先按这套流程把基础环境跑起来然后在真实的使用中把你自己的那套规范沉淀进去。后面等镜像量大了可以再考虑加装镜像复制、对接CI/CD这些进阶能力。