
1. 项目缘起为什么我们需要一个自己的镜像仓库在任何一个稍微有点规模的软件研发团队里你大概率会听到“持续集成”和“持续部署”这两个词。简单来说它们的目标就是让代码从提交到上线的过程像工厂流水线一样自动化、标准化、快速且可靠。想象一下你写了一段新功能代码提交到Git仓库后系统自动帮你编译、打包、跑测试然后自动部署到测试环境甚至生产环境。整个过程无需人工干预既减少了人为失误也极大地提升了交付效率。在这个自动化流水线中有一个环节至关重要那就是制品管理。对于现代应用尤其是微服务架构最终的交付物往往是一个个Docker镜像。这些镜像就是流水线上的“半成品”或“成品”。如果每次构建都从公共仓库拉取基础镜像或者把构建好的镜像随意存放在某个开发者的机器上那这个流水线就乱套了。你会面临镜像版本混乱、依赖不一致、安全风险高、分发效率低等一系列问题。这时候一个私有的、企业级的Docker镜像仓库就成了刚需。它就像是你团队内部的“中央仓库”或“物流中心”所有构建好的镜像都统一存放到这里所有需要部署的环境都从这里拉取镜像。这保证了环境的一致性、版本的可追溯性以及内部网络下的高速访问。市面上有很多选择比如Docker Registry、Nexus Repository Manager等。但Harbor凭借其开箱即用的企业级特性脱颖而出它不仅是一个镜像仓库更是一个完整的制品管理平台。它原生支持镜像的漏洞扫描、内容签名与验证、基于角色的访问控制、镜像复制策略、图形化的管理界面并且与主流的CI/CD工具如Jenkins、GitLab CI无缝集成。可以说搭建Harbor是构建一个健壮、安全、高效的CI/CD体系的基础设施第一步。2. 部署前夜环境规划与核心组件拆解在动手安装之前盲目执行安装脚本是最大的忌讳。理解Harbor的架构和你的环境需求能帮你避开90%的后期运维坑。Harbor在架构上是一个典型的微服务应用它由多个容器化组件构成通过Docker Compose或Kubernetes Helm Chart进行编排部署。2.1 核心服务组件一览当你成功运行Harbor后通过docker-compose ps命令你会看到类似下面的一系列服务harbor-core: 这是Harbor的大脑和API网关。所有Web UI的操作和外部API调用比如Jenkins推送镜像最终都会由它来处理和路由到其他服务。harbor-portal: 这就是我们看到的那个漂亮的Web管理界面基于Nginx负责提供用户交互。harbor-db: PostgreSQL数据库用于存储用户、项目、权限、复制策略等所有元数据。这是Harbor的“记忆中枢”数据无价务必做好备份。redis: 用作缓存和会话存储提升核心服务的响应速度。registry: 这才是真正存储Docker镜像二进制数据的仓库它基于开源的Docker Distribution项目。Harbor在它之上封装了权限、审计等企业级功能。registryctl: 负责与底层registry交互执行垃圾回收等管理操作。jobservice: 后台作业服务。像镜像复制、漏洞扫描这些耗时任务都会由它来异步执行。trivy-adapter(或clair-adapter): 镜像安全扫描适配器。Harbor默认集成Trivy一个轻量级漏洞扫描工具当你启用扫描功能后推送的镜像会被自动扫描并在UI中显示风险等级。理解这些组件有助于你在出问题时快速定位。比如推送镜像失败可能是registry服务挂了Web界面登录不了可能是core或redis有问题。2.2 硬件与网络环境规划对于生产环境规划比安装本身更重要。服务器规格对于中小型团队日构建镜像数在几百个级别一台4核8G内存、100GB以上磁盘的Linux虚拟机如CentOS 7.6/Ubuntu 18.04作为起点是足够的。重点在于磁盘I/O和容量镜像仓库是IO密集型应用且数据增长很快建议使用SSD并预留充足空间。网络与域名强烈建议为Harbor配置一个域名如harbor.yourcompany.com而不是直接使用IP地址。这关系到证书配置和后续与其他系统的集成。你需要提前在DNS服务器或本地hosts文件中做好解析。存储后端默认安装使用本地文件系统存储镜像。对于生产环境你应该考虑配置外部存储如NFS、Ceph、S3兼容的对象存储如MinIO或云厂商提供的对象存储服务。这便于扩展、备份和高可用部署。在安装前的配置文件中会有相应的配置项。数据库高可用对于核心生产系统可以考虑将harbor-db外接到一个高可用的PostgreSQL集群而不是使用容器内自带的数据库。3. 实战安装从零到一搭建Harbor v2.x假设我们在一台全新的CentOS 7.9服务器上使用离线安装包进行部署。这是最常见和可控的方式。3.1 基础环境准备首先确保服务器环境干净并安装必要的依赖。# 1. 更新系统并安装基础工具 sudo yum update -y sudo yum install -y yum-utils device-mapper-persistent-data lvm2 # 2. 安装Docker与Docker Compose # 添加Docker官方仓库 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 安装Docker引擎 sudo yum install -y docker-ce docker-ce-cli containerd.io # 启动并设置开机自启 sudo systemctl start docker sudo systemctl enable docker # 3. 安装Docker Compose # 从GitHub Release下载稳定版本例如 v2.20.0 sudo curl -L https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose sudo chmod x /usr/local/bin/docker-compose # 验证安装 docker-compose --version3.2 下载与解压Harbor离线安装包访问 Harbor GitHub Release页面 选择最新的稳定版本例如v2.8.0。根据你的需求下载离线安装包harbor-offline-installer-v2.8.0.tgz它包含了所有必要的镜像。# 假设我们将Harbor安装在 /opt 目录下 cd /opt # 使用wget下载或将本地包上传至此目录 sudo wget https://github.com/goharbor/harbor/releases/download/v2.8.0/harbor-offline-installer-v2.8.0.tgz # 解压 sudo tar xzvf harbor-offline-installer-v2.8.0.tgz cd harbor现在你会看到目录下有几个关键文件harbor.yml.tmpl配置模板、install.sh安装脚本、prepare配置准备脚本以及common目录。3.3 关键配置文件harbor.yml详解与定制harbor.yml是整个安装的灵魂。你需要复制模板并仔细修改它。sudo cp harbor.yml.tmpl harbor.yml sudo vi harbor.yml下面我们逐段解析最关键的配置项# 第一部分主机名与网络配置 - 这是最容易出错的地方 hostname: harbor.yourcompany.com # 必须修改填写你为Harbor准备的域名或IP。 # 如果使用IP后续客户端配置会非常麻烦不推荐。 # 例如192.168.1.100 (不推荐) 或 harbor.internal.com (推荐) # HTTP相关配置生产环境建议关闭只用HTTPS # http: # port: 80 # HTTPS配置 - 生产环境强制要求 https: port: 443 certificate: /your/certificate/path/server.crt # 你的SSL证书文件路径 private_key: /your/certificate/path/server.key # 你的SSL私钥文件路径 # 重要经验如果你暂时没有正式证书或者只是在测试环境 # 可以注释掉https部分使用http。但更推荐使用自签名证书先跑通流程。 # 生成自签名证书的命令示例 # openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 365 -out ca.crt -subj /CCN/STBeijing/LBeijing/OYourCompany/CNharbor.yourcompany.com # 然后将ca.crt和ca.key的路径配置到上面。 # 第二部分Harbor管理员密码 harbor_admin_password: Harbor12345 # 修改这是admin用户的初始密码务必改成强密码。 # 第三部分数据库密码 database: password: root123 # 修改这是容器内PostgreSQL数据库的root密码。 max_idle_conns: 50 max_open_conns: 100 # 第四部分数据持久化路径 data_volume: /data # 默认数据存储路径包括镜像、数据库数据等。 # 确保该目录所在磁盘有足够空间或将其挂载到大容量存储上。 # 第五部分外部存储可选生产环境建议配置 # 例如使用一个NFS共享目录 # storage_service: # filesystem: # rootdirectory: /nfs_storage/harbor # 或者使用S3 # storage_service: # s3: # region: us-east-1 # bucket: your-harbor-bucket # accesskey: YOUR_ACCESS_KEY # secretkey: YOUR_SECRET_KEY # 第六部分其他功能开关 clair: updaters_interval: 12 # 漏洞库更新间隔默认12小时 trivy: ignore_unfixed: false # 是否忽略未修复的漏洞建议false以看到所有风险 skip_update: false # 是否跳过Trivy数据库更新建议false offline_scan: false # 是否离线扫描若无外网可设为true并使用离线漏洞库 jobservice: max_job_workers: 10 # 后台作业的最大工作线程数根据服务器性能调整 notification: webhook_job_max_retry: 3 # Webhook通知失败重试次数注意修改完harbor.yml后Harbor提供了一个prepare脚本来验证和生成最终的运行时配置。它会根据你的harbor.yml生成common/config目录下的各组件配置文件。这是一个好习惯可以提前发现配置错误。3.4 执行安装与验证配置无误后就可以运行安装脚本了。离线安装包已经包含了所有镜像所以安装过程不需要联网。# 使用install.sh脚本进行安装 sudo ./install.sh安装脚本会依次执行以下操作加载Docker镜像从离线包中。根据harbor.yml准备配置文件。使用docker-compose启动所有服务容器。当看到✔ ----Harbor has been installed and started successfully.----的提示时表示安装成功。3.5 安装后的基础检查安装完成后不要急着用先做几个快速检查# 1. 检查所有容器是否都处于运行状态 (Up) sudo docker-compose ps # 你应该看到core, portal, jobservice等所有服务的状态都是 Up # 2. 检查关键服务日志确保没有持续报错 sudo docker-compose logs -f core # 查看核心服务日志CtrlC退出 # 同样可以检查 registry, nginx 等服务 # 3. 在服务器本机测试访问假设你配置了域名或正确IP curl -k https://harbor.yourcompany.com/api/v2.0/ping # 如果返回 pong说明API服务是正常的。现在打开浏览器访问https://harbor.yourcompany.com你应该能看到Harbor的登录界面。使用用户名admin和你设置的harbor_admin_password登录。4. 避坑指南安装与初始化过程中的典型问题即使按照步骤操作你也可能会遇到一些问题。这里汇总了几个最常见的坑及其解决方案。4.1 容器启动失败端口冲突错误现象运行docker-compose ps发现某个容器状态是Exit或Restarting查看日志docker-compose logs [service_name]显示address already in use。根因分析Harbor默认会占用80、443、4443等端口。如果你的服务器上已经运行了Nginx、Apache或其他Web服务就会冲突。解决方案修改Harbor端口在harbor.yml中修改http.port和https.port例如改为8080和8443。然后重新运行sudo ./install.sh。停止冲突服务如果端口可以释放则停止占用端口的服务。例如sudo systemctl stop nginx。使用反向代理更优雅的生产环境做法是让Harbor使用非标准端口如8080然后在前端用一个专业的反向代理如Nginx监听80/443并将请求代理到Harbor。这便于统一管理SSL证书和域名。4.2 Docker客户端无法推送镜像证书问题错误现象在客户端机器执行docker push harbor.yourcompany.com/library/nginx:latest时报错x509: certificate signed by unknown authority。根因分析Docker客户端不信任你为Harbor配置的SSL证书尤其是自签名证书。解决方案针对自签名证书将CA证书放入Docker信任列表推荐将Harbor服务器上生成的ca.crt文件拷贝到客户端机器。根据客户端操作系统将证书放到指定位置Linux:/etc/docker/certs.d/harbor.yourcompany.com/ca.crtmacOS (Docker Desktop):~/.docker/certs.d/harbor.yourcompany.com/ca.crtWindows (Docker Desktop):C:\Users\你的用户名\.docker\certs.d\harbor.yourcompany.com\ca.crt重启Docker服务或Docker Desktop。修改Docker守护进程配置忽略证书验证不推荐仅用于测试 编辑客户端机器的/etc/docker/daemon.jsonLinux或 Docker Desktop 设置中的daemon.json添加{ insecure-registries: [harbor.yourcompany.com] }警告insecure-registries会完全禁用对该仓库的TLS验证存在中间人攻击风险绝对不要在连接公网的生产环境中使用。4.3 推送镜像时报错 “denied: requested access to the resource is denied”错误现象docker push失败提示权限被拒绝。根因分析这是最常见的问题之一。你没有登录或者登录的用户没有目标项目的推送权限。解决方案首先确保你已经登录docker login harbor.yourcompany.com输入正确的用户名和密码。检查项目权限Harbor的权限模型是项目级的。默认情况下只有管理员和项目成员才能推送镜像。用管理员账号登录Web UI。进入“项目”列表找到或创建你打算推送镜像的项目例如my-project。点击项目名称进入详情在“成员”选项卡中将你的用户添加为成员并赋予“开发者”或“项目管理员”角色“开发者”角色拥有推送权限。镜像Tag必须包含项目路径这是Harbor的强制要求。你不能直接推送nginx:latest。你必须将镜像重新打Tag格式为[Harbor主机名]/[项目名]/[镜像名]:[标签]。# 从公共库拉取一个示例镜像 docker pull nginx:latest # 重新打Tag docker tag nginx:latest harbor.yourcompany.com/my-project/nginx:latest # 现在再推送 docker push harbor.yourcompany.com/my-project/nginx:latest4.4 Web界面访问缓慢或部分功能加载失败错误现象登录后界面加载很慢或者“漏洞扫描”、“复制管理”等页面一直转圈。根因分析可能的原因有多个。服务器资源不足Harbor的多个组件特别是Trivy扫描器在首次启动或执行任务时会消耗较多CPU和内存。检查服务器资源使用情况top或htop。网络问题jobservice或trivy-adapter需要访问外网以下载漏洞数据库。如果服务器处于内网无外网环境且未配置离线漏洞库这些功能会失败。浏览器缓存或证书问题尝试清除浏览器缓存或检查浏览器是否因为自签名证书而阻止了部分脚本加载虽然能访问但可能拦截了API请求。解决方案确保服务器至少有4GB可用内存。对于资源紧张的环境可以在harbor.yml中调低jobservice.max_job_workers和关闭暂时不需要的功能如trivy.skip_update: true。对于无外网环境必须为Trivy配置离线漏洞库具体请参考Harbor官方文档中“离线安装”部分。对于自签名证书确保在浏览器中访问时点击“高级”-“继续前往”以完全信任该站点而不是仅仅忽略一次警告。5. 集成到CI/CD流水线让Jenkins自动推送镜像安装好Harbor只是第一步让它融入你的自动化流程才是价值所在。这里以最经典的Jenkins为例展示如何配置一个简单的流水线在代码构建成功后自动将Docker镜像推送到Harbor。5.1 在Harbor中创建机器人账户为了安全我们不建议在Jenkins中使用管理员账号。Harbor提供了“机器人账户”功能专门用于API调用。管理员登录Harbor Web UI。进入目标项目如ci-cd-project。点击“机器人账户” - “新建机器人账户”。设置名称如jenkins-robot选择权限至少需要“推送”权限设置过期时间。创建成功后务必立即复制并保存生成的Token。这个Token只显示一次用于Jenkins的凭证配置。5.2 在Jenkins中配置凭证进入Jenkins管理界面 - “管理凭证” - “全局凭证” - “添加凭证”。选择类型为“Username with password”。用户名填写你创建的机器人账户名例如robot$jenkins-robot注意格式robot$是前缀。密码栏粘贴上一步复制的Token。给这个凭证设置一个ID例如harbor-robot-credential。5.3 编写Jenkins Pipeline脚本以下是一个简化的Jenkinsfile示例它完成了代码拉取、构建、打Tag、推送镜像到Harbor的全过程。pipeline { agent any // 指定一个具有Docker环境的agent environment { // 定义环境变量 HARBOR_HOST harbor.yourcompany.com HARBOR_PROJECT ci-cd-project IMAGE_NAME my-springboot-app // 使用上一步创建的凭证ID HARBOR_CREDENTIALS_ID harbor-robot-credential } stages { stage(Checkout) { steps { // 从Git仓库拉取代码 git branch: main, url: https://your-git-repo.com/your-project.git } } stage(Build Test) { steps { script { // 这里根据你的项目进行编译和测试例如Maven sh mvn clean package } } } stage(Build Docker Image) { steps { script { // 读取pom.xml中的版本号或使用Jenkins构建号作为镜像标签 def version sh(script: mvn help:evaluate -Dexpressionproject.version -q -DforceStdout, returnStdout: true).trim() def imageTag ${HARBOR_HOST}/${HARBOR_PROJECT}/${IMAGE_NAME}:${version}-${env.BUILD_NUMBER} // 构建Docker镜像 docker.build(imageTag) } } } stage(Push to Harbor) { steps { script { def version sh(script: mvn help:evaluate -Dexpressionproject.version -q -DforceStdout, returnStdout: true).trim() def imageTag ${HARBOR_HOST}/${HARBOR_PROJECT}/${IMAGE_NAME}:${version}-${env.BUILD_NUMBER} // 使用withCredentials包装安全地使用Harbor凭证登录 withCredentials([usernamePassword(credentialsId: env.HARBOR_CREDENTIALS_ID, passwordVariable: HARBOR_PASSWORD, usernameVariable: HARBOR_USERNAME)]) { // 登录到Harbor仓库 sh echo ${HARBOR_PASSWORD} | docker login ${HARBOR_HOST} -u ${HARBOR_USERNAME} --password-stdin // 推送镜像 sh docker push ${imageTag} // 可选推送完成后登出 sh docker logout ${HARBOR_HOST} } } } } } post { always { // 清理工作空间避免磁盘空间占用 cleanWs() } } }5.4 关键点与经验分享标签策略示例中使用了“项目版本构建号”作为标签这能清晰追溯每次构建对应的代码版本。在生产中你可能会对通过所有测试的镜像打上latest或stable标签。凭证安全务必使用withCredentials将凭证注入到执行步骤中避免在日志中泄露Token。镜像清理流水线运行后会在Jenkins agent上留下构建的镜像。可以在post阶段添加sh ‘docker image prune -f’来清理未使用的镜像释放磁盘空间。Harbor Webhook你还可以在Harbor项目中配置Webhook当有新的镜像被推送时自动触发后续的部署流程例如通知Kubernetes进行更新。这实现了从CI到CD的完整衔接。6. 生产环境进阶考量与维护建议当Harbor开始承载核心业务镜像后以下几个方面的考虑就变得至关重要。6.1 高可用与灾备部署单节点部署存在单点故障风险。Harbor支持高可用部署通常有两种模式多副本部署通过Kubernetes Helm Chart这是官方推荐的生产部署方式。通过Helm将Harbor部署在K8s集群上并配置多个副本可以实现服务层面的高可用。同时需要配套使用高可用的外部PostgreSQL数据库、Redis集群以及共享存储如S3、Ceph。主从复制模式如果你有多数据中心需求可以利用Harbor强大的镜像复制功能。在一个中心站点部署主Harbor在其他站点部署从Harbor并配置策略将特定项目的镜像自动异步复制到从站点。这既能实现灾备也能让不同地域的团队就近拉取镜像提升速度。6.2 存储空间管理与垃圾回收镜像仓库是“空间吞噬兽”。必须定期清理无用镜像否则磁盘很快会被占满。设置保留策略在Harbor项目的“策略”中可以设置“标签保留规则”。例如只保留最近10个“latest”标签的镜像或者自动清理7天前的临时构建镜像。这能从源头控制镜像数量。手动垃圾回收删除镜像在Harbor UI中删除实际上只是删除了元数据标签物理存储层registry的二进制数据并未立即释放。需要执行垃圾回收来清理这些“悬空”的Blob。操作步骤在Harbor UI中进入“系统管理” - “垃圾回收” - “立即执行”。重要警告垃圾回收期间registry会进入只读模式所有镜像推送和拉取操作将会被阻塞。务必在业务低峰期进行并提前通知团队。监控磁盘使用率建立对Harbor数据卷/data或你配置的外部存储的磁盘监控告警提前预警。6.3 安全加固实践启用内容信任NotaryHarbor集成了Notary可以对镜像进行签名和验证。确保只有被可信发布者签名的镜像才能被拉取防止中间人攻击或仓库被污染。强制扫描策略在项目配置中可以设置“自动扫描镜像”以及“阻止未扫描/高危漏洞的镜像运行”。这能将安全左移避免有漏洞的镜像流入生产环境。定期升级关注Harbor的安全公告和版本更新及时修补漏洞。升级前务必在测试环境充分验证并备份数据库和镜像数据。审计日志Harbor详细记录了所有用户操作推送、拉取、删除、登录等。定期审查审计日志有助于发现异常行为和安全事件追溯。从一台裸机到建立起一个稳定、安全、支撑着整个团队CI/CD流程的Harbor服务这个过程本身就是一个典型的DevOps实践。它不仅仅是运行几个容器更涉及到架构规划、网络配置、安全策略和运维流程的方方面面。