Docker 5.2:Docker 私有镜像仓库 Harbor
如果你所在的公司研发团队超过十几个人,项目一多,镜像一多,公共仓库的拉取速度、私有代码的安全问题、版本管理和权限分配就全都冒出来了。这个时候,你大概率会需要一个私有镜像仓库。而在诸多私有仓库方案中,Harbor 算是最主流、功能最全的一个,也是我这几年在多个项目中实际用下来最顺手的一个。
这篇文章我不打算照着官方文档给你翻译一遍,而是从一个实际部署和运维者的角度,把 Harbor 是什么、解决什么问题、怎么规划、怎么部署、怎么日常运维、会踩哪些坑,一次性讲透。无论你是刚接触容器的小白,还是已经用 registry 用了半年的项目负责人,都能从中找到可以立刻照做的内容。
1. 为什么需要私有镜像仓库,而不是直接用公共仓库
很多团队一开始用 Docker 的时候,都是直接从 Docker Hub 拉公共镜像,或者推到自己的公共仓库里存着。项目少、人就三五个的时候,这么干确实没毛病。但当你开始真正做企业级项目,问题就会一个个冒出来。
首先是访问速度。国内拉 Docker Hub 的镜像本身就不算快,如果团队分布在不同网络环境,有人要用 3 台机器同时拉同一个大镜像,网络基本就卡死在那了。其次是漏洞和安全问题,公共仓库里的镜像谁都能看,你把自己项目打成镜像推到公共空间,等于把内部代码和依赖关系暴露给所有人。第三是没有权限体系,公共仓库里你没法精细控制谁能拉、谁能推、谁能删,出了问题也没有操作审计。
Harbor 就是专门为解决这些问题而生的。它是目前最流行的开源企业级镜像仓库方案,基于 Docker 官方 Registry 之上做了大量增强。简单来说,它做了几件核心的事情:提供 Web 管理界面、支持基于项目的权限控制、内置镜像漏洞扫描、支持镜像签名、提供仓库复制能力、有操作审计日志,还支持按策略清理旧镜像。
用一句直白的话说,Docker Hub 能做的它能做,Docker Hub 做不到的企业级管控它也能做。如果你的团队已经有多个项目、多个环境、多个人协作开发,那么私有仓库的搭建就不要再拖了。
1.1 原生私有仓库 Registry 的痛点
可能有人会说,Docker 官方不是提供了 registry 镜像吗?我起一个容器当私有仓库不就行了?这个问题我见过很多次,也亲自体验过。Docker 官方 Registry 是一个非常简单的基础组件,它的定位是“一个容器镜像的存储与分发服务”,而不是“一个镜像仓库管理平台”。
用原生 Registry 跑起来的第一个问题是没有可视化界面。你要拉镜像只能靠命令行工具,想看仓库里有什么镜像、有哪些标签,全靠 API 去查,有项目经验的人知道,时间长了根本理不清。第二个问题是没有任何权限控制。只要知道地址,任何人都能 pull、push,这在一个真实的团队协作环境里基本是不可接受的。第三个问题是缺少镜像清理机制。磁盘空间是有限的,旧镜像堆积在一起,没有 GC(垃圾回收)机制,运维就只能手动去删。更别提漏洞扫描、复制同步、审计日志这些高级功能了。
Harbor 正是在此基础上发展出来的增强方案。它保留了原生 Registry 的核心能力,同时在前面加了一套完整的 Web 服务层、权限体系和扩展组件。用于解决的就是上面这些痛点:提供图形化管理、精细的权限模型、镜像签名与漏洞扫描、跨环境同步复制、策略化垃圾回收等。我个人的建议是,如果你的仓库只服务于个人开发或测试环境,Registry 够用;但凡涉及多人协作、生产环境,就直接上 Harbor。
1.2 Harbor 的核心能力与适合场景
我习惯把 Harbor 的核心能力拆成六个维度,这样不管是向领导汇报还是自己规划,思路都会很清楚:
- 权限控制:基于项目的多用户管理,支持 LDAP、OIDC 对接,可以精确控制每个用户对哪个项目的 push、pull、delete 权限。
- 可视化界面:从仓库列表、镜像列表、标签管理、复制任务到系统审计,全部有 Web 界面,不需要记 API。
- 镜像漏洞扫描:集成多种漏洞库,可以在镜像推送后自动触发扫描,也可以在界面手动触发。
- 镜像签名:结合 Notary 服务,确保镜像在传输过程中没有被篡改,这在生产环境的合规要求下很有价值。
- 复制与同步:可以从 Harbor 到 Harbor、从 Harbor 到公共仓库或反向同步,支持推拉两种模式,适合多机房、多环境同步镜像。
- 垃圾回收与配额管理:通过设置项目配额限制存储使用,通过 GC 策略实现自动清理无引用的镜像与分片。
至于适合什么场景,我实际接触过的典型情况有这么几类:多项目多团队的企业内部开发环境,需要隔离不同项目的镜像,并记录谁在什么时间做了什么操作;需要做多机房同步的场景,比如在多个区域各部署一套 Harbor,通过复制保证镜像一致;还有信创、金融这类对安全审计有强要求的行业,必须要有操作审计、漏洞扫描和签名能力。
2. 部署前必须想清楚的三件事
很多人拿到 Harbor 就急着 docker-compose up,结果后面权限配置、存储扩容、升级切换全都来折腾一遍,我认为这是最不值得踩的坑。实际上,部署 Harbor 前不用写太多代码,但要把几件架构层面的事想透。这里结合我自己的经验,说说部署前最少需要搞清楚的三个问题。
2.1 存储选型:走本地磁盘还是走对象存储
Harbor 的镜像数据默认存在本地文件系统,安装的时候会指定一个目录,比如 /data。但这个“本地”具体是指哪块盘,很多人安装的时候没细想。
如果你的部署环境就是一台虚拟机或物理机,镜像量不大,直接用本地盘没任何问题。但有一类情况要提前规划好:机器磁盘不够了怎么办?Harbor 对镜像数据的分布其实是相对固化的,想从本地盘平滑迁移到另一块盘,最好的办法是让底层存储本身就支持容量扩展,比如使用云厂商的云硬盘、分布式存储挂载,或者直接在 NFS 上跑 /data 目录。这样扩容诉求是交给底层存储解决的,而不是重新部署一遍 Harbor。
另外,Harbor 是支持配置 S3 兼容对象存储作为镜像存储后端的。这种方式适合那种“镜像量大、机器随时可能要换”的场景。但这里有一个需要提醒的点:配置对象存储会稍微增加每次推送、拉取的网络延迟,如果对象存储性能和网络带宽跟不上,镜像拉取速度可能反而不如本地磁盘。根据我的实际经验,如果在同一内网里有高性能的 S3 服务,这个开销是可接受的;但如果你的对象存储在外网或者性能一般,建议还是老老实实用本地盘加扩容方案。
2.2 暴露方式:HTTPS 地址还是 IP 加端口
Harbor 安装完之后,需要给客户端提供一个仓库地址,这个地址会写入每台机器的 Docker 配置。这个地址可以是域名,也可以是 IP 加端口。我强烈建议在生产环境用正式的 HTTPS 域名,因为 Docker 从 1.13 之后,默认只会信任 HTTPS 的 registry 地址。如果你用的是 HTTP 地址,则必须在每台客户端机器上修改 /etc/docker/daemon.json 增加 insecure-registries 配置,这在规模化部署时就是一个巨大的运维负担。
还有一个细节容易被忽略:你在 Harbor 界面上填写的访问地址(hostname)和证书里的域名必须一致,否则客户端会报证书校验失败。如果你暂时没有域名,只有 IP,也可以为这个 IP 生成自签名证书,并把 ca.crt 分发到各客户端。说到底,地址规划这事越早定下来越好,等到镜像已经推了一大堆再改地址,所有客户端都要重新配置,CI/CD 里的配置也要全改。
有些客户会问,那我要不要用端口映射,比如把 Harbor 映射到 443 或某个高位端口?这个就看你的环境了。Harbor 的核心服务包括前端和 Registry 两部分,默认使用 443 端口对外提供 HTTPS 服务。如果你的 443 已经占用,那就需要提前规划端口映射方案。
2.3 组件选择:装全模块还是按需裁剪
Harbor 安装配置里有一个关键选项,就是每类组件是否启用。比如 Trivy 漏洞扫描组件、Notary 签名组件、Webhook 组件,还有 Chartmuseum(已经被废弃,后面版本基本不涉及)。我见过不少同学初始化安装时直接全部启用,结果发现 Harbor 占用的内存直接飙到了 2GB 以上,在配置不高的机器上每天都有人问“为什么我的 Harbor 这么卡”。
我的思路是这样的:如果是小团队、单项目,首要目标是快速拿到一个能用的仓库,那直接把漏洞扫描关掉就行,能省掉不少资源开销;如果团队规模中等,镜像安全比较关注,那就保留 Trivy,并在项目维度开启自动扫描;如果公司有合规要求,那就需要把签名、审计都打开。组件可以之后再调整,但要想清楚额外的存储、计算开销是否能接受。Harbor 不是越完整越好,而是够用最好。
3. 一次完整的 Harbor 部署实操
接下来进入正题。我会以 Docker 和 Docker Compose 的方式部署一套 Harbor,这也是当前最主流、最容易理解的方式。带大家一步步走完整流程,从下载安装包,到生成配置,再到启动和验证。
3.1 准备环境与下载安装包
Harbor 提供了两种部署形态:一种是在线安装包(harbor-online-installer),体积小,安装时需要联网拉取镜像;另一种是离线安装包(harbor-offline-installer),把所有 Docker 镜像都打进了包里,适合隔离网络或无外网环境。我这里以离线安装包为例,因为生产环境太常见了,而且就算你有外网,离线包安装也会快很多。
部署前需要确认几点:
- 已经装了 Docker 和 Docker Compose 插件。Harbor 依赖这两个东西来拉起整个服务。
- 磁盘有足够的剩余空间,至少给镜像数据留出预估使用量的余地。
- 准备好域名或 IP,以及对应的 HTTPS 证书,没有就用 HTTP 先跑通。
安装包获取可以直接到 Harbor 官方发布页面,选择对应的 release 版本,下载 harbor-offline-installer-v2.x.x.tgz。文件大概 1GB 多,建议放到一个固定目录,比如 /opt/harbor。下载完成后解压:
cd /opt/harbor tar -xzvf harbor-offline-installer-v2.9.0.tgz cd harbor解压目录下会有一个 harbor.yml.tmpl 文件,这是主配置模板。我们接下来要复制一份并修改其中的关键项:
cp harbor.yml.tmpl harbor.yml3.2 修改配置文件:hostname、密码、存储路径是关键
打开 harbor.yml,需要围绕三个核心去调整:
第一是 hostname。这里要填的就是刚才规划的那个地址,客户端会通过这个地址访问仓库。如果填了域名,要确保这个域名能解析到 Harbor 所在机器;如果暂时没有域名,就填 IP 地址。
第二是 HTTPS 证书。Harbor 支持在配置里直接指定证书路径。如果你的服务是公网域名,用正规机构签发的证书最好。如果只在内网使用,自签名也完全可以。配置项大致是这个样子:
https: port: 443 certificate: /data/certs/harbor.crt private_key: /data/certs/harbor.key当然,如果没有证书,也可以先把 https 整段注释掉,然后开启 http 端口 80 来跑通流程。但别把这个当作长期方案,我最后会单独说这个问题。
第三是 harbor_admin_password,也就是 admin 账号的初始密码。默认是 Harbor12345,部署完成后建议立刻改掉。
还有一个值得注意的配置是 data_volume。默认是 /data,你可以改成自己规划好的存储目录,比如 /data/harbor,或者某个单独挂载的大磁盘路径。
这些改完后,保存配置文件。接下来就是安装脚本登场了。
3.3 密钥生成与执行安装
在跑安装脚本之前,Harbor 有几个组件需要预共享密钥(secret key)。这些密钥会在安装脚本中自动生成,不需要手动去改。不过如果你用了外部数据库或外部 Redis,那么在 harbor.yml 里配置好数据库密码就行了,不用额外去管密钥。
安装直接执行:
sudo ./install.sh这里会检测 Docker 和 Docker Compose 是否可用,然后加载镜像、配置组件、编排容器。整个过程中如果缺了什么组件或端口被占用,脚本会抛错提示。根据机器的配置不同,这个步骤可能要花几分钟。
安装完成后,可以通过 docker ps 看看整个 Harbor 集群是否起来了。我见过的主机配置以下常用容器:harbor-core、harbor-registry、harbor-jobservice、harbor-portal、harbor-db、harbor-redis,还有一个 nginx 组件叫 harbor-nginx。
如果都处于 Up 状态,就可以访问 https://你的地址,使用 admin 和你设置的密码登录。
3.4 客户端登录与推送镜像验证
Harbor 装好只是第一步,能顺利 push 和 pull 镜像才是真正的“可用”。这里我给一个完整的实验指南。
在任一台有 Docker 的机器上,先登录 Harbor:
docker login <harbor地址>如果是自签名证书,记得先要把 Harbor 的 CA 证书放到本机 Docker 的信任列表,然后再登录。命令行会提示输入用户名和密码。登录成功之后,给本地镜像打个 tag,tag 的前缀必须是 Harbor 仓库地址加上项目名,例如:
docker tag nginx:latest <harbor地址>/library/nginx:test docker push <harbor地址>/library/nginx:test这里的 library 是 Harbor 里默认自带的公开项目。推完镜像后,回到 Harbor 的 Web 界面,在 library 项目下就能看到这个镜像以及它的标签。此时再到另一台机器上执行 docker pull,验证拉取是否正常。只要这一轮 push 和 pull 都通过,说明 Harbor 的核心链路已经通了。
3.5 实操中遇到的配置文件与密钥问题
安装过程中最容易出问题的就是配置文件格式和密钥相关的东西。
Harbor 的 harbor.yml 对格式非常敏感,尤其是缩进和空格。如果你是从官方模板改的,尽量别大段重排,直接在原文上面改。另外,一旦你第一次执行了 install.sh 之后,再改动 harbor.yml 里的某些参数(比如数据库密码、密钥),直接重新执行 install.sh 是不一定会生效的,因为 Harbor 会把配置持久化到数据库里。如果真要改密码,最好通过 Web 界面或 API 去改,而不是改配置。
另一个容易踩的坑是证书文件的权限。Harbor nginx 容器在启动时读取证书文件,要求私钥文件的权限不能太开放,否则会报权限错误。建议把证书和密钥都放在一个可读目录下,权限设置为 0400 或 0600 比较稳妥。
最后提示一点:如果安装到一半失败,直接重来一遍是不行的。需要先执行 docker-compose down -v 清理容器和持久化卷,再执行 ./install.sh,不然旧的配置会残留。
4. 接入 Harbor 的正确姿势与避坑细节
Harbor 装好只是开始,真正影响日常使用体验的,是客户端和 CI/CD 怎么接入。这块的坑特别多,我挑最常见的几个讲。
4.1 Docker 客户端配置 insecure-registries 的时机
很多团队在一开始没有域名也没有证书,就用 HTTP 部署了 Harbor。这种情况下,客户端执行 docker login 的时候,会直接报错提示“certificate signed by unknown authority”或者“HTTP request denied”。网上搜到的解决方案,清一色是让你修改 /etc/docker/daemon.json,添加 insecure-registries 项。
这个方法在单机测试时是有效的,但我建议千万不要当成生产环境的标准方案。因为 insecure-registries 意味着客户端跳过对仓库地址的证书校验,所有访问该地址的请求都不会被 TLS 保护,镜像在传输过程中存在被劫持或篡改的风险。
如果实在只能走 HTTP,那么在配置了这个 insecure-registries 之后,记得重启 Docker,并确认 Docker 能正常启动。加入配置项的时候,写法要规范,比如:
{ "insecure-registries": ["<harbor-ip>:<port>"] }重启之后,执行 docker info 可以检查配置是否生效。但我仍然要强调:这只适合临时验证,一旦进入正式环境,请务必切换到 HTTPS。
4.2 使用机器人账户,避免暴露员工密码
Harbor 在权限管理上有一个非常实用的功能:机器人账户。这个在 CI/CD 场景下尤其好用。你的流水线需要推送镜像时,不应该把员工的真实账号密码写进 Jenkins 或 GitLab CI 的凭据里,因为一旦人员离职,就要马上改密码,操作记录也没办法追踪到具体是谁推的。
机器人账户可以绑定到某个项目,并赋予只推或者只拉或者推拉都允许的权限。在 Harbor 的 Web 界面上,进入“项目 → 机器人账户”,创建一个新的机器人,系统会给你一个 token,这个 token 是客户端登录时使用的密码。创建完成后,可以用它测试登录和推送。它的好处是权限范围小、可随时吊销,而且多套环境之间互相隔离。
我实际遇到的一个最佳实践是:每个环境都创建独立的机器人账户,比如 dev 流水线用一个,prod 流水线用一个,这样一旦某个环境被盗用或误操作,直接删掉那个机器人就行,不影响其他人。这个思路非常管用,尤其是项目多、微服务多、管理人员没那么充足的时候。
4.3 镜像复制与多环境同步的配置要点
如果公司有多套环境,比如开发环境、测试环境、生产环境都是独立的 Kubernetes 集群,每个集群里配置了独立的 Harbor。这个时候最省心的做法不是让每个环境的构建流水线各自构建镜像,而是“一处构建、多处复制”。
Harbor 的复制管理支持两种模式:基于推送的复制,就是从一个 Harbor 主动推送到目标 Harbor;基于拉取的复制,就是目标 Harbor 定期从源 Harbor 拉取内容。无论哪种,关键配置点有目标仓库地址、访问账号、复制模式、触发策略(事件驱动,比如镜像上传后触发;或者定时轮询)。
这里有个需要提醒的重点:源端和目标端的地址、账号信息一定要确保稳定可访问。如果目标端是 HTTPS 但证书是自签名的,复制任务可能会因为证书校验失败而报错。官方推荐的做法是在目标端使用正式签发的证书,或者临时在复制配置里跳过校验,但后者同样是生产环境的大忌。
我运维过的一个比较舒服的架构是这样的:开发环境一套 Harbor,作为整个公司的源头仓库;测试环境和生产环境各自一套 Harbor,它们通过复制管理从开发环境同步指定项目。这样开发推送后自动同步,测试和生产不需要重复构建,每次发布的东西就是开发验证过的那一套,一致性很有保障。
4.4 Webhook 与事件通知的实用玩法
Harbor 支持 Webhook,也就是当镜像推送、扫描完成等事件发生时,主动向第三方系统发送 HTTP 请求。这个功能在自动化流程里非常关键。
我现在参与的一个项目中,研发团队希望镜像推送到仓库后,测试环境能自动更新服务。实现方式就是:Harbor 配置好 Webhook,将 push 事件发给一个内部接口,该接口收到请求后再触发 Kubernetes 的滚动更新。这样代码合并、构建、推送、部署,完全自动衔接,中间不需要有人手工触发。
另一个实用的场景是把镜像推送事件发给消息中间件,由中间件统一调度多套环境。Harbor 配置 Webhook 时支持按项目维度绑定。我建议把项目分组规划好,比如基础组件项目和业务项目分开,这样 Webhook 的应用范围也更可控。
Webhook 配置里有一个常见问题,就是回调地址的鉴权。你在配置 Webhook 时,可以在请求头里增加一个自定义 token,第三方系统通过校验这个 token 来确保请求是可信的 Harbor 发出的。这个细节很多人忽略了,导致第三方接口随便被人调,存在安全风险。
5. 日常运维中的核心任务和常见坑
Harbor 部署完之后,真正的运维挑战才开始。如果只是装完就丢在那里不管,过不了几个月就会出现磁盘满、镜像拉不了、证书过期这些事。
5.1 镜像垃圾回收机制与操作流程
镜像仓库用久了,最大的问题就是磁盘空间。Harbor 支持垃圾回收功能,但它和 Docker 的缓存清理不一样,垃圾回收是清理那些已经被删除标记的镜像层和数据块。如果你在项目里删除了某个镜像标签,底层存储并不会立即释放空间,而是要执行一次垃圾回收才会把数据清理掉。
Harbor 的 Web 界面上提供了垃圾回收操作入口,在“系统管理 → 垃圾回收”中可以点击“立即回收”。同时它也支持策略化配置,比如每天或每周定时执行。这里有一个很重要的经验:执行垃圾回收时,Harbor 的 Registry 服务会处于只读状态,期间如果有客户端正在 push 镜像,可能会失败。所以最好在低峰期执行,并且要避免在 CI 构建高峰期触发 GC。
另外,垃圾回收之后,“完成”不代表空间百分百释放。它清理的是“未被引用”的分层。如果你保留了很多外部构建缓存,那些不经过 Harbor 管理但依赖 Harbor 作为上游的数据空间,还是要靠存储层去解决的。所以 GC 不是万能的,底层的容量监控和配额管理仍然不可少。
5.2 项目配额与清理策略的配合
Harbor 提供了项目配额功能,可以限制一个项目的最大存储容量和最大仓库数量。这对于控制每个团队的资源使用量非常有效。我遇到的一个真实案例是:多个团队共用一个 Harbor,每个团队都觉得自己的镜像不占空间,结果半年后磁盘突然告警。后来我給每个项目设了配额,超限后的推送会被拒绝,团队自己就会主动去清理旧镜像。
配额设置的同时,最好结合一个“镜像保留策略”,比如每个仓库只保留最近 N 个标签,或者只保留最近 30 天的镜像。这个在 Harbor 的项目配置里可以配置规则。这样配合起来,垃圾回收的负担也会小很多。
有几个细节要特别注意:配额生效是对“推入的数据量”实时校验的,如果已经在推送过程中触达上限,这次推送会被终止。但已存在但超限的项目并不会被强制删除,只会拒绝新的推送。所以,不要把配额设置得过小,否则团队每次发版都会被卡,影响效率。
5.3 日志与监控:不能等到出事再看
Harbor 的日志分散在多个层面:nginx 访问日志、core 服务日志、jobservice 日志、registry 日志。容器化的方式会把这些日志输出到 docker 标准输出或挂载目录。如果是 Docker 方式部署,直接查看容器日志;如果部署在 Kubernetes 里,则要看 Pod 日志。
我的习惯是至少把三种日志接出来:Harbor 自身的标准输出日志、nginx 访问日志、审计相关日志。在系统管理的“审计日志”里,可以看到用户登录、推送、删除等关键操作。这个在出现问题时定位是哪个用户、哪个 IP 在什么时间做了哪个操作,非常重要。
监控方面,Harbor 官方没有自带一套完整的 dashboard,但系统管理的健康检查接口可以配合外部监控。用 Prometheus 拉取 Harbor 的指标也支持一部分,主要是 registry 内部的性能指标。实际使用中,我建议重点监控几个指标:磁盘使用率、容器 CPU/内存使用、项目数量是否异常增长、复制任务的执行时长。这几个指标能覆盖大部分日常风险。
5.4 升级与备份:两条不能省的保障线
Harbor 的版本升级逻辑比较清晰:官方会提供数据库迁移脚本和升级用的脚本。升级前最重要的就是备份。这里说的备份不是打个快照就算完,而是要把 Harbor 的数据库和存储卷都备份好。因为镜像数据可以重新从外部拉取,数据库一旦损坏就非常麻烦。
备份策略我建议按优先级分为两级:第一级,数据库和配置文件定期备份,至少每天一次;第二级,如果镜像数据价值高,或者外部不可恢复,那整个 data 目录都要纳入备份体系。数据量大的时候备份比较占空间,但至少保证数据库备份不能丢。
在执行升级时,官方文档里有明确的脚本流程,一般是先下载新版本离线包,解压后执行 up.sh 或者使用 docker-compose。升级过程中一定要确保所有容器能够停止再重建,千万不要在业务高峰期升级。升级失败的常见原因就是本地数据量太大,迁移脚本在跑的过程中超时,此时不要急着重试,而是先确认数据库无损再处理。
6. 安全加固不能只靠一层配置
Harbor 从设计上已经考虑了很多安全能力,但在真实的生产环境里,安全加固是个综合工程,不是开一个 HTTPS 就算完事。
6.1 最小化权限模型搭配 LDAP 对接
Harbor 的权限模型是“项目维度”:用户可以被加入某个项目,并赋予访客、开发者、维护者等不同角色。访客只能拉取镜像,开发者可以推送,维护者可以管理项目设置和成员。
企业里如果已经有人事系统或统一认证体系,我建议直接把 LDAP 或 AD 对接进来,避免在 Harbor 里维护一堆散装的用户密码。同样,对接 OIDC 也可以实现单点登录。这样员工入职、离职,权限都能自动跟着统一体系统一走。
如果公司规模不大,也可以用本地用户模式,但一定要给每个机器人和用户起清楚的名字,最好能关联到具体的使用方。我见过有团队所有开发共用 admin 账号,出问题根本查不到是谁操作的,这种状态要尽早统一改掉。
6.2 漏洞扫描和签名机制在生产环境的取舍
Harbor 内置的漏洞扫描功能支持在推送之后触发扫描,并生成报告。生产环境里我建议开启自动扫描,并在项目配置中选择“阻止有高危漏洞的镜像推送”。这能避免不安全的镜像被引入到生产集群。
但这个机制也有成本,扫描镜像需要额外的开销,而且漏洞库更新也要时间。我见过有些团队扫描到漏洞之后不知所措,因为很多基础镜像的漏洞根本没法立刻修复。这时候宗旨应该是:高危漏洞必须先阻止上线,中低危漏洞可以结合实际情况定优先级,而不是一竿子打死。
镜像签名机制,即 Harbor 结合 Notary 的能力,目前在一些对安全合规要求严格的行业里比较常见。签名能确保你拿到的镜像是“构建并被验证过的那个”。但对于多数互联网业务团队来说,签名带来的额外流程成本偏高,不一定适合立刻上。我的建议是,先确保镜像传输链路是 HTTPS 的,同时开启漏洞扫描,签名可以等团队大了、安全要求提高了再说。
6.3 定期审计与风险排除的小技巧
我会定期检查这几项内容:系统管理里的审计日志,看有没有陌生 IP 的登录;机器人账户列表,看有没有长时间未使用的账户;项目配额使用率,看有没有项目接近上限;复制任务的成功率,看有没有长期失败但没有被注意到的链路。
这些检查不需要天天做,但至少每月一轮。很多事故本来可以避免,就是因为没人定期看一眼监控和日志。把 Harbor 纳入你已有的监控和告警体系,既是省心,也是责任。
7. 最后再分享几个我实际总结的运维心得
资深的运维经验往往不是写在文档里的,而是踩过坑之后才明白的。这里分享几条我用 Harbor 用得最久之后的实际体会。
- 无论配置看起来多完美,每次安装完都建议立即跑一轮从登录到推送的完整验证。因为 Harbor 涉及 nginx、core、registry、数据库等多个容器,任何一个环节出了问题,表面上可能都很正常,只有真正推一个镜像才暴露。
- 不要在同一个 Harbor 实例里同时放内部生产和外部演示的镜像。尽量用项目隔离和机器人账户把这些逻辑边界彻底分开,这样安全性和可维护性都会好很多。
- 遇到拉取超时,先别怪网络,先检查是否是因为某个项目配额满导致 GC 没有定时执行,数据积压后磁盘 IO 才开始变差。这种性能问题远比网络问题常见。
- 域名证书一定要留足提前量,自签名证书和正式证书的更新机制不同,别等过期了再换。证书过期后,所有客户端的 login 请求都会失败,这种问题定位需要花很长时间,却完全是可以预防的。
- Harbor 的配置和数据展示会相对滞后,比如项目里删了镜像,界面上不会立刻消失,这不代表操作失败。理解它的异步处理机制后,就不会被这些假象误导。
8. 扩展思路:从单一仓库走向企业级镜像中心
当你的 Harbor 从一个简单仓库演变成企业内部的基础设施后,你很可能还会面对更大的问题:如何将镜像的构建、存储、分发、部署全部串成一个自动化链路。
这时候可以考虑在 Harbor 前面增加一个统一的镜像构建入口,比如配套的 CI 流水线会在代码合并后自动构建镜像,并把带有版本号的镜像推送到 Harbor,然后由部署平台负责从 Harbor 拉取镜像到各环境。Harbor 在其中扮演了稳定、安全、可控的中间层。
也可以思考如何把 Harbor 的复制能力与多集群融合起来。比如在不同区域的 Kubernetes 集群里,各自配置一个本地的 Harbor 只读副本,数据源统一从一个中心 Harbor 拉取。这样真正地做到了“构建一次、随处运行”。
如果你已经到达了这个阶段,那么恭喜你,你已经不再是“给团队搭了个仓库”的阶段,而是真正在构建一个企业内部可控、可审计、可扩展的镜像交付体系了。而所有这一切,都是从先跑通一个稳定可靠的 Docker 私有镜像仓库开始的。