ARTICLE DETAIL

资讯详情

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

ARM服务器离线安装Harbor v2.4.0:从镜像打包到避坑指南

ARM服务器离线安装Harbor v2.4.0:从镜像打包到避坑指南 简介为ARM架构服务器量身打造的Harbor v2.4.0离线安装包适用于内网隔离环境、国产化信创场景也适合需要在树莓派、鲲鹏等ARM平台上快速搭建私有镜像仓库的运维人员。压缩包共6个文件以shell安装脚本、docker镜像压缩包.tar.gz、YAML配置文件及prepare预处理脚本为主整体大小402.34MB结构精简无需手动拉取镜像即可离线完成部署。已有1574人学习下载。资源附带install.sh与harbor.yml等核心文件执行前仅需准备docker和docker-compose环境一键运行脚本即可自动完成镜像加载、配置生成和容器启动同时提供LICENSE许可说明与prepare脚本便于理解部署流程和排错。对于无法访问互联网的ARM生产环境这套离线包能显著降低安装门槛节省逐一下载镜像的时间。1. 为什么ARM服务器上装Harbor离线安装才是真正的后悔药在云桌面、信创服务器、边缘网关这些ARM环境里装Harbor v2.4.0最容易遇到的问题不是Harbor本身而是“在线拉镜像拉一半被限速、连不上Docker Hub、yum源里没有docker-compose”。我见过很多团队在ARM服务器前卡了一整天最后把离线安装包解压、docker load、改配置、跑脚本二十分钟就起来了。离线安装把本来散落各处的依赖收敛成一个tar包让你在断网生产环境也能一步步复现。这篇文章面向的是没有外网的ARM服务器、跑银河麒麟V10或统信UOS的飞腾/鲲鹏平台以及需要给客户做交付部署的运维。你会看到从哪里拿镜像包、怎么装Docker以及我踩过的一堆坑。2. 离线安装前的准备ARM架构镜像包从哪来、怎么传过去在动手跑./install.sh之前最该做的不是配环境而是先确认一件事你手上的Harbor镜像包到底是不是ARM架构。Harbor的离线安装包本质是一个大tar里面是docker save出来的镜像归档加一个安装脚本。官方release页面提供的harbor-offline-installer-v2.4.0.tgz主要面向x86_64环境如果你的服务器是arm64直接把官方离线包拿来load容器起来也照样会exec format error。所以常见做法是找一台同样ARM架构、能联网的机器手动拉取Harbor v2.4.0的arm64镜像save成tar包再传到内网。准备工作分三步确认架构、打镜像包、传包校验。2.1 先搞清楚你的ARM机器是哪种arm64 vs armv7 直接决定安装包怎么选ARM不是只有一个版本。uname -m输出aarch64的机器是arm64也是Harbor能支持的主流平台输出armv7l的是32位ARM跑Harbor会非常吃力哪怕把镜像换成armhf内存和磁盘也扛不住。生产服务器常见的飞腾FT-2000、鲲鹏920以及银河麒麟V10的AArch64版本都属于arm64。判断方法很简单登录服务器执行uname -m看到aarch64就按本文流程走看到x86_64则说明这台机器不是ARM别继续瞎折腾。uname -m # aarch64 - arm64可以装Harbor # armv7l - 更适合用轻量registry不建议装Harbor这里要澄清一个容易混淆的术语Docker官方叫linux/arm64有些系统里叫aarch64同一个东西。你在下载Docker二进制、拉取镜像时认准aarch64或arm64就行。如果系统里执行file /bin/bash显示ARM aarch64同样说明是64位ARM。还有一个容易踩的边界部分国产OS的uname -m会显示正常但内核或glibc版本很老。Harbor v2.4.0的镜像基于Photon OS对内核版本有隐性要求麒麟V10这类系统通常没问题但老旧的内核比如3.10跑overlay2会有文件系统兼容性问题后面会看到。2.2 在联网机器上用 docker pull save 打包 arm64 镜像的完整命令如果你拿到的离线包包含的是amd64镜像或者你想让交付更可控就需要提前打一个arm64镜像包。最可靠的方式是找一台arm64且能访问外网的机器把Harbor v2.4.0需要的镜像全部拉下来再docker save成tar。镜像清单不能拍脑袋写建议先从官方离线包或Harbor源码的Makefile里取。Harbor v2.4.0由core、jobservice、portal、registry、registryctl、db、redis、nginx、log这几个核心组件构成具体镜像名称以离线包load出来的实际列表为准。我这里给你一个通用循环脚本mkdir -p harbor-arm64-images cd harbor-arm64-images for img in \ goharbor/harbor-core:v2.4.0 \ goharbor/harbor-jobservice:v2.4.0 \ goharbor/harbor-portal:v2.4.0 \ goharbor/harbor-registry:v2.4.0 \ goharbor/harbor-registryctl:v2.4.0 \ goharbor/harbor-db:v2.4.0 \ goharbor/harbor-redis:v2.4.0 \ goharbor/harbor-nginx:v2.4.0 \ goharbor/harbor-log:v2.4.0; do docker pull $img docker save $img -o $(basename ${img%%:*})_${img##*:}.tar done说明$img形如goharbor/harbor-core:v2.4.0basename只取harbor-core文件名最终是harbor-core_v2.4.0.tar。这条命令的意义不是让你直接拿去替换离线包而是让你理解离线包里的大tar是怎么做出来的它其实就是把上述镜像save到一个file里的结果。实际部署时我更推荐保持官方离线包结构不变只把里面的harbor.v2.4.0.tar.gz用自己打的arm64 tar替换掉这样install.sh的逻辑不用改。需要注意的是docker save和docker export的区别save保存的是镜像层和元数据可以原样load回到DockerHarbor离线包要的就是这个export导出容器文件系统会丢失镜像历史不能用来做离线镜像包。如果你想偷懒只save一个harbor-core装到一半会发现其他容器连不上基础服务。校验镜像架构不能省。在拉完镜像后挨个检查for img in $(docker images --format {{.Repository}}:{{.Tag}} | grep goharbor); do echo $img - $(docker image inspect $img --format {{.Architecture}}) done输出里如果出现amd64说明拉错平台了。常见原因是你那台“联网ARM机器”其实是x86虚拟机或者Docker启用了BuildKit的跨平台模拟。这时候要优先看宿主机是不是真ARM在Docker里跑一个arch命令输出aarch64才有效。另外docker save后的tar体积不小在x86机器上拉arm64镜像需要开启仿真这种镜像虽然能save但不建议作为生产离线包因为层文件里混入模拟痕迹极端情况下装到真机上会有兼容性隐患。2.3 传包与校验SHA256比对和目录规划离线包传内网的方式很灵活管理口scp、U盘、带外挂载都行。不建议用rz传几十GB的包终端会卡死也不建议用FTP裸传容易半包。传完后第一件事是算校验值防止传输过程中损坏。sha256sum harbor.v2.4.0.tar.gz # 把输出和源机器上的 sha256 对比完全一致再继续这一步是血泪经验我有一次跳过校验解压正常install.sh跑了一半才报tar: Error is not recoverable重新传才解决。不仅是tar包Docker二进制和docker-compose二进制都应该做一次校验。目录规划建议在解压前想清楚。创建专用目录mkdir -p /opt/harbor tar -zxvf harbor-offline-installer-v2.4.0.tgz -C /opt/harbor cd /opt/harbor/harbor ls解压后你能看到这些文件以官方release常见结构为准harbor.yml.tmpl、install.sh、common.sh、LICENSE外加一个镜像归档文件。如果里面是github release的标准离线包这里还要注意版本安装脚本会检查harbor.v2.4.0.tar.gz和harbor.yml.tmpl是否齐全少了会在第一步报错。关于磁盘空间很多人以为Harbor只需要两个G实际在ARM环境里离线包本身加上解压后的镜像、日志、数据库轻松超过10G。我一般先用df -h /opt看剩余空间如果不够就把整个/opt/harbor放到独立数据盘上而不是给根目录扩容。磁盘不足的报错往往不是直接说No space而是PostgreSQL容器反复重启到后面排查会非常头疼。3. 在ARM服务器上装Docker和Docker Compose离线环境的两个前置条件Harbor是一组容器所以离线安装的第一道门槛是把Docker环境弄起来。安装方式有取舍为什么推荐二进制而不是rpm包docker-compose版本有什么讲究装完怎么确认系统没有坑这些都是我在ARM交付现场反复核对过的。3.1 离线安装Docker的三种方式与选型内网装Docker我见过三种做法。第一种是拿官方rpm包离线安装适合CentOS 7和部分银河麒麟版本但rpm依赖容易缺系统自带的老docker还可能抢占端口。第二种是直接拷贝一个已经装好Docker的镜像节点上的二进制省事但不干净容易把其他机器的systemd残留带过去。第三种是用官方静态二进制包解压后手动写systemd service依赖最少也最适合ARM场景。我一般用第三种。静态二进制包在官方release页面下载文件名类似docker-20.10.17.tgz版本号以你拿到的实际包为准。下载后解压tar -zxvf docker-20.10.17.tgz cp docker/* /usr/local/bin/ mkdir -p /etc/docker注意cp docker/*会把docker、dockerd、containerd、runc等一起拷到/usr/local/bin不需要单独装containerd。然后写daemon配置。离线环境里daemon.json不要配置registry-mirrors因为那只会让Docker在拉镜像时去连外网影响启动速度。配置如下cat /etc/docker/daemon.json EOF { data-root: /data/docker, storage-driver: overlay2, exec-opts: [native.cgroupdriversystemd], log-driver: json-file, log-opts: {max-size: 50m, max-file: 3}, mtu: 1500 } EOF这里逐一说明>cat /etc/systemd/system/docker.service EOF [Unit] DescriptionDocker Daemon Afternetwork-online.target [Service] Typenotify ExecStart/usr/local/bin/dockerd --config-file/etc/docker/daemon.json Restartalways RestartSec5 [Install] WantedBymulti-user.target EOF systemctl daemon-reload systemctl enable --now docker说明Typenotify是关键dockerd会通过sd_notify通知systemd启动成功如果不写systemd可能误判。Restartalways保证内核升级或偶发宕机后自动拉起。启动后执行docker version能看到Client和Server的版本信息就说明daemon正常。如果上面写错daemon.jsondocker会启动失败此时先跑dockerd --config-file/etc/docker/daemon.json看标准错误输出不要反复重启。3.2 docker-compose 离线安装与版本匹配Harbor v2.4.0的install.sh会调用docker-compose命令来编排容器。它不看compose文件里的version字段但会执行docker-compose up -d。所以机器上必须有这个命令。离线环境下最简单的方式是放一个静态二进制路径/usr/local/bin/docker-compose。下载时认准docker-compose-linux-aarch64在x86机器上下的程序在ARM上跑不了。chmod x docker-compose-linux-aarch64 mv docker-compose-linux-aarch64 /usr/local/bin/docker-compose docker-compose --version版本建议不要低于1.29.2。太老的compose对Harbor的配置解析会有偏差比如不识别${...}或不支持某些网络模式。如果你已经装了docker composev2插件可以用软链接方式兼容ls /usr/libexec/docker/cli-plugins/docker-compose ln -s /usr/libexec/docker/cli-plugins/docker-compose /usr/local/bin/docker-compose但不同发行版插件路径不同执行docker compose version能看是否存在。我更倾向于直接放独立二进制因为install.sh里可能检测命令路径软链接的兼容性要看运气。装完还要确认当前用户是否在docker组里或者直接用root执行install.shusermod -aG docker $(whoami) newgrp docker3.3 验证Docker和Compose可用一条命令排除存储驱动问题在跑Harbor之前先花两分钟验证Docker环境。这个验证能排除掉一大半ARM和国产化系统的基础环境问题docker info 21 | grep -E Architecture|Storage Driver|Cgroup Driver|Docker Root Dir重点看三行Architecture必须是aarch64Storage Driver必须是overlay2Cgroup Driver是systemd则说明上一步的daemon配置生效了如果是cgroupfs也不致命但建议统一。如果Storage Driver是vfs多半是系统盘文件系统不支持overlay2比如XFS没开ftype或者内核太旧。这种情况先换ext4数据盘再启动Harbor不然Registry的IO性能会非常糟糕。如果docker info正常也可以直接跑一个已经load的镜像试一下。离线环境没有外网镜像不要用docker run hello-world那会去拉镜像超时。可以随便拿本地已有的busybox或alpine跑docker run --rm --name arch-test busybox:latest uname -m # 输出 aarch64 说明容器平台正确能跑起来我这里假设离线包已经load过了如果还没有可以先跳过等下一章load完再验证。compose验证没有那么多花样docker-compose --version能打印版本号就够了真正的编排问题在install.sh阶段暴露。4. Harbor v2.4.0 离线安装与配置从tar包到Web界面前置Docker弄好后Harbor本身安装反而很快。但快不代表没有坑核心集中在三个地方镜像tar的架构、harbor.yml参数、以及install.sh执行完后的健康检查。4.1 镜像归档的load与架构检查在跑install.sh前可以先手动load镜像让架构错误提前暴露。Harbor离线包里的harbor.v2.4.0.tar.gz是docker save格式的压缩包不能用tar -zxvf解压要用docker load导入docker load -i harbor.v2.4.0.tar.gzdocker load不会立刻报架构错误它只是把镜像层导入到本地存储。所以load完必须立刻检查架构for img in $(docker images --format {{.Repository}}:{{.Tag}} | grep ^goharbor); do echo $img $(docker image inspect $img --format {{.Architecture}}) done如果你拿的是我们自己打的arm64 tar这里所有输出都应该是arm64。如果还有amd64不要继续安装回头用2.2节的方式在联网ARM机器上重新打包。这一步虽然简单但能帮你省下后面几十条容器日志的排查时间。另外load完之后用docker images | grep goharbor看一下镜像标签Harbor v2.4.0的镜像tag通常就是v2.4.0。如果同时存在多个版本安装脚本可能以compose文件里写死的tag为准不会混乱。4.2 配置harbor.ymlhostname/端口/数据目录和密码解压后的harbor.yml.tmpl是模板不能直接用需要cp harbor.yml.tmpl harbor.yml再改。由于Harbor很多组件共享这个配置改错一个字段会导致整个应用起不来。cp harbor.yml.tmpl harbor.yml vi harbor.yml关键配置如下hostname: 192.168.10.10 http: port: 80 https: port: 443 certificate: /data/harbor/certs/server.crt private_key: /data/harbor/certs/server.key harbor_admin_password: Harbor12345 data_volume: /data/harbor log: level: info rotate_count: 10 rotate_size: 100M参数含义hostname不用填DNS直接填服务器IP。如果之后客户端要通过域名访问可以把域名也解析到这个IP但hostname里的值和客户端访问地址要一致否则Harbor生成的token里的URL会错。http.port默认80。生产环境80经常被宿主业务占用建议改成8081。改完后所有客户端访问地址都要带端口。https如果暂时没有证书把整个https段落注释掉否则install.sh会要求证书文件存在。正式环境我建议用内部CA签发离线环境自签也能用。harbor_admin_password初始管理员密码装完后可以在Web界面改。千万别用默认值上生产。data_volume这是数据落盘位置建议独立挂载磁盘比如/data/harbor。一个容易被忽略的点data_volume目录的属主要和容器内用户匹配。Harbor镜像内部很多进程以非root运行如果目录是root所有PostgreSQL和registry可能没有写权限。我一般先建目录再授权mkdir -p /data/harbor chmod -R 777 /data/harbor # 开发环境快速跑生产环境不建议777而是等容器起后看日志里具体报错uid再chown到对应uid。这里先给一个可跑的方案后面避坑章详细说。4.3 执行install.sh正常输出与失败判断配置保存后直接执行./install.sh这个脚本会做四件事加载离线镜像、用harbor.yml生成docker-compose.yml、docker-compose up -d启动全部服务、最后输出访问地址。正常过程会看到若干[Step] preparing ...之类的步骤输出最终docker ps能看到一组容器harbor-core、harbor-jobservice、harbor-portal、harbor-registry、harbor-registryctl、harbor-db、harbor-redis、harbor-nginx、harbor-log。如果安装脚本中途失败最常见的是docker-compose命令不存在或harbor.yml语法问题。语法问题可以用python3 -c import yaml; yaml.safe_load(open(harbor.yml))先快速校验避免到install.sh报错才回头改。启动后立刻做两个验证。第一个看容器状态docker ps --format table {{.Names}}\t{{.Status}} | grep harbor所有容器状态应该是Up如果某个容器是Restarting就按第5章排查。第二个用HTTP探活curl -s http://127.0.0.1/api/v2.0/systeminfo能返回一段JSON说明整个服务链基本通了。注意这里探活走的是80端口如果harbor.yml改成了8081URL也要跟着改。浏览器访问http://192.168.10.10能看到登录页就用admin和harbor.yml里设置的密码登录。4.4 改配置后重新安装的正确姿势Harbor不是改完harbor.yml再执行./install.sh就自动更新的。如果只是改了端口或hostname最稳的路径是先停掉当前compose栈再重新installdocker-compose down ./install.sh这里有个后悔药docker-compose down不加-v数据卷中的镜像数据、数据库会保留如果误加了-v全部仓库数据清空。我见过不止一个同事在改配置时把仓库推倒了。如果你确实想清理重来先备份/data/harbor/database和/data/harbor/registry再动数据卷。重新install会再次load镜像如果镜像tar没有变化可以跳过加载但脚本会自动处理不用干预。5. ARM架构Harbor落地避坑5个踩过的典型问题这一章把我在ARM和国产化系统上常见的故障列出来。每条都是什么现象、什么原因、怎么解决。5.1 现象harbor-db容器反复重启日志全是文件写入失败第一次装Harbor时docker ps里看到harbor-db状态是Restartingdocker logs harbor-db报could not write to file pg_wal/000000010000000000000001: Invalid argument或者Permission denied。原因有两个一是data_volume挂在了NFS、CephFS这类网络文件系统上PostgreSQL对O_DIRECT和文件锁要求很高网络存储大概率跑不起来二是目录属主不对容器内postgres用户写不进目录。解决方法是先把data_volume改到本地ext4或xfs磁盘再确认数据目录属主。df -Th /data/harbor # 列出的文件系统应该是 ext4/xfs而不是 nfs4/ceph chown -R 999:999 /data/harbor/db # 具体uid以镜像内postgres用户为准 docker-compose down docker-compose up -d如果df -Th显示是nfs先把目录迁到本地盘再继续。属主uid如果不确定可以在容器起不来之前用docker run --rm -it --entrypoint id goharbor/harbor-db:v2.4.0 postgres查看或者直接看日志里缺的是哪个uid。这个坑在ARM环境出现频率特别高因为很多ARM服务器会把数据盘塞成LVM或者挂到阵列上格式不是本地文件系统。5.2 现象Harbor能打开登录页但登录后是502这时候登录页能加载说明nginx、portal是通的但后端core或db出了问题。查看harbor-core和harbor-db状态多半是core容器在重启。常见原因不是配置而是数据库连接串里hostname解析问题harbor.yml里hostname填了域名但/etc/hosts里没有这个域名的指向core在容器内部解析不到自己。docker logs harbor-core --tail 50 | grep -i error如果看到dial tcp: lookup xxx on 10.0.0.53:53: no such host就是hostname解析失败。解决把业务访问那个域名也加进宿主机/etc/hosts或者直接让hostname等于服务器IP。还有可能是db容器没起来导致core连库失败先按5.1把db解决再回来看core。在ARM环境里docker logs是定位问题最快的办法别一上来就重装。5.3 现象docker login通过但docker push大镜像时413或者连接中断登录能成功说明Harbor整个服务是正常的。推镜像出问题九成出在客户端到Harbor之间的转发链路上。常见部署里很多人会在Harbor前面再挂一层Nginx做域名转发而那个Nginx的client_max_body_size默认只有1m哪怕Harbor自己可以接收大镜像前置Nginx也把请求挡了。解决是在前置Nginx配置里加client_max_body_size 0;0表示不限制body大小。如果你的部署没有那层Nginx那就检查网络MTU。ARM服务器的板载网卡有时候会协商出异常MTU比如9000的巨型帧跨交换机后双方不一致push到一半就断流。Docker daemon的mtu: 1400可以强制降下来但要根据实际内网情况调。另外Harbor自带的nginx容器本身也有client_max_body_size默认是0不需要改。5.4 现象所有容器都显示Up但访问页面或拉镜像报exec format error这个现象很有迷惑性容器进程一直在但访问时连接失败看日志是standard_init_linux.go: exec format error。原因非常明确宿主机是arm64镜像却是amd64Docker load不报错只有CPU执行到二进制时才炸。解决不要继续在运行环境折腾回头把镜像包换成arm64。怎么确认按第4章的命令检查Architecture。如果是官方离线包自带的amd64镜像可以在联网机器上重新打arm64版Harbor镜像或者直接把2.2节打好的tar覆盖离线包。有人会问能不能用qemu-user模拟跑amd64技术上行生产上不建议性能损失大而且Harbor的registry在高并发下会非常糟糕。我们不推荐用模拟器糊弄宁愿多花半小时准备arm64镜像包。5.5 现象银河麒麟V10上dockerd启动失败或socket挂载权限报错国产OS上最容易碰到的是系统里预装了podman-docker或者旧版docker的systemd残留。安装新的dockerd后systemctl start docker报failed to start containerd、/var/run/docker.sock: permission denied。原因旧服务文件或socket文件还在和新的dockerd抢资源。解决把旧的包和服务文件清干净再启动。systemctl stop docker rm -f /etc/systemd/system/docker.service /etc/systemd/system/docker.socket rm -rf /var/run/docker.sock systemctl daemon-reload systemctl enable --now docker如果还是起不来先手动执行dockerd --config-file/etc/docker/daemon.json看错误。常见还有selinux拦截在daemon.json里加selinux-enabled: false。注意这里说的是技术配置生产环境安全策略按你们公司的基线来。另外有的麒麟V10版本/etc/sysconfig/docker里已经写了OPTIONS-g /data/docker会和daemon.json的data-root冲突要把冲突参数删掉。6. 进阶验证用一条push链路确认Harbor真的能扛住ARM环境6.1 从Web创建项目到docker push的完整命令安装完成后最容易忽略的是“到底能不能用”。我的习惯是不打开浏览器直接用命令行走一遍推送流程。先从Web界面或API创建一个项目比如library然后执行docker login 192.168.10.10 -u admin -p Harbor12345 docker tag busybox:latest 192.168.10.10/library/busybox:test docker push 192.168.10.10/library/busybox:test这里的busybox必须是一个arm64镜像可以用本地已有的。如果本地没有先docker save包里的任意镜像load进来再用。push成功后Harbor返回latest digest: sha256:...说明完整链路通了。这一步能把登录、权限、镜像存储、nginx转发全部验证一遍比看任何健康检查都实在。6.2 用API和数据目录确认落盘push完不要直接关掉再查两个东西。第一个是API返回的项目列表第二个是数据目录中是否有镜像层文件curl -s -u admin:Harbor12345 http://192.168.10.10/api/v2.0/projects find /data/harbor/registry -type f | head如果docker push成功但API查不到项目多半是hostname配置导致请求落到了错误服务如果数据目录里没有文件说明registry容器可能把数据写到容器层了检查data_volume是否真的生效。这里顺便看一下docker stats的输出在ARM环境里Harbor全栈的内存占用一般会在2G上下波动如果单容器明显超标比如harbor-db吃了几个G就要检查是不是有客户端连接泄漏或日志量过大。6.3 我的归档习惯离线安装包要能“一次交付多次复现”每次给客户交付完我会把整个安装上下文归档成一个目录harbor-2.4.0-arm64-on-kylinv10里面放harbor.yml、install.sh的最终日志、docker-compose.yml、所有离线包和sha256校验文件。下次换一台新机器只需照着README重放命令。我还有一个习惯把docker image inspect的架构输出做成表格贴在安装单里这能帮后来的人快速判断镜像包是否放错。这套流程的核心就是提前确认两点镜像是不是arm64数据目录是不是本地盘。这两点做对了Harbor在ARM机器上其实比想象中省心。希望帮到你。本文还有配套的精品资源点击获取
返回列表