ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

企业级私有Docker镜像仓库搭建指南:从Harbor部署到生产运维

企业级私有Docker镜像仓库搭建指南:从Harbor部署到生产运维

1. 项目概述:为什么需要一个私有的Docker Registry?

在容器化开发和部署的日常工作中,我们频繁地与Docker Hub这样的公共镜像仓库打交道。docker pull ubuntu:latestdocker pull nginx这样的命令早已成为肌肉记忆。然而,当项目进入深水区,特别是涉及到企业级应用、专有软件或对安全、速度有更高要求的场景时,公共仓库的局限性就暴露无遗。镜像拉取速度受制于网络,敏感的商业代码或算法模型镜像绝不可能上传到公共空间,团队内部共享测试镜像也颇为不便。这时,搭建一个私有Docker Registry,就从一个“可选项”变成了“必选项”。

私有Registry,简单说,就是你自己搭建和维护的一个Docker镜像仓库服务器。它完全由你掌控,部署在内网或你信任的云服务器上。你可以把团队开发的应用镜像、基础环境镜像、甚至是第三方镜像的定制版本,安全地推送到这个私有仓库中。后续的持续集成(CI)流水线、测试环境、生产环境,都从这个私有仓库拉取镜像,整个过程高效、安全、可控。这不仅仅是技术上的隔离,更是研发流程规范化、资产私有化的重要一步。无论是三五人的小团队,还是上百人的研发部门,一个稳定可靠的私有Registry都是容器化架构中不可或缺的基础设施。

2. 核心需求与方案选型

在动手搭建之前,我们需要明确自己的核心需求,这直接决定了技术方案的选择。一个私有Registry并非只有一种形态,从最简单的单机版到功能完备的企业级方案,差异巨大。

2.1 需求拆解:你需要什么样的Registry?

  1. 基础存储与分发:这是最核心的功能,能够通过标准的Docker API(v2)接收(push)和提供(pull)镜像。
  2. 身份认证(Authentication):谁可以推送?谁可以拉取?简单的场景可能只需要HTTP基本认证,复杂的则需要集成LDAP、OAuth2等。
  3. 访问控制(Authorization):认证之后,用户/系统能对哪些镜像仓库(项目)进行操作?是只读、读写还是管理员权限?
  4. 用户界面(WebUI):提供一个图形化界面来浏览镜像、查看标签、管理仓库,对于非命令行用户或管理者非常友好。
  5. 漏洞扫描(Vulnerability Scanning):自动扫描镜像中的操作系统和应用程序依赖,识别已知的安全漏洞(CVE)。
  6. 镜像复制(Replication):在多数据中心或混合云场景下,将镜像从一个Registry同步到另一个,保证环境一致性。
  7. 高可用与持久化:Registry服务本身无状态,但存储的镜像数据(Blobs)和元数据(Manifests)必须持久化。生产环境需要保证服务的高可用性。

2.2 方案对比:从Registry到Harbor

面对这些需求,社区和业界提供了不同层次的解决方案:

  • Docker Distribution (Registry:2):这是Docker官方提供的、最基础的镜像仓库实现。它非常轻量,只解决了最核心的“存储与分发”问题。认证、UI、扫描等高级功能都需要你自己通过组合其他工具(如Nginx做反向代理和认证)来实现,适合极简场景或作为学习入门。
  • Harbor:由VMware(现为Broadcom)开源,是目前最流行、功能最全面的企业级私有Registry解决方案。它在Docker Distribution的基础上,原生集成了基于角色的访问控制(RBAC)、精美的WebUI、漏洞扫描、镜像复制、日志审计、Helm Chart仓库等一系列企业级功能。它像是一个“开箱即用”的完整产品,极大地降低了运维复杂度。

选型结论:对于绝大多数寻求搭建私有Registry的团队,尤其是希望获得完整管理能力、安全特性和良好用户体验的,Harbor是毫无疑问的首选。它通过容器化部署,本身也极其方便。因此,本记录将重点围绕Harbor的搭建展开,这涵盖了私有Registry搭建的绝大多数核心实践。

3. 环境准备与前置条件

