news 2026/10/23 3:44:09

Harbor 私有镜像仓库安装:Ubuntu 全版本实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Harbor 私有镜像仓库安装:Ubuntu 全版本实战指南

1. Harbor是什么?为什么值得装

Harbor是一个开源的容器镜像仓库,它不只是“私有的Docker Registry”,而是在Registry之上做了一整套企业级能力:基于角色的访问控制(RBAC)、镜像漏洞扫描、镜像复制同步、回收策略、审计日志、Web端图形化管理界面。说白了,如果你所在的团队或公司需要一套靠谱的私有镜像仓库,Harbor基本是首选。

在过去几年里,我前前后后在Ubuntu 18.04、20.04、22.04上装过不下十次Harbor,覆盖的场景很杂:有小团队内部几个人用的轻量环境,也有要把镜像推到机房多台机器做生产发布的正式环境。表面上看装Harbor就是下载离线包、改个配置、跑一下install.sh,但实际操作中版本差异、网络环境、Docker Compose的版本坑,还有HTTPS自签证书的问题,任何一个环节没处理好都可能卡一整天。

这篇博文把所有经验做一个汇总,直接从零开始,把三个Ubuntu版本下装Harbor的完整流程、配置细节、踩坑点全部拆开讲。不管你用的是老旧的18.04,还是主流的20.04,或者刚换上来的22.04,按我这个流程走一遍基本都能跑通。

2. 安装前的整体规划

2.1 Harbor的核心组件与运行架构

在动手安装之前,先搞清楚Harbor装完之后系统里会多出什么东西,这对后续排查问题很有帮助。Harbor本身不是一个大而全的单体程序,而是通过Docker Compose拉起一组容器来协作。

以Harbor 2.x版本为例,安装完成后默认会运行的容器包括:

组件作用
nginx前端反向代理,统一入口,负责HTTPS/HTTP转发
harbor-core核心API服务,处理认证、权限、项目管理
harbor-db后端数据库,基于PostgreSQL,存元数据
harbor-portalWeb前端页面
harbor-jobservice执行异步任务,比如镜像复制、配额回收
registry真正存储镜像的Docker Registry,支持多种存储后端
harbor-registryctl管理registry配置和生命周期
harbor-log统一日志收集

Harbor 2.4以后的版本还会多出几个,比如harbor-exporter用来暴露Prometheus监控指标,但核心逻辑不变。理解这一点之后,如果你发现某个功能不正常,能很快判断是哪个容器出问题了。

另外值得一提的存储逻辑:Harbor默认把镜像数据存在宿主机磁盘的/data目录下,数据库也在/data/database里面。这意味着如果你的磁盘没规划好,很可能装的时候没问题,跑一段时间后反而因为镜像越来越多把分区撑满,那是后话,但规划时就得想到。

2.2 硬件和系统要求参考

Harbor官方文档给的最低配置是2核4G,但这只是“能跑”,实际用起来会比较吃力。以我的经验,三个环境尺寸可以参考:

  • 小团队内部测试(几个人用):2核4G,40G磁盘,够用但别忘了监控磁盘占用;
  • 中等规模团队(几十人日常构建推送):4核8G,100G以上磁盘,建议盘和数据目录不落在系统盘;
  • 生产级(有大量镜像、频繁拉取):8核16G,根据镜像增长情况规划存储,最好给/data单独挂一块盘。

我推荐新手初期用2核4G起步,但把/data规划到一块独立的硬盘或云盘上。做镜像仓库最怕的事就是“数据把系统盘撑满”,到时候连日志都写不进去,排查起来非常难受。

2.3 三个Ubuntu版本的关键差异

很多人问:Ubuntu 18.04、20.04、22.04装Harbor到底有区别吗?直接说结论:区别不大,安装步骤大同小异,真正有差异的集中在两点——系统自带软件源和Docker Compose的获取方式。

  • Ubuntu 18.04:系统较老,自带gcc、make这些包版本偏低,但装Docker和跑Harbor完全没影响。需要注意18.04的apt源如果使用的是旧地址可能出现404,装之前先确认软件源可用。
  • Ubuntu 20.04:最省心的版本,按常规流程走就行,绝大多数教程默认就是它。
  • Ubuntu 22.04:系统自带较新的OpenSSL和一些库,装Docker时建议直接用Docker官方源,不要用Ubuntu自带源,否则版本较旧且缺少一些修复补丁。另外22.04默认安装的是iptables-nft,Docker的兼容性没问题,但如果你系统里同时装了firewalld或ufw,需要注意网段转发冲突。

