ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

ARM服务器离线安装Harbor v2.4.0实战与避坑指南

ARM服务器离线安装Harbor v2.4.0实战与避坑指南

简介:面向需要在ARM架构服务器上私有化部署容器镜像仓库的运维与DevOps人员,这份harbor-v2.4.0离线安装包解决了内网环境无法拉取在线镜像、依赖下载困难的问题。压缩包共6个文件,以sh脚本、gz压缩包、yml配置、license许可及prepare准备文件为主,整体约402.34MB,其中gz为Harbor核心镜像归档,yml承载服务参数配置,sh脚本负责一键执行安装流程。使用前需预先装好docker与docker-compose,随后运行install.sh即可完成部署,省去逐组件手工配置的繁琐。内容涵盖镜像归档、配置模板与安装脚本等关键模块,便于读者快速搭建可用的私有仓库环境,并对照配置项理解各服务组件的组织方式。目前已有1576人学习下载,适合希望掌握ARM平台Harbor离线部署与配置调整的技术人员参考。

1. 一次在 arm 服务器上装 harbor 的翻车记录

第一次在 arm 架构的服务器上装 harbor-v2.4.0,我以为跟 x86 上一样,下载、解压、改配置、跑脚本,半小时收工。结果prepare脚本跑完,docker-compose up -d之后,harbor-core 容器反复重启,日志里全是镜像架构不匹配的报错。折腾到凌晨两点才发现,官方 release 包里默认带的是 amd64 的镜像,arm 上根本拉不起来。这件事让我意识到,harbor 的离线安装包分架构,arm 环境必须用对应的 arm 版本,否则后面所有步骤都是白费。

harbor 作为企业级镜像仓库,在 arm 服务器上部署的需求这两年明显多了起来,尤其是国产化替代和边缘计算场景。但 arm 的坑比 x86 多得多,从离线包选择、镜像架构校验,到 docker-compose 版本兼容、存储驱动配置,每一步都可能卡住。这篇笔记记录我在 arm 环境完整装一遍 harbor-v2.4.0 的过程,包括版本怎么选、参数怎么改、装完怎么验证,以及我踩过的那些坑。如果你也正对着 arm 服务器发愁,希望能帮你少走点弯路。

2. 环境准备:arm 架构下 harbor-v2.4.0 的版本选择与依赖清单

2.1 确认 CPU 架构与操作系统兼容性

arm 服务器上装 harbor,第一件事不是下载安装包,而是确认你的 CPU 架构到底是 arm64 还是 aarch64。这两个名字经常混用,但 harbor 的离线包命名用的是arm64。执行下面这条命令确认:

# 确认 CPU 架构,输出 aarch64 或 arm64 都表示 64 位 ARM uname -m # 查看操作系统版本,确认内核版本和发行版 cat /etc/os-release

如果uname -m输出的是aarch64,说明是 64 位 ARM 架构,可以用 harbor 的 arm64 离线包。如果输出armv7l或armv6l,那是 32 位 ARM,harbor-v2.4.0 不支持,别浪费时间。操作系统方面,我实测过 Ubuntu 20.04 arm64 和 CentOS 7 arm64 都能跑,但 CentOS 7 的内核版本偏低,docker 需要额外升级。常见做法是优先选 Ubuntu 20.04 或 22.04 的 arm64 版本,内核 5.x 以上,省去很多驱动兼容问题。

还有一个容易忽略的点:磁盘空间。harbor 的离线包解压后加上镜像层,至少需要 40GB 可用空间。df -h看一眼根分区,别装到一半发现空间不够,清理起来很麻烦。

2.2 安装 docker 与 docker-compose 的版本取舍

harbor-v2.4.0 对 docker 和 docker-compose 的版本有明确要求。docker 最低 17.06.0,但 arm 上我建议用 20.10.x 以上的版本,因为低版本在 arm 上对 overlay2 存储驱动的支持不稳定。docker-compose 必须是 1.18.0 以上,但注意 harbor-v2.4.0 的安装脚本用的是docker-compose命令,不是docker compose插件,所以得单独装 docker-compose 二进制。

# 安装 docker(以 Ubuntu arm64 为例) sudo apt-get update sudo apt-get install -y docker.io # 确认 docker 版本,建议 20.10.x 以上 docker --version # 下载 docker-compose 二进制(arm64 版本) sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose # 赋予执行权限 sudo chmod +x /usr/local/bin/docker-compose # 验证 docker-compose 版本 docker-compose --version

这里有个细节:docker-compose 的 GitHub release 页面提供的二进制文件名里,$(uname -m)在 arm 上输出aarch64,但 release 里对应的文件是docker-compose-Linux-aarch64,能直接匹配。如果下载速度慢,可以换用国内镜像源,但注意别下成 amd64 的版本,否则执行时会报cannot execute binary file。