在启动Harbor容器之前,我们需要确保宿主机环境满足要求。这里以一台干净的Linux服务器(如Ubuntu 22.04 LTS)为例。

3.1 系统与依赖检查

首先,更新系统并安装必要的工具:

sudo apt update && sudo apt upgrade -y sudo apt install -y curl wget git vim

关键依赖:Docker与Docker ComposeHarbor本身以容器形式运行,因此Docker引擎是必须的。同时,Harbor使用docker-compose来编排和管理多个服务容器(如核心Registry、数据库、UI、JobService等)。

  1. 安装Docker Engine

    # 卸载旧版本 sudo apt remove docker docker-engine docker.io containerd runc # 设置仓库 sudo apt install -y ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 安装Docker sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # 启动并设置开机自启 sudo systemctl enable docker sudo systemctl start docker # 将当前用户加入docker组,避免每次使用sudo sudo usermod -aG docker $USER # 注意:需要重新登录或执行 `newgrp docker` 使组生效
  2. 安装Docker Compose独立版本: 虽然Docker Desktop包含了Compose,但在Linux服务器上,我们通常安装独立的docker-compose二进制文件。Harbor的安装脚本需要调用docker-compose命令。

    # 下载特定版本,这里以v2.24.5为例 sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose # 赋予执行权限 sudo chmod +x /usr/local/bin/docker-compose # 验证安装 docker-compose --version

3.2 规划存储与网络

  • 存储路径:Harbor的数据(镜像文件、数据库、配置文件)默认会存储在/data目录下。你需要确保该路径有足够的磁盘空间(建议至少100GB,视镜像数量而定)。你也可以在配置中修改这个路径。
  • 网络与防火墙:Harbor默认监听80(HTTP)和443(HTTPS)端口。确保服务器的防火墙(如ufwfirewalld)开放了这些端口,并且外部网络能够访问到服务器的IP或域名。
    # 如果使用ufw sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw reload
  • 域名与SSL证书(强烈推荐):在生产环境,务必使用HTTPS。你需要一个域名(例如harbor.yourcompany.com)和对应的SSL证书(可以是来自Let‘s Encrypt的免费证书,或企业购买的证书)。Harbor支持自动生成自签名证书,但仅适用于测试环境,客户端需要额外配置信任该证书,较为麻烦。

4. Harbor安装与配置详解

一切准备就绪,现在开始安装Harbor。我们将采用离线安装包的方式,这样更稳定,不依赖外网。