内核和存储驱动方面,三个版本我都建议使用overlay2驱动,Ubuntu 20.04及以后版本默认就是overlay2,18.04如果发现Docker还在用aufs,建议改掉。

3. 系统环境准备

3.1 更新软件源和基础依赖

不管哪个版本的Ubuntu,装之前先把系统基础环境收拾干净。更新源是所有步骤里最不容易出错的,但也是很多人会忽略的,特别是18.04的老源问题,改完源不update就装,很容易装到一半报依赖错误。

依次执行以下命令:

sudo apt update && sudo apt upgrade -y

这一步会比较慢,取决于网络状况,耐心等它跑完。升级完成后安装常用工具:

sudo apt install -y curl wget vim net-tools ca-certificates gnupg lsb-release

这里有一个实测经验:ca-certificates和gnupg一定要装,尤其后面要用官方源安装Docker时,没有gnupg会导致添加GPG密钥时无法导入。

注意18.04的系统如果之前被人改过apt源,可能update时会报错,这时候直接编辑/etc/apt/sources.list,把里面的地址换成可用的镜像源(国内环境一般用阿里云或清华源),再重新update。

3.2 关闭交换分区与防火墙策略

Harbor里的PostgreSQL对内存需求相对平稳,一般不强制关swap,但当系统物理内存小于4G时,swap被频繁使用会导致性能断崖式下跌,所以建议4G内存以下的环境把swap关掉或者调低swappiness:

# 临时调整 sudo sysctl vm.swappiness=10 # 永久生效,编辑 /etc/sysctl.conf,添加: vm.swappiness=10

防火墙策略视情况而定。如果你用的是云服务器,安全组需要在控制台放通80(或443)端口;如果用的是本机或内网虚拟机,建议直接关闭防火墙方便排查:

sudo ufw disable sudo systemctl stop firewalld 2>/dev/null || true

这里特别提醒一点:Harbor安装完成之后,网页无法访问并不一定都是防火墙的问题,也可能是Harbor网关没起来。所以排查顺序是先看Docker容器状态,再查防火墙,不要一上来就操作防火墙规则。

3.3 规划数据目录

Harbor默认的data目录是/data,我个人的习惯是不改这个默认值,因为它写死在很多配置里,改了容易漏。但/data的分区需要提前规划好,比如你现在根目录空间紧张,那么可以在另一个盘或分区建目录,然后做一个软链接:

# 假设 /mnt/harbor-data 是一块单独挂载的大容量分区 sudo mkdir -p /mnt/harbor-data sudo ln -s /mnt/harbor-data /data

软链接的方式比直接改harbor.yml里的data_volume字段更稳妥,因为你不需要关心配置里到底哪里引用了/data路径,底层全给你转过去了。

4. 安装Docker和Docker Compose

4.1 Docker安装(三个版本通用方案)

三个Ubuntu版本都可以用Docker官方源安装,步骤基本一致,保持命令统一:

# 添加Docker官方GPG密钥 sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg # 添加Docker仓库 echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

Docker Compose插件在20.04和22.04上可以直接用docker compose命令,但Harbor官方脚本在2.6版本以前依赖的是docker-compose(带横杠的那个老版本),所以建议把compose插件和不带版本号的docker-compose都装上:

sudo apt install -y docker-compose-plugin sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose 2>/dev/null || true

18.04的老环境有一个常见的坑:lsb_release -cs返回的是bionic,而Docker官方源对bionic的支持一直没有停止,所以走这条路没问题。但如果你的18.04是精简版,连lsb-release都没有,那先装一下lsb-release再继续。

4.2 Docker Compose的版本检查

Harbor 2.x要求Docker Compose版本最好不低于1.29,低于这个版本跑install.sh时可能直接报错。装完先验证一下:

docker-compose --version

如果系统之前装过很老的compose(比如1.24甚至更早),建议先卸载干净再装新版本:

sudo rm /usr/local/bin/docker-compose /usr/bin/docker-compose 2>/dev/null

