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-portal | Web前端页面 |
| 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-pluginDocker 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 || true18.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.shinstall.sh有三个常用参数:
- --with-trivy:启用镜像漏洞扫描功能
- --with-notary:启用镜像签名功能(一般用不到)
- --with-chartmuseum:启用Helm Chart仓库功能
大多数团队只需要加--with-trivy:
sudo ./install.sh --with-trivyinstall.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 /dataHarbor容器内部通常以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时,你会发现自己完全不记得当初是怎么配置的,那才是真正让人抓狂的时刻。