docker 装完后,记得把当前用户加入 docker 组,否则每次都要 sudo:

# 将当前用户加入 docker 组 sudo usermod -aG docker $USER # 重新登录使组权限生效,或者执行下面命令临时切换 newgrp docker

2.3 下载正确的 arm64 离线安装包

harbor 的离线安装包在官方 release 页面有多个文件,arm 环境必须选文件名里带arm64的那个。以 v2.4.0 为例,文件名是harbor-offline-installer-v2.4.0-arm64.tgz。如果你下的是harbor-offline-installer-v2.4.0.tgz,那是 amd64 版本,装到 arm 上必然失败。

# 下载 arm64 离线包(示例链接,实际以官方 release 为准) wget https://github.com/goharbor/harbor/releases/download/v2.4.0/harbor-offline-installer-v2.4.0-arm64.tgz # 解压到指定目录 tar -xzvf harbor-offline-installer-v2.4.0-arm64.tgz -C /opt/ # 进入解压后的目录 cd /opt/harbor

解压后目录里应该包含harbor.v2.4.0.tar.gz(镜像包)、harbor.yml.tmpl(配置模板)、prepare(预处理脚本)、install.sh(安装脚本)。用ls -lh看一下文件大小,harbor.v2.4.0.tar.gz大概 500MB 左右,如果只有几十 MB,说明下载不完整,重新下。

提示:下载前先确认服务器能访问外网,或者提前把离线包传到服务器上。arm 环境经常在内网,外网访问受限,建议在能上网的机器上下好再 scp 过去。

3. 配置 harbor.yml:arm 环境下必须改对的五个参数

3.1 从模板生成配置文件并设置 hostname

harbor 解压后没有直接的harbor.yml,需要从harbor.yml.tmpl复制一份:

# 复制配置模板 cp harbor.yml.tmpl harbor.yml # 编辑配置文件 vim harbor.yml

打开后第一个要改的是hostname。这个参数决定 harbor 的访问地址,可以填 IP 也可以填域名。arm 服务器通常在内网,我一般直接填服务器 IP:

# 修改为实际服务器 IP 或域名 hostname: 192.168.1.100

注意不要带http://或https://前缀,也不要带端口。如果填了协议头,后面启动时会报 hostname 格式错误。这个参数改完后,harbor 的 web 界面、docker login 地址都用这个值,所以别填localhost或127.0.0.1,否则其他机器访问不了。

3.2 关闭 https 或配置证书(arm 环境建议先关)

harbor 默认配置里 https 是打开的,需要提供证书和私钥。内网测试环境我一般先把 https 注释掉,用 http 跑通再说:

# 注释掉 https 相关配置 # https: # port: 443 # certificate: /your/certificate/path # private_key: /your/private/key/path

如果必须用 https,那就得准备证书。arm 环境上生成自签名证书的命令和 x86 一样:

# 生成自签名证书(示例) openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout /etc/harbor/ssl/harbor.key \ -out /etc/harbor/ssl/harbor.crt \ -subj "/CN=192.168.1.100"

然后把harbor.yml里的certificate和private_key指向这两个文件。注意证书的 CN 必须和 hostname 一致,否则 docker login 时会报证书不匹配。

3.3 数据目录与日志目录的路径规划

harbor 默认把数据存在/data目录下,包括镜像层、数据库、Redis 持久化文件、日志等。arm 服务器如果有单独的挂载盘,建议改到挂载盘上,避免根分区被撑爆:

# 修改数据目录 data_volume: /data/harbor # 日志配置 log: level: info local: rotate_count: 50 rotate_size: 200M location: /var/log/harbor

data_volume改完后,prepare脚本会自动创建对应目录。注意目录权限,harbor 容器以非 root 用户运行,如果目录权限不对,启动时会报 permission denied。我一般提前建好目录并给 755 权限:

# 创建数据目录并设置权限 sudo mkdir -p /data/harbor sudo chmod 755 /data/harbor

3.4 端口冲突排查与修改

harbor 默认用 80 和 443 端口。如果服务器上已经有 nginx 或其他 web 服务占了 80,harbor 起不来。先检查端口占用:

# 检查 80 和 443 端口是否被占用 sudo netstat -tlnp | grep -E ':80|:443'

如果被占用,要么停掉占用端口的服务,要么改 harbor 的端口:

# 修改 http 端口 http: port: 8080 # 如果启用了 https,也改一下 https: port: 8443

改完端口后,访问地址就变成http://192.168.1.100:8080,docker login 也要带端口。注意hostname参数不要带端口,端口只在http.port里配。

3.5 数据库密码与核心组件参数调整

harbor.yml里有个harbor_admin_password,这是 admin 用户的初始密码。默认是Harbor12345,生产环境必须改:

# 修改 admin 初始密码 harbor_admin_password: YourStrongPassword123

另外database部分的password也要改,这是 harbor 内部数据库的密码,虽然不对外暴露,但建议一起改掉:

database: password: YourDBPassword456 max_idle_conns: 100 max_open_conns: 900

max_idle_conns和max_open_conns在 arm 环境下如果并发不高,可以保持默认。如果镜像推送频繁,可以适当调大,但注意 arm 服务器的内存通常比 x86 小,别调太大导致 OOM。

注意:所有密码修改后,如果之前已经跑过prepare,需要重新跑一次,否则配置不会生效。prepare脚本会根据harbor.yml生成docker-compose.yml和各个组件的配置文件。

4. 执行安装:从 prepare 到容器启动的完整流程

4.1 运行 prepare 脚本生成配置

配置改完后,执行prepare脚本:

# 在 harbor 目录下执行 sudo ./prepare

这个脚本会做几件事:检查harbor.yml语法、生成docker-compose.yml、生成各组件配置文件(如core/env、registry/config.yml)、创建数据目录。如果harbor.yml里有语法错误,脚本会直接报错并指出行号。常见错误包括缩进不对、冒号后没空格、注释格式不对。arm 环境下这个脚本本身没有架构差异,但生成的配置里会引用镜像名,后面加载镜像时要注意架构。

执行成功后,当前目录下会多出docker-compose.yml和common目录。common目录里是各组件配置,一般不需要手动改。

4.2 加载离线镜像并确认架构

prepare完成后,需要把离线包里的镜像加载到 docker:

# 加载镜像 sudo docker load -i harbor.v2.4.0.tar.gz

加载过程可能持续几分钟,取决于磁盘速度。加载完成后,用docker images看一下镜像列表:

# 查看已加载的镜像 sudo docker images | grep goharbor

你应该能看到goharbor/harbor-core:v2.4.0、goharbor/harbor-portal:v2.4.0、goharbor/registry-photon:v2.4.0等镜像。关键一步:确认这些镜像的架构是 arm64:

# 查看镜像架构信息 sudo docker inspect goharbor/harbor-core:v2.4.0 | grep -i architecture

如果输出"Architecture": "arm64",说明镜像正确。如果输出amd64,说明你下错了离线包,需要重新下载 arm64 版本。这一步是 arm 环境最容易翻车的地方,我见过有人用 amd64 的包在 arm 上跑,容器起来后立刻退出,日志里报exec format error,排查半天才发现是镜像架构不对。

4.3 启动 harbor 并观察容器状态

镜像加载完成后,执行安装脚本:

# 启动 harbor sudo ./install.sh

install.sh内部会调用docker-compose up -d,启动所有容器。启动过程大概需要 1-2 分钟,取决于服务器性能。启动完成后,用下面命令查看容器状态:

# 查看容器运行状态 sudo docker-compose ps

正常情况下,所有容器的状态应该是Up或Up (healthy)。如果有容器显示Exit或Restarting,说明有问题。最常见的几个问题:端口被占用导致 nginx 起不来、数据目录权限不对导致 registry 起不来、数据库密码不一致导致 core 连不上数据库。

如果某个容器反复重启,用docker logs看日志:

# 查看 harbor-core 日志 sudo docker logs harbor-core # 查看 nginx 日志 sudo docker logs nginx

日志里通常会直接指出问题,比如connection refused表示依赖的服务没起来,permission denied表示目录权限问题,exec format error表示镜像架构不对。

4.4 验证 web 界面与 docker login

所有容器Up之后,打开浏览器访问http://192.168.1.100(或你配置的端口),应该能看到 harbor 的登录页面。默认用户名admin,密码是你改过的harbor_admin_password。登录进去后,能看到项目列表和系统状态。

然后在另一台机器上测试 docker login:

# 登录 harbor docker login 192.168.1.100 # 输入用户名和密码后,如果显示 Login Succeeded,说明认证正常

如果 harbor 配的是 http 而不是 https,docker 默认会拒绝连接,需要在 docker 的配置里加insecure-registries:

# 编辑 docker 配置 sudo vim /etc/docker/daemon.json # 添加以下内容 { "insecure-registries": ["192.168.1.100"] } # 重启 docker sudo systemctl restart docker

注意这个配置要在客户端机器上改,不是 harbor 服务器上。改完后 docker login 就能成功了。登录成功后,可以试着推一个镜像上去,验证整个链路是否通畅。

5. 避坑记录:arm 环境装 harbor 最容易踩的五个坑

5.1 镜像架构不匹配导致容器反复重启

现象:docker-compose ps显示 harbor-core 或 harbor-portal 状态为Restarting,docker logs里报exec format error或standard_init_linux.go: exec user process caused: exec format error。

原因:下载了 amd64 的离线安装包,加载的镜像架构是 x86,arm 服务器无法执行。