新版compose插件安装后,Docker Compose的调用路径是/usr/libexec/docker/cli-plugins/docker-compose,而老版本习惯是/usr/local/bin/docker-compose。Harbor的脚本调用docker-compose时是直接查PATH的,所以最稳妥的做法是把任何能找到的docker-compose二进制都检查一遍,确保版本正确,别让它混着旧版用。

4.3 配置Docker加速与系统参数

国内环境拉取镜像时经常遇到超时问题,但Harbor安装包里的镜像一般都在安装包里,离线安装不会受影响。不过如果你的网络情况特殊,或者后面要手动拉一些额外的镜像,这时候Docker加速就派得上用场。

编辑/etc/docker/daemon.json:

{ "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" } }

修改完重启Docker:

sudo systemctl restart docker sudo systemctl enable docker

把Docker设置为开机自启这一点很关键,很多人装完Harbor重启机器后又忘了这点,结果Docker没起来,Harbor里的容器全部处于停止状态,网页自然无法访问。另外,日志限制我建议加上,不然Harbor容器经常打日志,占满/var/lib/docker所在分区只是时间问题。

5. Harbor安装包下载与离线安装

5.1 为什么推荐离线安装包

Harbor的安装包有两种:在线安装器和离线安装器。在线安装器会从Docker Hub拉取镜像,国内网络环境下载速度不稳定,而且中途断网会导致安装失败,浪费时间。所以我一直推荐使用离线安装包(harbor-offline-installer-v2.x.tgz)。

离线包体积较大,一般2.5版本大约在600MB到1GB之间,但是下载完成后安装过程就基本不受外网影响了,所有的Harbor组件镜像都已经被打包在tar包里,install.sh执行时会把镜像挨个load进去。

下载地址在Harbor的GitHub Releases页面,选择对应版本号,下载文件名包含offline-installer的那个包。如果没有明确需求,直接用最新稳定版,比如2.10.x或者2.11.x。但如果你装了老版本Harbor要升级,注意不能跨大版本太远,建议先看官方升级文档。

5.2 解压与install.sh执行流程

# 下载后解压 tar zxf harbor-offline-installer-v2.11.0.tgz cd harbor

解压后目录里应该有一个harbor.yml.tmpl模板文件、install.sh脚本和common.sh等文件。首次安装前要先把模板复制为真正的配置文件:

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

编辑完成后保存,再执行:

sudo ./install.sh

install.sh有三个常用参数:

  • --with-trivy:启用镜像漏洞扫描功能
  • --with-notary:启用镜像签名功能(一般用不到)
  • --with-chartmuseum:启用Helm Chart仓库功能

大多数团队只需要加--with-trivy:

sudo ./install.sh --with-trivy

install.sh执行时间取决于机器性能,配置一般的机器可能需要3-5分钟,主要是加载镜像和初始化数据库。执行过程中不要中断,中断后再次执行脚本一般会基于半初始化状态继续,但如果数据库初始化出了问题,最简单的方法是把/data目录和所有容器清掉重新来。

5.3 验证安装结果

安装完成后,运行下面的命令检查容器状态:

docker ps

正常情况下能列出上述表格里的所有组件容器,状态都是Up。如果某个容器是Exit状态,后续排查常见问题那一节会讲怎么定位。

再用浏览器访问Harbor的Web界面,默认地址是http://服务器IP,注意默认端口是80,如果在harbor.yml里改了端口就用新端口访问。默认管理员账号是admin,初始密码在配置文件里由harbor_admin_password字段指定,我一般习惯至少设置成12位以上的强密码,避免生产环境被爆破。

6. harbor.yml核心配置深度解析

6.1 hostname和端口的选择

harbor.yml是整场安装里唯一的重点配置文件,把所有核心参数都敲定在这里。新手常犯的错误是拿到模板文件之后,觉得只要改几个地方就行,结果漏改或者改错导致后面出各种奇怪问题。

hostname: 192.168.1.100 http: port: 80 https: port: 443 certificate: /data/cert/server.crt private_key: /data/cert/server.key harbor_admin_password: Harbor12345 database: password: root123 data_volume: /data

