简介:面向需要在ARM架构服务器上私有化部署容器镜像仓库的运维与DevOps人员,这份harbor-v2.4.0离线安装包解决了内网环境无法拉取在线镜像、依赖下载困难的问题,适合具备Docker基础、希望快速搭建企业级镜像仓库的中高级用户。压缩包共6个文件,以sh脚本、gz压缩包、yml配置、license许可及prepare准备文件为主,其中gz为Harbor核心镜像归档,yml承载服务参数配置,sh脚本负责一键安装与公共函数调用,整体约402.34MB,解压后执行install.sh即可完成部署,前置条件为已安装docker与docker-compose。目前已有1576人学习下载,验证了该方案在ARM平台上的可用性。读者可获得完整的离线部署组件、可复用的配置模板与安装脚本,便于在隔离网络中快速落地镜像仓库并理解其目录结构与参数组织方式。
1. 从一台没有外网的 ARM 服务器说起:harbor-v2.4.0 离线安装到底解决什么问题
很多做私有化交付的同行都遇到过这种场景:客户机房在物理隔离的内网里,给了一台 ARM 架构的服务器,要求把镜像仓库跑起来。你手里只有一台能上网的笔记本,服务器上连docker pull都执行不了。这时候 harbor-v2.4.0 离线安装包就是那根救命稻草——它把 Harbor 运行所需的全部镜像、二进制文件和配置模板打包成一个压缩包,拷进去解压、改配置、执行安装脚本,全程不需要访问任何外部镜像源。
Harbor 本身是 VMware 开源的企业级容器镜像仓库,2.4.0 这个版本在 ARM 生态里属于比较成熟的节点,支持多架构镜像清单、RBAC 权限控制、镜像复制、漏洞扫描(需额外集成 Trivy)等能力。离线安装包和在线安装包的核心区别在于:在线包只包含安装脚本和 compose 模板,镜像需要从 Docker Hub 拉取;离线包则把harbor-core、harbor-portal、harbor-db、redis、nginx等十几个组件的镜像全部预置在harbor.v2.4.0.tar.gz里,安装时直接docker load导入本地。
这篇文章面向的是需要在 ARM 服务器上完成 Harbor 离线部署的运维和交付工程师。我会从环境预检、安装包结构拆解、配置参数逐项说明、安装脚本执行、到常见报错排查,把整个流程拆成可复现的步骤。如果你之前只在 x86 上装过 Harbor,ARM 架构下有几个坑是绕不开的,后面会专门讲。
2. 安装前的环境预检与依赖确认:ARM 架构下哪些东西必须先到位
2.1 硬件与操作系统层面的硬性条件
Harbor 2.4.0 对资源的要求不算高,但 ARM 环境下有几个容易被忽略的点。最低配置是 2 核 CPU、4GB 内存、40GB 磁盘,这是官方给的下限,实际生产环境建议 4 核 8GB 起步,因为镜像扫描和复制任务会吃内存。磁盘方面,如果打算存大量镜像,/data目录最好单独挂一块盘,Harbor 默认把镜像数据放在/data/下。
操作系统层面,ARM 服务器上常见的是麒麟、统信 UOS、Ubuntu ARM64 这几个。内核版本建议 4.19 以上,因为 Harbor 2.4.0 依赖的containerd和runc对内核特性有要求。检查命令很简单:
# 确认 CPU 架构,输出应为 aarch64 或 arm64 uname -m # 确认内核版本,建议 4.19+ uname -r # 确认操作系统发行版 cat /etc/os-release如果uname -m输出的是aarch64,说明是 64 位 ARM 架构,和 Harbor 离线包的arm64目录对应。如果输出armv7l,那是 32 位 ARM,Harbor 2.4.0 不支持,别浪费时间。
2.2 Docker 与 Docker Compose 的版本匹配
Harbor 2.4.0 的安装脚本依赖docker和docker-compose。ARM 环境下 Docker 的安装方式和 x86 略有不同,很多发行版的默认源里 Docker 版本偏旧。建议 Docker 版本不低于 19.03,docker-compose不低于 1.25。
# 检查 Docker 版本 docker --version # 检查 Docker Compose 版本 docker-compose --version # 检查 Docker 服务是否正常运行 systemctl status docker如果 Docker 没装,ARM 环境下可以用发行版自带的包管理器安装,比如 Ubuntu ARM64 上apt install docker.io docker-compose。但要注意,部分国产化操作系统自带的 Docker 版本可能低于 19.03,这时候需要手动编译或找对应架构的二进制包。我一般会先确认docker info能正常输出,再往下走。
提示:Docker 的
># 检查 80 和 443 是否被占用 ss -tlnp | grep -E ':80|:443' # 检查 Harbor 内部组件常用端口 ss -tlnp | grep -E ':4443|:5432|:6379|:8080'如果 80 或 443 被 Nginx 或 Apache 占了,有两个选择:要么停掉已有服务,要么在
harbor.yml里改 Harbor 的对外端口。防火墙方面,如果服务器开了firewalld或ufw,需要放行对应端口,或者直接关掉防火墙(内网环境常见做法)。# 查看 firewalld 状态 systemctl status firewalld # 如果开启,放行 80 和 443 firewall-cmd --permanent --add-port=80/tcp firewall-cmd --permanent --add-port=443/tcp firewall-cmd --reload3. 离线包结构拆解与 harbor.yml 关键参数逐项说明
3.1 离线包解压后到底有什么
拿到
harbor-offline-installer-v2.4.0-arm64.tgz之后,先别急着执行安装脚本。解压看一下目录结构,心里有数再动手:# 解压离线安装包 tar -zxvf harbor-offline-installer-v2.4.0-arm64.tgz # 进入解压后的目录 cd harbor # 查看目录内容 ls -lh解压后你会看到这几个关键文件:
harbor.v2.4.0.tar.gz是预置的镜像包,大小通常在 1GB 以上;harbor.yml.tmpl是配置模板,需要复制成harbor.yml再改;install.sh是安装脚本;prepare是预处理脚本,负责生成 docker-compose 文件。common.sh里封装了一些公共函数,排查问题时可以读一读。镜像包不需要手动
docker load,install.sh会自动处理。但如果你想确认镜像包是否完整,可以先看一眼它的 SHA256:# 计算镜像包校验和,和官方发布页对比 sha256sum harbor.v2.4.0.tar.gz3.2 harbor.yml 里必须改的五个参数
harbor.yml.tmpl复制成harbor.yml后,有五个参数是必须根据实际环境修改的,不改大概率装完访问不了。第一个是
hostname。这个值决定 Harbor 的访问地址,可以填 IP 也可以填域名。如果填域名,需要确保内网 DNS 能解析;如果填 IP,直接写服务器 IP 即可。注意不要带http://或https://前缀。# 修改为实际服务器 IP 或域名 hostname: 192.168.1.100第二个是
http.port。默认是 80,如果被占用就改成其他端口,比如 8080。第三个是https相关配置,如果内网不需要 HTTPS,把整个https段注释掉即可,Harbor 会只跑 HTTP。第四个是harbor_admin_password,这是 admin 用户的初始密码,建议改掉默认的Harbor12345。第五个是data_volume,指定镜像数据的存储路径,默认/data。# HTTP 端口配置 http: port: 80 # HTTPS 配置,不需要则整段注释 # https: # port: 443 # certificate: /your/certificate/path # private_key: /your/private/key/path # 管理员初始密码 harbor_admin_password: YourStrongPassword # 数据存储路径 data_volume: /data3.3 数据库与日志参数的调整建议
harbor.yml里还有database和log两个段,默认配置在小规模场景下够用,但如果镜像数量多、访问频繁,建议调整。database.max_idle_conns和max_open_conns控制数据库连接池,默认分别是 50 和 1000,一般不用改。log.level默认是info,排查问题时可以临时改成debug,但生产环境别长期开着,日志量会暴涨。# 数据库连接池配置 database: max_idle_conns: 50 max_open_conns: 1000 # 日志级别,排查问题时改为 debug log: level: info local: rotate_count: 50 rotate_size: 200M location: /var/log/harbor
log.local下的rotate_count和rotate_size控制日志轮转,默认保留 50 个文件、每个最大 200MB。如果磁盘紧张,可以适当调小。location是日志存放路径,确保这个目录有写权限。注意:
harbor.yml里所有缩进必须用空格,不能用 Tab。YAML 对缩进敏感,一个 Tab 就能让安装脚本报解析错误。4. 执行安装脚本与验证:从 prepare 到 docker-compose 拉起全流程
4.1 运行 install.sh 时发生了什么
配置改完之后,执行
./install.sh即可。这个脚本内部会依次做几件事:先调用prepare脚本,根据harbor.yml生成docker-compose.yml;然后检查harbor.v2.4.0.tar.gz是否存在,存在就docker load导入镜像;最后执行docker-compose up -d拉起所有容器。# 执行安装脚本,不加参数默认包含 Notary 和 Trivy ./install.sh # 如果不需要 Notary 和 Trivy,可以只装核心组件 ./install.sh --without-notary --without-trivy安装过程中会输出大量日志,重点看最后几行有没有
Harbor has been installed and started successfully。如果有,说明安装成功。如果中途报错,日志会停在某一步,根据报错信息定位。4.2 用 docker-compose ps 确认容器状态
安装完成后,第一件事是确认所有容器都处于
Up状态:# 查看 Harbor 相关容器状态 docker-compose ps # 或者用 docker ps 过滤 docker ps --filter "name=harbor" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"正常情况下会看到
harbor-core、harbor-portal、harbor-db、harbor-jobservice、harbor-registry、redis、nginx等容器。如果有容器状态是Exit或Restarting,用docker logs看具体报错:# 查看某个容器的日志,比如 harbor-core docker logs harbor-core --tail 100 # 查看 harbor-db 日志,数据库起不来是常见问题 docker logs harbor-db --tail 100
harbor-db起不来最常见的原因是数据目录权限不对,或者之前装过 Harbor 残留了旧数据。解决办法是清空/data/database目录再重装。4.3 登录 Web 界面并推送第一个镜像
容器全部
Up之后,浏览器访问http://<hostname>:<port>,用harbor.yml里设的 admin 密码登录。登录成功后先创建一个项目,比如叫test,然后在本机测试推送镜像。# 登录 Harbor,替换为实际地址和端口 docker login 192.168.1.100:80 -u admin -p YourStrongPassword # 给本地镜像打标签 docker tag nginx:latest 192.168.1.100:80/test/nginx:latest # 推送镜像 docker push 192.168.1.100:80/test/nginx:latest如果推送时报
http: server gave HTTP response to HTTPS client,说明 Docker 客户端默认走 HTTPS,而 Harbor 配的是 HTTP。需要在 Docker 的daemon.json里加insecure-registries:{ "insecure-registries": ["192.168.1.100:80"] }改完重启 Docker 服务,再重新登录推送。这个坑在离线环境里特别常见,因为内网通常没有证书,只能走 HTTP。
5. 避坑与排查:ARM 离线安装 Harbor 最容易翻车的五个地方
5.1 镜像导入失败,报 no space left on device
现象是
install.sh执行到docker load那一步卡住,然后报磁盘空间不足。原因是harbor.v2.4.0.tar.gz解压后的镜像层加起来可能超过 2GB,而/var/lib/docker所在分区空间不够。解决办法是先df -h确认分区剩余空间,如果不够,把 Docker 的># 查看磁盘使用情况 df -h /var/lib/docker # 清理无用镜像和容器 docker system prune -a5.2 harbor-db 容器反复重启
现象是
docker-compose ps里harbor-db状态一直是Restarting,日志里报initdb: cannot be run as root或者permission denied。原因是 PostgreSQL 不允许以 root 用户初始化数据目录,而离线安装时如果之前用 root 跑过,数据目录权限会乱。解决办法是删掉/data/database目录,确保它属于 UID 999(PostgreSQL 容器内的用户),然后重新执行./install.sh。# 停止并清理旧容器 docker-compose down -v # 删除旧数据目录 rm -rf /data/database # 重新安装 ./install.sh5.3 访问 Web 界面报 502 Bad Gateway
现象是浏览器打开 Harbor 地址,Nginx 返回 502。原因是
harbor-core或harbor-portal没起来,Nginx 转发不到后端。先docker-compose ps看哪个容器挂了,再用docker logs看具体报错。常见原因是harbor.yml里hostname配错了,导致harbor-core启动时连不上自己的 API。# 检查 harbor-core 日志 docker logs harbor-core --tail 200 # 检查 nginx 配置是否正确生成 cat /path/to/harbor/common/config/nginx/nginx.conf5.4 推送镜像时认证失败
现象是
docker login成功,但docker push时报unauthorized: authentication required。原因是 Docker 客户端缓存的凭证和 Harbor 实际的不一致,或者项目权限没配对。解决办法是先docker logout,再重新docker login。如果还不行,检查 Harbor 里该项目的成员权限,确保当前用户有推送权限。# 登出再重新登录 docker logout 192.168.1.100:80 docker login 192.168.1.100:80 -u admin -p YourStrongPassword5.5 ARM 镜像和 x86 镜像混推导致 manifest 报错
现象是在 Harbor 里查看镜像时,某些 tag 显示
manifest unknown。原因是 Harbor 2.4.0 虽然支持多架构镜像清单,但如果你从 x86 机器上推了一个amd64镜像,又从 ARM 机器上推了同 tag 的arm64镜像,Harbor 不会自动合并成 manifest list,而是覆盖。解决办法是推多架构镜像时用docker manifest命令手动创建清单,或者用buildx构建多架构镜像后一次性推送。# 创建多架构 manifest 并推送 docker manifest create 192.168.1.100:80/test/nginx:latest \ 192.168.1.100:80/test/nginx:amd64 \ 192.168.1.100:80/test/nginx:arm64 docker manifest push 192.168.1.100:80/test/nginx:latest6. 装完之后怎么验证这套 Harbor 真的能用:三个进阶检查动作
装完能登录不代表就万事大吉了。我一般会做三个额外检查,确认这套 Harbor 在 ARM 环境下是真正可用的,而不是表面能跑。
第一个检查是镜像复制功能。Harbor 的复制功能依赖
harbor-jobservice和harbor-core的 gRPC 通信,如果这两个容器之间的网络有问题,复制任务会一直卡在Pending。验证方法是创建一个复制规则,指向另一个 registry(可以是同一个 Harbor 的另一个项目),然后推一个镜像看复制任务是否完成。如果卡住,检查harbor-jobservice的日志,常见原因是 Redis 连接超时。# 查看 jobservice 日志 docker logs harbor-jobservice --tail 100 # 检查 Redis 容器是否正常 docker exec -it redis redis-cli ping第二个检查是垃圾回收。Harbor 的镜像删除默认只是软删除,实际磁盘空间不会释放,需要手动触发 GC。在 Web 界面的「系统管理」→「垃圾回收」里可以手动触发,也可以配定时任务。GC 执行时会扫描所有 blob,如果
harbor-registry容器和harbor-db的数据不一致,GC 可能报错。建议在业务低峰期执行,并且执行前先备份/data目录。# 手动触发 GC(需要先获取 API token) curl -X POST -u admin:YourStrongPassword \ -H "Content-Type: application/json" \ "http://192.168.1.100:80/api/v2.0/system/gc/schedule" \ -d '{"schedule":{"type":"Manual"}}'第三个检查是日志轮转是否生效。Harbor 的日志默认放在
/var/log/harbor下,如果rotate_count设得太大而磁盘又小,跑一段时间后日志能把磁盘写满。我一般会把rotate_count调到 10 到 20 之间,rotate_size调到 100M,然后在/etc/logrotate.d/下加一个针对 Harbor 日志的轮转规则作为双保险。# 查看 Harbor 日志目录大小 du -sh /var/log/harbor # 查看当前日志文件列表 ls -lh /var/log/harbor还有一个容易被忽略的点:Harbor 2.4.0 的
harbor-core容器在 ARM 环境下启动比 x86 慢,因为 ARM 的 JVM 预热时间更长。如果你用docker-compose up -d之后立刻访问 Web 界面,可能会遇到 502,等 30 秒到 1 分钟再刷新就好了。这不是故障,是 ARM 平台的正常表现。从那以后我每次在 ARM 服务器上装完 Harbor,都会先等两分钟再访问 Web 界面,然后跑一遍镜像推送、拉取、删除、GC 的完整流程,确认每个环节都正常才交付。这套流程帮我省掉了很多返工。希望帮到你。
本文还有配套的精品资源,点击获取