
简介面向需要在银河麒麟V10ARM64架构内网环境中部署Harbor v2.4.0镜像仓库的运维与开发人员这份资源提供了完整的离线安装方案可解决国产化服务器上镜像仓库搭建、Docker集成及Kubernetes对接等实际问题。资源包共8个文件总大小约407.22MB主要包含3个Shell安装脚本负责环境预检、证书生成、安装入口、1个Harbor离线镜像包gz、1个YAML核心配置文件、license授权文件、prepare准备模块及yml.tmpl配置模板各文件职责清晰便于按需调整与分步执行。已有314人学习下载适合具备基础Docker与K8s知识、需要在信创环境下快速落地Harbor的读者。借助资源中的自动化脚本与配置模板可显著减少手工配置时间同时掌握Harbor v2.4.0在aarch64架构下的离线部署流程、关键配置项与校验方法为生产环境镜像仓库运维提供可靠参考。1. 在麒麟 V10 ARM64 上部署 Harbor v2.4.0 镜像仓库工具先把预期拉回地面在 ARM64 的国产化环境里部署 Harbor v2.4.0 镜像仓库工具听起来就是把离线安装包解压、改一行 hostname、然后跑 install.sh 的流程化操作。但实际做过的工程师都懂从离线包架构对不对、harbor.yml 哪些字段不能省到 docker login 时砸在脸上的connection refused每一步都能磨掉半天。本文以麒麟 V10 为基础系统按 ARM64 架构把 Harbor v2.4.0 从下载、配置、部署到推送验证完整走一遍适合正做国产化交付、或手里只有一台 aarch64 机器却必须把镜像仓库立起来的人。先说明白哪些坑是 ARM64 专属哪些是 Harbor 自身的通用行为省的你把无关问题当玄学调。2. 部署前环境盘点麒麟 V10 的版本与容器运行时怎么对齐 ARM642.1 先确认麒麟 V10 的 SP 小版本和 CPU 架构SP1 到 SP3 行为不一样拿到机器别急着去下载 Harbor 安装包第一步永远是确认操作系统版本和硬件架构。麒麟 V10 分为桌面版和服务器版两者在服务管理、默认防火墙策略、软件仓库来源上都有差异同一版本号底下还有 SP1、SP2、SP3 这类服务包。网上检索到的“麒麟v10 sp3下载”“虚拟机安装麒麟v10”这类问题基本都指向同一个根源系统镜像本身没选对后面什么软件都装不利索。我一般这么确认# 查看麒麟版本信息 cat /etc/kylin-release # 查看更详细的产品信息 cat /etc/.productinfo # 确认 CPU 架构aarch64 即 ARM64 uname -m lscpu | grep -E Architecture|Model nameuname -m输出aarch64说明这是一台 ARM64 机器如果是x86_64那你拿到的其实不是 ARM64 环境。另一个常见场景是用 QEMU 模拟 ARM64在 x86 宿主机上用虚拟机安装麒麟 V10 ARM64 镜像/proc/cpuinfo里会带QEMU字样。这种环境可以用来验证部署流程但性能损耗明显镜像拉取和扫描任务会慢很多我只建议把它当预演环境用。除了架构还要注意系统架构对应的软件源。麒麟 V10 桌面版 ARM64 的 yum 源如果配错成了 x86 源安装软件时会出现“软件包架构不匹配”的报错。排查命令也很简单把仓库文件打开看一眼 baseurl 里带的架构标识就行。2.2 Docker 与 docker-compose 的 ARM64 版本对齐旧包装上全翻车Harbor v2.4.0 对 Docker 版本的要求并不苛刻官方要求 Docker 17.06.0-ce 以上docker-compose 1.18.0 以上。但麒麟 V10 默认软件源里的 docker 包往往版本偏旧更麻烦的是直接在 x86 仓库里装出来的 docker 是 amd64 版在 ARM64 机器上即便装上了容器一启动就会报exec format error这就是典型的架构不对齐翻车现场。我在 ARM64 的麒麟 V10 上部署 Harbor v2.4.0 时容器引擎一般按下面的组合选组件版本建议说明Docker Engine20.10.x对 ARM64 支持成熟Harbor 2.4 官方验证过containerd1.6.x随 docker-ce 一起装别单独折腾docker-compose1.29.x 或 2.x保证系统里有docker-compose命令可被 install.sh 调用Docker 安装不建议用麒麟自带源我会先把 Docker 官方源配好# 备份原有源 mv /etc/yum.repos.d/docker-ce.repo /etc/yum.repos.d/docker-ce.repo.bak # 使用 Docker 官方源 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sed -i s/https:/http:/g /etc/yum.repos.d/docker-ce.repo yum makecache yum install -y docker-ce docker-ce-cli containerd.io如果你的麒麟 V10 机器访问外网受限常见做法是找一台相同架构的机器下载 rpm 包再拷贝进去。这里要叮嘱一句必须用 aarch64 的 rpm别图省事从 x86 机器上直接拷。Docker 装好后还要补齐 docker-compose。Harbor 离线包里的 install.sh 明确调用docker-compose这个命令如果系统里只有docker compose插件脚本会直接退出。靠谱的做法是把 compose 二进制放到/usr/local/bin并加执行权限# 以 docker-compose v2.x 为例 # 下载 aarch64 版本的 docker-compose-linux-aarch64 后执行 cp docker-compose-linux-aarch64 /usr/local/bin/docker-compose chmod x /usr/local/bin/docker-compose docker-compose --version验证 Docker 本身已经正确识别 ARM64最直接的方式是跑一个原生 arm64 测试容器docker run --rm arm64v8/alpine uname -m如果输出aarch64说明 Docker 能正常拉取并运行 ARM64 镜像。这一步通过了再继续往下走。Docker 启动后可能遇到 cgroup 版本不对、iptables 初始化失败一类问题。麒麟 V10 上比较常见的是iptables failed: cant initialize iptables table多半是因为旧版 iptables 与容器的 nft 兼容性有问题。临时方案是重启 docker 服务长期方案是按你的内核版本把 iptables 切换成 nft 模式我一般直接改 docker daemon 配置在/etc/docker/daemon.json里指定 iptables 为 false 的写法人人都会但不推荐那会让容器网络变得很难排查。3. 下载 Harbor v2.4.0 离线包并改写 harbor.yml先看清包再动手3.1 离线安装包下载与架构校验别把 amd64 的镜像包 load 到 ARM64 上Harbor v2.4.0 的发布页会同时提供在线安装器与离线安装包。ARM64 环境我强烈建议用离线包harbor-offline-installer-v2.4.0.tgz在线安装器要从 Docker Hub 现场拉镜像在内网环境经常因为网络问题卡住。离线包里面包含所有 Harbor 组件镜像以及 install.sh、harbor.yml.tmpl、docker-compose.yml 等文件。离线包下载解压后首先要确认里面的镜像压缩包与当前架构匹配。虽然 Harbor 官方在 2.4 时代已经开始推送 multi-arch 镜像但保险起见还是看一眼tar -xzf harbor-offline-installer-v2.4.0.tgz cd harbor ls -lh harbor.v2.4.0.tar.gz # 解压镜像包 docker load -i harbor.v2.4.0.tar.gzdocker load会把镜像导入本地镜像库。导入完成后抽查几个关键组件的架构信息docker image inspect goharbor/harbor-core:v2.4.0 --format {{.Os}} {{.Architecture}}如果输出linux arm64说明这份离线包在 ARM64 下可用。如果输出linux amd64说明你下载的包架构不对或者这份离线包的镜像没有带 multi-arch manifest需要重新获取适配 ARM64 的版本。有些人会问能不能在一台 Ubuntu x86 机器上把 Harbor 镜像包导出再搬到麒麟 ARM64 上 load答案是不行。Docker 镜像的层包含特定 CPU 架构的原生二进制Harbor 的 registry、core、nginx、postgres 这些组件全部是编译产物跨架构直接 load 进去能看见镜像名启动容器时立刻报exec format error。ARM64 的机器只能用 ARM64 的镜像包。3.2 harbor.yml 必改项详解hostname、密码、存储路径与日志 rotate离线包里的harbor.yml.tmpl是模板文件复制成harbor.yml后逐项修改。这份文件直接决定 Harbor 用什么协议暴露服务、数据库密码是什么、镜像数据落在哪个目录改错任何一个字段后面 install.sh 都会在 prepare 阶段给你颜色看。# 必改项 hostname: 192.168.10.10 # HTTP 配置 http: port: 80 # HTTPS 配置 # 如果暂时没有正式证书就整段注释掉 https否则 prepare 会卡在证书路径上 https: port: 443 certificate: /data/cert/harbor.crt private_key: /data/cert/harbor.key # 管理员初始密码 harbor_admin_password: Harbor12345 # 数据库密码不要和 admin 密码一样 database: password: Postgres123 max_idle_conns: 50 max_open_conns: 100 # 镜像数据存储根目录 data_volume: /data # 日志配置 log: level: info local: rotate_count: 20 rotate_size: 200M location: /var/log/harbor # Job 服务并发数 jobservice: max_job_workers: 10hostname 这一项写在文件最上面它决定了 Harbor 对外暴露的访问地址。生产环境如果有 DNS 解析可以直接写域名如果是内网部署写机器的 IP 地址最省事。我在实际项目里见过有人把 hostname 写成127.0.0.1结果推镜像时全部指向本机回环地址局域网内其它机器根本连不上。关于 https初装阶段我通常把整段注释掉让 Harbor 以纯 HTTP 模式跑通等确认整个链路没问题再补证书。Harbor 本身可以自动生成自签名证书但自签证书会带来 docker login 的 TLS 报错反而扰乱排障思路。data_volume是镜像分层、数据库文件、Redis 数据的落盘位置。麒麟 V10 上如果你把/根分区和/data放在同一个磁盘分区镜像一多磁盘很容易被打满。我建议提前用独立数据盘挂载到/data并且用df -h /data确认挂载成功后再往下走。log.local的rotate_count和rotate_size非常关键。Harbor 的日志会写到/var/log/harbor不设 rotate 的话运行一两个月单个日志文件能涨到几个 GB。后面第 5 章会专门讲这个坑。4. 执行部署与通路验证install.sh 之后的四步检查4.1 install.sh 前检查磁盘空间、目录权限与 docker-compose 版本配置文件改好之后别急着跑 install.sh。先做三个检查# 检查磁盘空间Harbor 运行时镜像 数据库 日志至少预留 50GB df -h /data # 检查数据目录权限 mkdir -p /data/cert chmod -R 755 /data # 检查 docker-compose 是否在 PATH 中且可执行 which docker-compose docker-compose version第一个检查的意义很直接Harbor 的核心镜像解压后大约占用 2GB 到 3GB 空间但运行时数据库膨胀速度快如果/data所在分区没有 50GB 以上空闲空间镜像推送到一半就可能出现磁盘满错误而那时你看到的第一反应往往是去排查网络。目录权限问题在麒麟 V10 上尤其常见。麒麟默认的 umask 与安全策略可能比 Ubuntu 更严格/data目录如果当前用户没有写权限Harbor 的 prepare 阶段会报权限不足。另外需要确认当前执行 install.sh 的用户有权限访问 docker socket最简单的方式是把部署用户加入 docker 用户组usermod -aG docker $USER newgrp dockerdocker-compose 的版本同样值得较真。麒麟 V10 自带仓库里可能有一个老旧的 docker-compose 1.x 版本而 Harbor v2.4.0 的 install.sh 会调用它来解析docker-compose.yml。如果版本过老会出现unsupported config option之类的报错。我一般直接用第 2 章提到的/usr/local/bin/docker-compose方案确保命令版本是可控的。4.2 从 docker compose ps 到第一条 push验证镜像仓库全链路一切就绪后开始安装# 执行安装如果需要 Trivy 漏洞扫描组件可加 --with-trivy ./install.shinstall.sh 会依次执行 prepare、加载镜像、启动容器。启动过程需要几分钟取决于磁盘 IO 和 CPU 性能。ARM64 机器上如果 CPU 核心少prepare 阶段生成配置和等待镜像启动的时间都会明显变长耐心等就好不要中途 CtrlC。装完之后第一件事不是打开浏览器而是看容器状态docker-compose ps正常情况下你应该看到 nginx、core、jobservice、registry、registryctl、db、redis、log 这 8 个核心容器全部处于 Up 状态。如果某个容器反复重启或处于 Exited 状态用下面的命令看日志定位docker-compose logs --tail50 服务名确认容器都活着再验证端口。Harbor 的 UI 通过 nginx 暴露HTTP 模式监听 80HTTPS 模式监听 443ss -lntp | grep -E :(80|443)然后打开浏览器访问http://192.168.10.10看到登录页后用 harbor.yml 里设置的 admin 密码登录。到这里只算装好了还不能算验证完。真正的验证是走一遍镜像推送流程。我先在 Harbor UI 里创建一个项目假设项目名是library再在命令行完成 login、tag、push# 登录 Harbor docker login http://192.168.10.10 -u admin -p Harbor12345 # 拉一个 arm64 的测试镜像 docker pull arm64v8/nginx:alpine # 打 tag docker tag arm64v8/nginx:alpine 192.168.10.10/library/nginx:arm64 # 推送 docker push 192.168.10.10/library/nginx:arm64推送成功后再把这个镜像从 Harbor 拉回来看看docker rmi 192.168.10.10/library/nginx:arm64 docker pull 192.168.10.10/library/nginx:arm64如果 push 和 pull 都成功Harbor 部署才算真正闭环。这样做的目的是把镜像存储层、认证层、网络转发层全部打通而不是只在浏览器里看到页面就宣布部署完成。另外还可以用 API 做一次快速健康检查curl -s http://192.168.10.10/api/v2.0/health返回内容包含status:healthy就说明 Harbor 组件内部通信正常。这一步会在第 6 章的脚本化检查里用到。5. ARM64 麒麟 V10 部署 Harbor 避坑指南五个血泪现场5.1 坑 1装了 x86_64 的 docker-ce容器全部报 exec format error现象docker run 一个镜像容器创建失败日志里出现exec format error或者stdin: incorrect format。原因麒麟 V10 的默认 yum 源里如果有 docker 包很可能是 x86_64 架构的。安装过程不会报错因为 rpm 包本身能装上但运行时内核发现二进制格式不对直接拒绝执行。还有一种情况是误把 amd64 的 docker-compose 或 containerd 相关包装到了 ARM64 机器上。解决先执行uname -m确认架构再检查docker info里有没有输出Architecture: aarch64。如果发现架构不一致卸载原有 docker 包重新用第 2.2 节的官方源安装 aarch64 版本。已经 load 进本地的错误架构镜像用docker images查出来再逐个docker rmi删掉。5.2 坑 2推镜像报dial tcp 192.168.x.x:443: connect: connection refused现象执行 docker push 时出现类似下面的报错Get https://192.168.10.10/v2/: dial tcp 192.168.10.10:443: connect: connection refused原因Harbor 的 nginx 容器没有监听 443 端口或者根本没有监听 443。常见情况有三种一是你明明在 harbor.yml 里把 https 整段注释了Harbor 只监听 80二是 nginx 容器启动失败端口没起来三是系统防火墙拦住了端口。解决先用ss -lntp | grep -E :(80|443)看端口是否存在。如果 443 不存在但 80 存在说明当前是 HTTP 模式那么你需要推送到 80 端口docker login http://192.168.10.10:80 -u admin -p Harbor12345 docker tag arm64v8/nginx:alpine 192.168.10.10:80/library/nginx:arm64 docker push 192.168.10.10:80/library/nginx:arm64如果端口本身存在但连接仍被拒绝检查 nginx 容器状态和日志。在麒麟 V10 上还要留意 firewalld 默认规则放行 80 和 443 端口即可。5.3 坑 3HTTP 模式配置好了docker login 仍然自动走 HTTPS现象Harbor 明确配置为 HTTP但docker login http://192.168.10.10不报端口错误却报http: server gave HTTP response to HTTPS client或者直接卡在 TLS 握手。原因Docker 客户端默认行为是对未在insecure-registries列表中的地址一律使用 HTTPS 连接。这个行为跟 Harbor 配置无关是 Docker daemon 侧的强制策略。解决编辑/etc/docker/daemon.json把 Harbor 地址加入 insecure-registries{ insecure-registries: [ 192.168.10.10:80 ] }然后重启 docker 服务systemctl restart docker注意重启 Docker 会让所有容器短暂中断Harbor 也在其中。重启后记得确认docker-compose ps里 Harbor 容器是否正常恢复。如果你后续决定启用 HTTPS这里需要把insecure-registries删掉改用正式证书避免 Docker 跳过证书校验带来的安全隐患。5.4 坑 4Harbor 跑了一周就占满磁盘日志没有 rotate现象部署时df -h /data明明还有 50GB 空间一周后容器开始异常磁盘使用率 100%。du -sh /var/log/harbor一看日志文件已经几个 GB。原因harbor.yml 里的 log 配置默认没有很激进的 rotate 策略或者你直接把 log 配置段删了用默认值。Harbor 的 core 和 jobservice 日志在主频高的机器上增长特别快尤其是推送任务多的时候jobservice 的日志一天涨几百 MB 很正常。解决在 harbor.yml 里配置 rotatelog: level: info local: rotate_count: 15 rotate_size: 100M location: /var/log/harbor重新运行 install.sh 让配置生效。另外麒麟 V10 系统自身的 journald 日志同样会占磁盘这也是网上“麒麟v10系统清理日志”检索量高的原因。顺手可以做# 限制 journald 最多占用 200M journalctl --vacuum-size200M # 永久配置 sed -i s/#SystemMaxUse/SystemMaxUse200M/ /etc/systemd/journald.conf systemctl restart systemd-journald镜像仓库里堆积的镜像层也会占空间Harbor UI 的“系统管理 → 垃圾回收”里可以手动触发 GC或者设置定时清理策略。清理之前先确认没有正在进行的推送任务。5.5 坑 5离线包或导出镜像的架构不干净load 时报 bad arm64 image magic现象执行docker load -i xxx.tar时报bad linux arm64 image magic!或 load 成功但容器一运行就崩溃。原因这个报错通常不是 Docker 镜像 tar 包而是你把虚拟机磁盘镜像、boot.img 或其他裸格式文件直接当成 docker 镜像包 load 了。还有一种常见情况在 x86 机器上用docker save导出镜像再拷贝到 ARM64 机器上 load。Docker save 导出的 tar 里带着原始平台信息如果镜像本身是 amd64 的load 时可能会报格式不识别就算 load 成功运行时的第一行就是 exec format error。解决先用file xxx.tar确认文件类型docker 镜像 tar 包的元数据应当包含 manifest.json 和 layer 目录。然后在目标机器上 load 完成执行docker image inspect 镜像名 --format {{.Os}} {{.Architecture}}看到linux arm64才说明架构匹配。这个坑特别容易出现在用 U 盘拷贝离线包、然后又从某种“ARM64 镜像合集”里复制文件的环境中。来源不对load 时低级报错一出现就容易让人误判断是 Harbor 本身的问题。6. 进阶与验证健康检查脚本、麒麟 V10 日志清理与 Harbor 版本升级6.1 用脚本把 Harbor 健康检查做成定时任务部署交付后我习惯给 Harbor 做一层最朴素的健康检查不依赖 Grafana 那类重型监控只判断“Harbor 是不是还能正常响应”。把这个脚本放到/opt/harbor-health.sh#!/bin/bash # 把下面地址替换成实际 Harbor 地址 HARBOR_ADDR192.168.10.10:80 HEALTH_CODE$(curl -s -o /dev/null -w %{http_code} http://${HARBOR_ADDR}/api/v2.0/health) if [ $HEALTH_CODE 200 ]; then echo $(date %Y-%m-%d %H:%M:%S) harbor health ok /var/log/harbor-health.log else echo $(date %Y-%m-%d %H:%M:%S) harbor health failed, code${HEALTH_CODE} /var/log/harbor-health.log # 这里可以接通知脚本比如 curl 一个告警接口 fi然后加入 crontabcrontab -e # 每 5 分钟检查一次 */5 * * * * /bin/bash /opt/harbor-health.sh这个脚本的价值不在技术含量在于它能在 Harbor 挂掉之后第一时间让你知道而不是等开发同学推镜像失败时才发现仓库早就不响应了。我见过太多环境Harbor 容器被 OOM kill 之后无人察觉直到下一次发版才暴露问题。6.2 Harbor 与麒麟 V10 的日志清理配合别直接删容器里的文件很多人在清理磁盘时会下意识去/var/lib/docker/containers里删日志文件。这个做法非常危险Docker 的经典日志文件是 JSON 格式且文件句柄被容器进程持有直接rm之后磁盘空间不会立刻释放甚至可能让 docker 进程出现未知写入错误。正确做法分两层。第一层是配置 Docker 的 log rotate编辑/etc/docker/daemon.json{ log-driver: json-file, log-opts: { max-size: 100m, max-file: 3 }, insecure-registries: [ 192.168.10.10:80 ] }重启 docker 服务后新容器才生效。第二层是清理 Harbor 自身的日志目录也就是第 5.4 节设置的/var/log/harbor。这里要提醒Harbor 容器会把日志通过 volume 映射到宿主机直接在宿主机上清理没有问题不要去容器里删文件。当 Harbor 长时间运行后数据库也可能膨胀。Harbor UI 里的 GC 是清理镜像层和未引用的 blob但数据库本身的膨胀还需要 PostgreSQL 层面的操作。低配环境可以考虑定时执行 VACUUM不过我的建议是不要随便在生产库上做这个操作除非你已经清楚 PostgreSQL 的锁机制。6.3 从 v2.4.0 升级到更高版本备份顺序与跨架构注意事项Harbor 版本升级是很多团队迟早要面对的问题。v2.4.0 还算稳定但它后续的 API 和组件镜像变化很大尤其是在 ARM64 平台上新版 Harbor 对镜像构建的 multi-arch 支持更成熟。我的升级习惯是先备份再升级最后验证。备份顺序很重要。先把容器停掉避免运行时的数据不一致docker-compose down然后备份数据库。Harbor v2.4.0 的数据库容器名是harbor-db执行# 在宿主机执行导出 PostgreSQL 全量数据 docker run --rm --volumes-from harbor-db \ -e PGPASSWORDPostgres123 \ postgres:13-alpine \ pg_dump -h harbor-db -U postgres -d registry /data/backup/registry_backup.sql再备份整个/data目录tar -czvf /data/backup/harbor-data-backup-$(date %F).tar.gz /data然后解压新版本的 Harbor 离线包复用原有的 harbor.yml执行新包的 install.sh。这里有一点要特别留意跨大版本升级前必须读官方升级文档v2.4.0 升到 v3.x 的路径和 v2.4.0 升到 v2.5.0 完全不是一回事跳过中间版本很容易造成数据迁移失败。跨架构升级也容易翻车。如果你在 x86 机器上把新版本的 Harbor 镜像包 load 好之后直接拷贝到 ARM64 机器上那就会遇到第 5.5 节的架构问题。在新版本离线包解压后仍然要在目标 ARM64 机器上确认镜像架构后再执行安装。关于升级的必要性我的看法是如果你当前 v2.4.0 跑得稳定没有遇到安全漏洞或功能瓶颈不必急着追新但如果你的麒麟 V10 环境要接入外部扫描器或对接更多项目规划一次升级是合理的。回到部署这件事本身我在麒麟 V10 ARM64 上部署 Harbor v2.4.0 的体会是这个组合并没有所谓的“特殊魔法”它只是把 ARM64 的架构约束和 Harbor 自身的配置文件要求叠加在一起。先把架构问题钉死再按官方文档一步步走大部分报错都有明确的解决路径。我第一次部署时就是被dial tcp ... connection refused带着去查防火墙绕了一大圈才发现只是配置里用了 HTTPS 而服务监听在 HTTP后来每次新环境都会先确认监听端口再判断故障方向这个习惯帮我省了大力气。希望这篇能帮到你少走几步弯路。本文还有配套的精品资源点击获取