先说hostname这个参数。它的值决定了Harbor Web界面里显示的访问地址,以及Docker客户端登录时要使用的地址。如果你在浏览器里直接用IP访问,那hostname填IP即可;如果你配置了域名,建议直接用完整的域名,比如harbor.example.com。

这里有个实践经验:如果你打算后续用域名访问,最好在/etc/hosts里把域名解析加到本机,不然Docker守护进程去解析域名时失败可能导致登录失败。

6.2 HTTP还是HTTPS

Harbor支持两种访问方式:HTTP和HTTPS。默认模板里https部分是注释掉的,如果不配置证书,Harbor会以纯HTTP方式运行,Docker客户端这时候需要额外配置insecure-registries才能登录。

我个人的建议是,即使在内网环境,也尽量启用HTTPS。理由有两个:一是Docker客户端访问HTTPS的仓库不需要额外配置insecure-registries,省事;二是如果后续要暴露到外网或者跨多个环境同步镜像,HTTPS能避免镜像传输被篡改的风险。

配置HTTPS需要提前准备好证书和私钥,证书路径和私钥路径都写在harbor.yml里,文件要放对位置并且权限正确,尤其是私钥,权限过宽时部分组件起不来。

6.3 密码与数据库配置

harbor_admin_password是Web管理员密码,安装完成后可以随时在网页上修改。database.password是PostgreSQL的密码,在安装时用于初始化数据库,这个密码写进配置后就不要随意更改了,否则数据库容器启动时认证会失败。

需要注意的是这些密码如果包含特殊符号,比如$、&、#,在harbor.yml的YAML解析里有可能会出问题,最好避开这些字符,或者将值用单引号包起来。实测下来我见过不止一个人因为密码里带了个$符号,安装时报database初始化失败,折腾半天才排查到。

6.4 存储路径与日志清理策略

data_volume决定所有持久化数据的存放位置,默认/data。如果你要改,一定注意后面所有相关路径跟着变。还可以配置logrotate相关的清理,但Harbor自己的日志目前主要靠Docker容器日志,建议结合第4.3节里的daemon.json配置做日志大小限制。

镜像存储的增长速度往往比你预想的快,尤其是团队持续做CI/CD构建的时候,一次构建推几个镜像上去,一个月凑几十GB很常见。建议安装完成后就打开Harbor网页的“镜像清理”功能,设置一个保留策略,比如保留最近10个标签或者镜像超过30天自动清理。配置好之后,jobservice会自动执行回收,不用人工干预。

7. Docker客户端配置与登录推送

7.1 HTTP仓库的insecure-registries配置

如果你没有配置HTTPS,而是使用纯HTTP访问Harbor,那么Docker客户端必须显式允许这个不安全的仓库地址,否则登录时会报:

Error response from daemon: Get "http://192.168.1.100/v2/": http: server gave HTTP response to HTTPS client

解决办法是编辑/etc/docker/daemon.json,添加insecure-registries:

{ "insecure-registries": ["192.168.1.100:80"] }

注意,如果你改了harbor.yml里的http.port为其他端口,比如10080,那么这里要写192.168.1.100:10080。

修改后重启Docker:

sudo systemctl restart docker

这一步和Harbor本身没有关系,需要理解的是:Docker守护进程在与Registry通信时,默认对所有地址都期望走HTTPS,只有明确列入了insecure-registries的HTTP地址才会被接受。所以这是一个纯粹的Docker客户端配置,不是Harbor的问题。

7.2 登录与推送命令

配置好之后,用下面的命令登录:

docker login 192.168.1.100

输入admin用户名和密码,登录成功后docker会把凭证保存在~/.docker/config.json里。

然后随便打一个标签推上去测试:

docker tag nginx:latest 192.168.1.100/library/nginx:latest docker push 192.168.1.100/library/nginx:latest

这里有一个标签规范的问题:Harbor的项目名在镜像地址里是路径的一部分。默认有一个library项目,相当于公共项目,推上去的任何成员都可以拉取。如果你自建了一个名为devops的项目,那推送地址就是:

docker tag 镜像名 192.168.1.100/devops/镜像名:标签 docker push 192.168.1.100/devops/镜像名:标签

很多刚接触Harbor的人在这里容易糊涂:为什么推不进去?是不是权限问题?其实多半就是没建项目,或者地址里缺了项目名。

7.3 多节点拉取的hosts配置