解决:重新下载文件名带arm64的离线包,docker load之前先docker rmi删掉旧镜像,或者直接docker load覆盖。加载后用docker inspect确认架构是arm64。

5.2 docker-compose 版本过低导致语法不兼容

现象:执行install.sh时报Unsupported config option for services或Version in "./docker-compose.yml" is unsupported。

原因:docker-compose 版本低于 1.18.0,不支持 harbor 生成的 compose 文件格式。

解决:升级 docker-compose 到 1.29.2 或更高版本。注意下载 arm64 对应的二进制文件,别下成 amd64 的。升级后docker-compose --version确认版本号。

5.3 数据目录权限不对导致 registry 启动失败

现象:docker-compose ps显示 registry 状态为Exit,docker logs registry里报permission denied或open /storage/...: permission denied。

原因:data_volume指定的目录权限不对,harbor 容器内的用户没有写权限。

解决:确保data_volume目录存在且权限为 755,所有者是 root。如果之前用其他用户创建过,chown -R root:root /data/harbor改回来。另外注意 SELinux 如果开启,可能需要额外配置,arm 环境上我一般直接关掉 SELinux 省事。

5.4 端口被占用导致 nginx 无法启动

现象:docker-compose ps显示 nginx 状态为Exit,docker logs nginx里报bind() to 0.0.0.0:80 failed (98: Address already in use)。

原因:服务器上已有其他服务占用了 80 或 443 端口。

解决:netstat -tlnp | grep :80找到占用进程,停掉或改端口。如果改 harbor 端口,修改harbor.yml里的http.port,重新跑prepare和install.sh。注意hostname不要带端口。

5.5 数据库密码不一致导致 core 连不上数据库

现象:harbor-core 容器不断重启,docker logs harbor-core里报pq: password authentication failed for user "postgres"或dial tcp ... connect: connection refused。

原因:harbor.yml里database.password改过,但之前已经跑过prepare,旧的配置残留在common/config目录里,导致数据库容器和 core 容器用的密码不一致。

解决:删掉common目录和docker-compose.yml,重新跑prepare。如果数据库容器已经初始化过,还需要删掉data_volume下的database目录,让数据库重新初始化。这个操作会丢失已有数据,生产环境慎用。

6. 装完怎么验证:三个必须走一遍的检查动作

装完 harbor 只是第一步,能不能正常用,得靠验证。我一般会走三个检查动作,少一个都不放心。

第一个动作是看容器健康状态。docker-compose ps只能看到容器是否在跑,但 harbor 的容器有健康检查,Up (healthy)才是真正就绪。如果显示Up (health: starting),等 30 秒再看。如果一直是starting,说明健康检查没通过,得看日志。我习惯用下面这条命令一次性看所有容器的健康状态:

# 查看所有容器的健康状态 sudo docker-compose ps --format "table {{.Name}}\t{{.Status}}"

第二个动作是登录 web 界面后,创建一个测试项目,然后从另一台机器推一个镜像上去。这一步能验证前端、后端、数据库、存储、认证整条链路。推镜像的命令如下:

# 拉一个测试镜像 docker pull hello-world # 打标签 docker tag hello-world 192.168.1.100/library/hello-world:v1 # 推送 docker push 192.168.1.100/library/hello-world:v1

推送成功后,在 harbor 的 web 界面里能看到这个镜像,说明存储和数据库都正常。如果推送时报unauthorized,检查 docker login 是否成功;如果报no such host,检查 hostname 解析;如果报connection refused,检查端口和防火墙。

第三个动作是重启服务器后,确认 harbor 能自动恢复。harbor 的容器默认没有设置restart: always,服务器重启后容器不会自动起来。我一般会配置 systemd 服务或者加restart策略:

# 编辑 docker-compose.yml,给每个服务加 restart 策略 # 或者用 systemd 管理 sudo vim /etc/systemd/system/harbor.service

systemd 服务文件内容如下:

[Unit] Description=Harbor After=docker.service systemd-networkd.service systemd-resolved.service Requires=docker.service Documentation=http://github.com/goharbor/harbor [Service] Type=simple Restart=on-failure RestartSec=5 ExecStart=/usr/local/bin/docker-compose -f /opt/harbor/docker-compose.yml up ExecStop=/usr/local/bin/docker-compose -f /opt/harbor/docker-compose.yml down [Install] WantedBy=multi-user.target

配置完后systemctl daemon-reload和systemctl enable harbor,下次重启服务器 harbor 会自动起来。这个动作我每次装完都会做,因为生产环境不可能每次重启都手动敲命令。

从那以后,我每次在 arm 上装 harbor,都会先uname -m确认架构,再docker inspect确认镜像架构,最后推一个测试镜像验证整条链路。这三个动作走完,才敢说装好了。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进