4.1 下载与解压Harbor

  1. 访问Harbor的GitHub Releases页面(例如https://github.com/goharbor/harbor/releases),找到最新的稳定版本。本文以v2.10.0为例。
  2. 下载离线安装包和对应的校验文件。
    cd /tmp wget https://github.com/goharbor/harbor/releases/download/v2.10.0/harbor-offline-installer-v2.10.0.tgz wget https://github.com/goharbor/harbor/releases/download/v2.10.0/harbor-offline-installer-v2.10.0.tgz.sha256sum # 校验文件完整性 sha256sum -c harbor-offline-installer-v2.10.0.tgz.sha256sum
  3. 解压到安装目录,例如/opt
    sudo tar xzf harbor-offline-installer-v2.10.0.tgz -C /opt cd /opt/harbor

4.2 关键配置文件harbor.yml

Harbor的所有配置都集中在harbor.yml文件中。首次安装时,需要复制模板并修改。

sudo cp harbor.yml.tmpl harbor.yml sudo vim harbor.yml

下面是最关键的一些配置项,你需要根据实际情况修改:

# 主机名:必须设置为访问Harbor的域名或IP。这是最重要的配置! hostname: harbor.yourcompany.com # 或你的服务器IP,如 192.168.1.100 # HTTP相关配置(生产环境建议关闭HTTP,只使用HTTPS) http: port: 80 # HTTPS相关配置(生产环境必须启用) https: port: 443 # 你的证书和私钥的路径 certificate: /your/certificate/path/harbor.yourcompany.com.crt private_key: /your/private/key/path/harbor.yourcompany.com.key # Harbor管理员初始密码。首次登录后请立即修改! harbor_admin_password: Harbor12345 # 数据持久化目录 data_volume: /data # 数据库配置(通常使用内部PostgreSQL,无需修改,除非你有外部数据库) database: password: root123 max_idle_conns: 50 max_open_conns: 100 # 数据表清理作业的周期(默认每天凌晨2点) jobservice: max_job_workers: 10 # 通知(可选,可集成邮件、Webhook等) notification: webhook_job_max_retry: 10 # 日志级别 log: level: info local: rotate_count: 50 rotate_size: 200M location: /var/log/harbor # 版本控制(默认false,如果从旧版升级,需设置为true) _version: 2.10.0

重要提示hostname配置至关重要。客户端(Docker Daemon)在登录和推送/拉取镜像时,会使用这个主机名来访问Harbor。如果这里填IP,客户端就必须用IP;如果填域名,客户端必须能解析这个域名。配置错误会导致客户端无法认证或操作镜像。

4.3 执行安装脚本

配置好harbor.yml后,运行安装脚本。脚本会解析配置文件,拉取必要的Docker镜像,并启动所有服务。

sudo ./install.sh

如果一切顺利,你将看到类似✔ ----Harbor has been installed and started successfully.----的输出。

安装完成后,Harbor的所有服务(nginx, portal, core, jobservice, registry, redis, database等)都会以容器的形式运行。你可以通过sudo docker-compose ps命令查看所有容器的状态。

5. 初始化访问与基础管理

安装成功后,打开浏览器,访问你配置的地址(如https://harbor.yourcompany.com)。由于是自签名证书或首次访问,浏览器可能会提示安全风险,选择继续访问即可。

5.1 首次登录与修改密码

  1. 使用默认用户名admin和你在harbor.yml中配置的harbor_admin_password(例如Harbor12345)登录。
  2. 登录后第一件事:立即在右上角用户菜单中修改管理员密码!这是最基本的安全要求。

5.2 创建项目与用户

Harbor的核心组织单元是“项目”(Project)。镜像仓库(Repository)隶属于项目。通常,我们会为不同的团队或产品线创建不同的项目。

  1. 创建项目

    • 点击“项目” -> “新建项目”。
    • 输入项目名称,例如backend-team
    • “访问级别”选择“公开”或“私有”。公开项目,所有用户(包括未登录的)都可以拉取镜像;私有项目,只有项目成员才能拉取。
    • 勾选“启用内容信任”和“自动扫描镜像”可以根据安全需求选择。
  2. 创建用户与分配权限

    • 点击“系统管理” -> “用户管理” -> “新建用户”。
    • 填写用户名、邮箱、密码等信息。
    • 创建用户后,进入具体的项目(如backend-team),点击“成员” -> “+用户”,将用户添加进来,并赋予相应的角色(如“项目管理员”、“开发人员”、“访客”)。
    • “开发人员”可以推送和拉取镜像,“访客”只能拉取,“项目管理员”拥有项目的全部管理权限。

6. 客户端配置与日常使用

服务器端搭建好了,现在需要让开发机器或CI服务器能够使用这个私有仓库。

6.1 配置Docker Daemon信任私有仓库

由于我们使用了自签名证书(或在测试时用了HTTP),Docker Daemon默认不信任这样的仓库,需要在客户端进行配置。

对于使用HTTPS(自签名证书)的情况

  1. 将Harbor服务器上的CA证书(或你的自签名证书)拷贝到客户端机器的信任目录。
    # 在Harbor服务器上,证书通常在 /data/cert/ 或你配置的路径下 # 假设证书文件是 harbor.yourcompany.com.crt # 将其拷贝到客户端,例如 /usr/local/share/ca-certificates/ sudo cp harbor.yourcompany.com.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates
  2. 告诉Docker Daemon信任这个仓库。编辑/etc/docker/daemon.json文件(如果不存在则创建)。
    { "insecure-registries": [], "registry-mirrors": [], "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2" }
    关键点:如果你使用的是企业CA签发的证书或Let‘s Encrypt证书,Docker默认是信任的,无需将仓库添加到insecure-registries。只有使用自签名证书时,才需要添加。但更推荐的做法是正确部署受信任的证书,避免使用insecure-registries,这是一个安全风险。

对于测试环境使用HTTP的情况(不推荐): 必须在daemon.json中明确声明该仓库为不安全。

{ "insecure-registries": ["harbor.yourcompany.com:80", "192.168.1.100:80"] }

修改后,重启Docker服务:

sudo systemctl restart docker

6.2 登录、推送与拉取镜像

  1. 登录到私有仓库

    docker login harbor.yourcompany.com # 输入你在Harbor创建的用户名和密码

    登录成功后,凭证会保存在~/.docker/config.json中。

  2. 给本地镜像打标签: Docker镜像的完整名称格式为仓库地址/项目名/镜像名:标签

    # 假设我们有一个本地镜像叫 my-app:v1.0 docker tag my-app:v1.0 harbor.yourcompany.com/backend-team/my-app:v1.0
  3. 推送镜像到私有仓库

    docker push harbor.yourcompany.com/backend-team/my-app:v1.0

    推送时,Harbor会自动在backend-team项目下创建名为my-app的仓库。

  4. 从私有仓库拉取镜像

    docker pull harbor.yourcompany.com/backend-team/my-app:v1.0
  5. 在WebUI中查看: 刷新Harbor的Web界面,进入backend-team项目,你就能看到刚刚推送的my-app仓库及其v1.0标签。

7. 进阶配置与运维要点

基础功能跑通后,为了满足生产要求,还需要关注以下方面。

7.1 启用内容信任(Notary)

内容信任(Docker Content Trust, DCT)机制允许对镜像标签进行数字签名,确保拉取的镜像来自可信的发布者,且未被篡改。Harbor集成了Notary服务来提供此功能。

  1. 在项目设置中启用“内容信任”。
  2. 推送镜像时,客户端需要设置环境变量DOCKER_CONTENT_TRUST=1
    export DOCKER_CONTENT_TRUST=1 export DOCKER_CONTENT_TRUST_SERVER=https://harbor.yourcompany.com:4443 docker push harbor.yourcompany.com/backend-team/my-app:signed-v1.0
    首次使用会生成本地密钥。启用后,拉取未签名的标签将会失败。

7.2 配置漏洞扫描

Harbor集成了Trivy、Clair等扫描器。以Trivy为例(默认集成):

  1. 在“系统管理” -> “漏洞扫描器”中,确保Trivy扫描器是“启用”状态。
  2. 在项目或仓库级别,可以配置“自动扫描”:每当有新的镜像被推送时,自动触发漏洞扫描。
  3. 扫描完成后,在镜像详情页可以看到漏洞列表,按照严重级别(Critical, High, Medium, Low)分类,并给出修复建议。

7.3 配置镜像复制

如果你有多个Harbor实例(例如北京和上海机房),或者需要将镜像同步到公有云仓库,可以使用复制功能。

  1. 在“系统管理” -> “注册表管理”中,新建一个目标注册表(另一个Harbor实例或Docker Hub等)。
  2. 在“复制管理”中,新建复制规则。选择源项目、目标注册表和目标项目,并选择触发的资源(如所有镜像,或带特定标签的镜像)和触发方式(手动、定时、事件驱动)。

7.4 备份与恢复

Harbor的数据包括:

  • 镜像文件:存储在配置的data_volume目录下的registry目录中。
  • 数据库:存储在database容器卷中,对应data_volume下的database目录。
  • 配置文件:就是你的harbor.yml

备份步骤

  1. 停止Harbor服务:cd /opt/harbor && sudo docker-compose down
  2. 备份整个数据目录和配置文件:
    sudo tar czf harbor-backup-$(date +%Y%m%d).tar.gz /data /opt/harbor/harbor.yml
  3. 启动Harbor服务:sudo docker-compose up -d

恢复步骤

  1. 停止Harbor服务。
  2. 将备份文件解压到原路径。
  3. 运行Harbor的准备工作脚本(会恢复数据库结构等):sudo ./prepare
  4. 启动Harbor服务。

8. 常见问题与故障排查实录

在实际搭建和运维过程中,你几乎一定会遇到下面这些问题。这里记录了我的踩坑实录和解决方法。

8.1 客户端登录失败:Error response from daemon: Get “https://harbor.yourcompany.com/v2/“: x509: certificate signed by unknown authority

问题:Docker客户端不信任Harbor服务器的SSL证书。排查

  1. 确认你访问的地址(harbor.yourcompany.com)与harbor.yml中的hostname完全一致。
  2. 确认证书是否正确部署。可以尝试用curl -v https://harbor.yourcompany.com检查证书链。解决
  • 方案一(推荐,生产环境):为你的域名申请一个受信任的CA签发的证书(如Let‘s Encrypt免费证书),并正确配置到Harbor和Nginx。
  • 方案二(测试环境):将Harbor的CA证书(或自签名证书)添加到客户端的系统信任链,并重启Docker,如前文6.1节所述。切勿在生产环境使用insecure-registries绕过证书验证

8.2 推送镜像失败:denied: requested access to the resource is denied

问题:权限不足。排查

  1. 是否已执行docker login?用cat ~/.docker/config.json查看当前登录状态。
  2. 登录的用户是否有目标项目的推送权限?例如,用户可能只是“访客”角色。
  3. 镜像的标签格式是否正确?必须是仓库地址/项目名/镜像名:标签。项目名必须存在且用户有权限。解决
  4. 重新登录:docker logout harbor.yourcompany.com && docker login harbor.yourcompany.com
  5. 在Harbor WebUI中,检查该用户是否在目标项目中,并且角色是“开发人员”或“项目管理员”。

8.3 Harbor服务启动失败:docker-compose up报错,特别是数据库相关

问题:可能是之前的安装残留或配置文件错误。排查

  1. 查看具体容器的日志:sudo docker-compose logs -f [服务名,如 core, database]
  2. 常见错误是数据库连接失败或初始化失败。解决
  3. 彻底清理旧数据(危险操作,会删除所有镜像和配置!仅用于测试环境重装):
    cd /opt/harbor sudo docker-compose down -v # -v 会删除数据卷 sudo rm -rf /data/database /data/registry /data/redis ...
  4. 再次检查harbor.yml配置文件,特别是hostname和数据库密码。
  5. 重新运行sudo ./install.sh

8.4 磁盘空间不足

问题:随着镜像增多,/data目录所在磁盘被占满。排查:使用df -hdu -sh /data/*查看磁盘使用情况。解决

  1. 清理无用镜像:在Harbor WebUI中,可以手动删除不再需要的镜像标签。Harbor的“垃圾回收”功能可以清理未被任何标签引用的镜像层(Blobs)。
  2. 设置保留策略:在项目配置中,可以设置“标签保留规则”,自动清理早于一定天数的标签。
  3. 扩容存储:规划初期就应为/data目录挂载大容量存储,或使用网络存储(如NFS、Ceph)。Harbor支持配置外部存储(如S3、Azure Blob、Swift、Google Cloud Storage),这是生产环境的最佳实践,需要在harbor.yml中配置storage_service部分。

8.5 WebUI访问缓慢或无法加载

问题:可能是浏览器缓存、前端资源加载问题,或后端服务异常。排查

  1. 检查所有容器是否正常运行:sudo docker-compose ps。查看状态是否为Up
  2. 检查coreportal服务的日志。解决
  3. 清除浏览器缓存,或使用无痕模式访问。
  4. 重启Harbor服务:cd /opt/harbor && sudo docker-compose restart
  5. 如果问题持续,检查服务器资源(CPU、内存)是否充足。Harbor在镜像推送/拉取高峰时,对资源有一定消耗。

搭建和维护一个高可用的私有Docker Registry,特别是像Harbor这样的成熟方案,远不止是运行几条安装命令。它涉及到网络、存储、安全、权限和日常运维的方方面面。从最初的单机测试,到最终承载整个公司的容器镜像流转,这个过程让我深刻体会到,基础设施的稳定性和易用性,是研发效能的一块基石。把镜像仓库这件“小事”做扎实了,后续的CI/CD、自动化部署、环境治理才会顺畅。如果你在搭建过程中遇到了上面没覆盖到的问题,我的建议永远是:第一时间查看日志docker-compose logs是你最好的朋友,它能告诉你服务内部究竟发生了什么。

返回列表