如果你有多台机器都要从这个Harbor拉镜像,那么每台机器的Docker配置里都要写对应的insecure-registries(如果是HTTP方式),或者把该机器的DNS解析到Harbor所在服务器。比如你的Harbor配置了域名harbor.example.com,那么所有客户端要么配DNS,要么在/etc/hosts里加一条:

192.168.1.100 harbor.example.com

可别小看这一步,我在实际项目里见过有人配好了insecure-registries但漏配hosts,结果Docker一直解析不了域名,登录报“cannot resolve host”,最后排查一圈发现就是hosts的问题。

8. 自签HTTPS证书的完整配置

8.1 生成CA和服务器证书

Harbor支持使用自签证书。自签证书的流程是:先生成一个CA根证书,再用这个CA给Harbor服务器签发一个证书。Docker客户端需要信任这个CA根证书,这样访问Harbor时才不会报证书错误。

首先生成CA根证书:

mkdir -p /data/cert && cd /data/cert openssl genrsa -out ca.key 4096 openssl req -new -x509 -days 3650 -key ca.key -out ca.crt \ -subj "/C=CN/ST=Beijing/L=Beijing/O=MyOrg/CN=harbor-ca"

再生成服务器私钥和证书签发请求(CSR):

openssl genrsa -out server.key 4096 openssl req -new -key server.key -out server.csr \ -subj "/C=CN/ST=Beijing/L=Beijing/O=MyOrg/CN=192.168.1.100"

这里的CN,如果是用IP访问就填IP,如果用域名访问就填域名。然后创建一个扩展文件server.ext:

subjectAltName = IP:192.168.1.100

如果域名访问,加一行DNS:域名:

subjectAltName = DNS:harbor.example.com, IP:192.168.1.100

最后用CA签发服务器证书:

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \ -out server.crt -days 3650 -extfile server.ext

证书有效期我一般设置10年,省得频繁续期。如果要做得更规范,可以只签3年然后到期自动续期,但内网环境10年完全可行。

8.2 把证书配置到harbor.yml

生成好证书后,修改harbor.yml:

https: port: 443 certificate: /data/cert/server.crt private_key: /data/cert/server.key

注意,http部分建议直接注释掉(用#号注释),只保留https部分。这样Harbor只监听443端口,Docker客户端不需要再配置insecure-registries,直接就能用:

docker login harbor.example.com

证书文件权限建议设置成600或644都可以,关键是Docker容器内运行的nginx进程需要读取到它。比如你可以看到容器里/usr/local/etc/harbor的证书文件,其实是从宿主机挂载进去的。如果权限不对,nginx容器会反复重启。

8.3 客户端信任自签CA

如果你在Docker客户端上直接登录,会发现仍然报错:

x509: certificate signed by unknown authority

这是因为客户端不认你的自签CA。解决办法是把CA根证书添加为系统信任:

Ubuntu客户端执行:

sudo cp /data/cert/ca.crt /usr/local/share/ca-certificates/harbor-ca.crt sudo update-ca-certificates

如果你是Mac环境,做法是双击ca.crt导入钥匙串并设置信任;Windows则是导入到“受信任的根证书颁发机构”。

Docker守护进程实际上用的是操作系统级的CA信任库,所以只要系统信任了自定义CA,docker login就不会报证书错误。如果你是在远程机器上登录,需要把ca.crt传到那台机器再执行同样操作。

9. Harbor开机自启与升级维护

9.1 使用systemd管理Harbor容器

Harbor本身没有提供systemd服务脚本,默认情况下重启操作系统后,Docker服务起来,但Harbor的容器不会自动启动。因为Docker服务有restart策略可以做补救,但最稳定的方式是为Harbor写一个systemd unit。

我习惯的做法是写一个简洁的systemd服务,保证Docker启动后再拉起Harbor容器。先创建一个服务文件:

sudo vim /etc/systemd/system/harbor.service

内容如下:

[Unit] Description=Harbor Container Service Requires=docker.service After=docker.service [Service] Type=oneshot RemainAfterExit=yes WorkingDirectory=/opt/harbor ExecStart=/usr/local/bin/docker-compose -f /opt/harbor/docker-compose.yml up -d ExecStop=/usr/local/bin/docker-compose -f /opt/harbor/docker-compose.yml down [Install] WantedBy=multi-user.target

注意把WorkingDirectory路径改成你自己的Harbor解压目录。然后执行:

sudo systemctl daemon-reload sudo systemctl enable harbor sudo systemctl start harbor

以后重启机器,Harbor就会自动恢复。这个服务文件的写法比直接给每个容器设置restart: always更可控,因为Harbor容器之间有依赖关系,比如harbor-db必须先于harbor-core启动,而compose up -d会自动处理好顺序。

9.2 日常维护命令集锦

Harbor安装完成后,日常维护主要靠docker-compose命令。常用命令整理如下:

查看所有Harbor组件状态:

cd /opt/harbor docker-compose ps

停止所有组件:

docker-compose stop

启动所有组件:

docker-compose start

修改harbor.yml配置后,重新加载配置:

sudo ./install.sh

重新执行install.sh并不会把你已有的镜像数据清掉,只要/data目录保留着,数据就还在。这个脚本的执行逻辑是先启动一堆基础设施容器,然后重建核心组件,所以不用怕重复执行会丢数据。

如果遇到某个容器反复崩,需要看日志:

docker-compose logs -f harbor-core

把harbor-core换成具体容器名即可。

9.3 版本升级的注意点

Harbor官方建议不要跨大版本升级,比如从2.5升到2.11,最好先升到2.8再升到2.11。升级的大体流程是:备份数据库和配置,下载新版安装包,停掉旧版容器,然后执行新版 install.sh。

数据库备份的核心是/data/database目录,最简单粗暴的方式是直接复制整个/data目录:

sudo cp -r /data /data-backup-$(date +%Y%m%d)

这样即使升级出了幺蛾子,也能整体回滚。但注意数据库文件的一致性,如果数据量大,最好先stop一次容器再用tar打包:

docker-compose stop cd / && sudo tar zcf /opt/harbor-backup.tar.gz data docker-compose start

生产环境升级前建议先在测试环境完整演练一遍,尤其是数据库版本跨度大的时候。

10. 常见问题与排错实战

10.1 Harbor组件反复重启或启动失败

如果你发现docker ps出来的容器状态里harbor-db或者harbor-core是Restarting,最常见的两个原因:一是数据库密码配置和初始化时不一致,二是指定的存储目录权限有误。

排查第一步先看数据库容器日志:

docker-compose logs --tail=200 harbor-db

如果日志里出现“FATAL: password authentication failed”,很大概率是harbor.yml里的database.password和已有的数据库密码不匹配,这个情况多半发生在你改了配置文件之后重新执行install.sh。解决办法是把/data清空重新安装,或者把配置文件里的密码改成旧密码。

如果是目录权限问题,日志会提示“Permission denied”之类的字样,检查/data目录的所有者和权限:

sudo chown -R 10000:10000 /data

Harbor容器内部通常以UID 10000运行,所以/data目录的owner需要让容器有写权限。

10.2 登录时报错:server gave HTTP response to HTTPS client

这个问题在纯HTTP部署下出现的概率极高。在Docker客户端执行docker login后,Docker守护进程默认以HTTPS去访问Registry,而你的Harbor只监听HTTP,于是被拒绝。

处理方法就是第7.1节说的,在/etc/docker/daemon.json配置insecure-registries,把Harbor地址加进去,然后重启Docker。这里有个额外的坑:配置完成后如果还是报同样的错,先检查daemon.json的JSON格式是否合法,多一个逗号少一个逗号都会导致Docker忽略配置。

10.3 Web界面能开但Docker无法登录

Web界面能打开说明Harbor网关、前端和核心API基本正常,但Docker登录失败需要额外关注两个地方:一是Docker客户端到Harbor的网络连通性,二是端口是否开放。

比如Harbor Web用了80端口,你从内网另一台机器访问网页正常,但docker login时如果填的是域名而不是IP,而DNS解析却指向错误地址,就会连不通。用这个命令快速排查:

curl -v http://harbor.example.com/v2/

如果curl返回401 Unauthorized,说明网络通路OK,因为访问/v2/接口时未认证恰好返回401,这是正常现象,接下来应该聚焦在认证和仓库配置上;如果curl超时或者Connection refused,那先查路由、防火墙和安全组。

10.4 镜像推送缓慢或超时

Harbor本身推送慢,最典型的原因是磁盘IO瓶颈。Docker Registry存储镜像时是边收边写的,磁盘写入速度直接决定推送速度。另外,网络延迟和带宽也会影响,尤其是多人同时推送大镜像时。

排查方法:

iostat -x 1

如果看到await或者%util非常高,说明磁盘确实到了瓶颈。这种问题没有代码层面的解法,只能升级磁盘或分担负载。

另外一个容易被忽略的点是nginx的body大小限制,Harbor默认配置里client_max_body_size通常设置为0也就是不限大小,所以一般不会卡在nginx上,但如果你在harbor.yml里或下游代理层加了限制,大镜像就会直接413失败。

10.5 磁盘空间被占满的应急处理

Harbor运行中可能突然出现磁盘空间不足,此时Docker推送镜像失败,Web界面报错。应急先看磁盘使用情况:

df -h du -sh /data/*

如果是镜像数据占满,最直接的办法是在Harbor界面做镜像清理,找到大仓库,删除旧标签,然后执行“垃圾回收”。这一过程会真正释放磁盘空间,但执行时建议避开业务高峰,因为垃圾回收过程会短暂停写。

此外别忘了/var/lib/docker目录也可能被容器日志占满。如果发现docker目录巨大,清理方式:

sudo docker system prune -a

这个命令会删除所有未被使用的镜像和容器,谨慎使用,确认Harbor之外的业务容器都无碍后再执行。

10.6 常见问题速查表

问题现象最可能原因解决手段
网页打不开80/443端口被占用或防火墙未放行检查监听端口和防火墙规则,确保nginx容器正常
Docker login报HTTP错误未配置insecure-registries修改daemon.json并重启Docker
证书校验失败客户端不信任自签CA将CA证书添加进系统信任库
Harbor容器反复重启数据库密码不一致或/data权限问题清空或重置/data,纠正权限
推送镜像很慢磁盘IO瓶颈检查iostat,扩磁盘或换SSD
无法解析Harbor地址客户端没配DNS或hosts添加hosts解析
install.sh执行失败Docker Compose版本过低或端口占用升级compose,释放端口重装

11. 实操心得与建议

根据我个人的安装经验,再分享三个实际踩过坑之后沉淀下来的心得。

第一个心得:安装前把系统时间和时区校准。Harbor内部有证书校验,如果你机器时间不对,自签证书在签发和验证时可能出现各种诡异问题,而且日志里提示的偏差非常不明显,排查起来很头疼。装之前先跑一下date,确认时间是准确的再继续。

第二个心得:不要盲目追新版本。Harbor的新版本确实功能更强,但与之配套的docker-compose和系统库版本要求也会往上涨。比如有些非常老的内核跑新版Harbor的某些容器时会直接崩,排查到内核层面非常痛苦。如果你所在网络环境是内网隔离的,装一个经过验证的稳定版,比追最新版更省心。

第三个心得:Harbor装好后先做一个完整的备份脚本。备份内容包括harbor.yml、/data目录和Docker Compose文件。我自己是写了一个简单的shell脚本,每周定时把/data目录用tar打包存到另一块磁盘,同时把harbor.yml复制一份带日期的副本。真出问题时,恢复装一个干净环境,把备份数据一放,基本能做到一套全量恢复,不用重新配置一堆东西。

最后再说一个小细节:整个安装过程中记录的每一条自定义修改,比如改了哪些密码、生成了什么证书、部署了哪个目录,一定要记在文档里。不然三个月后需要升级或迁移Harbor时,你会发现自己完全不记得当初是怎么配置的,那才是真正让人抓狂的时刻。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/23 3:43:48

Windows 11 25H2官方镜像获取、启动盘制作与安装升级指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/23 3:42:29

WSL2搭建3DGS训练环境:CUDA/PyTorch版本匹配与避坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/23 3:41:43

SPI与I2C深度解析:嵌入式片间通信原理、选型与实战调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/23 3:39:50

树莓派CM4硬件设计详解:BCM2711主控与200Pin连接器引脚分组

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/23 3:39:37

Windows 11 IoT LTSC 2024 老电脑安装调优指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/23 3:39:29

UE5蓝图实现RTS游戏框选单位功能

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华