完全无外网内网环境下的CubeStudio离线部署实践(含Harbor镜像仓库搭建)

发布时间:2026/10/8 17:11:36
完全无外网内网环境下的CubeStudio离线部署实践(含Harbor镜像仓库搭建) 1. 先说说这次需求为什么要在完全无外网的内网里部署CubeStudio前一阵接了个信创环境下的私有化部署项目客户要求把企业大模型平台 CubeStudio 部署到一套完全隔离的内网环境里。所谓“完全无外网”不是普通办公网那种“限制访问外网”而是物理隔离——服务器所在的网段连默认路由都没有DNS 解析外网域名直接超时想拉一个 pip 包、一个 docker 镜像如果没有提前准备就只能干瞪眼。这种环境在政企、金融、能源行业特别常见等保三级、分级保护、数据不出域这些要求摆在那外部镜像仓库、公共软件源全部不可达。CubeStudio 这种平台涉及模型服务、应用编排、前后端组件镜像数量少说十几个依赖关系还复杂如果没有一套完整的离线交付方案实施当天就会卡死在第一步。我这套流程跑完之后把整个路径梳理了一遍包括镜像怎么导出、Harbor 怎么在离线环境里搭起来、出网机怎么中转、内网节点怎么拉取部署以及一路踩过来的坑。这篇东西适合谁看正好要做 CubeStudio 或者类似容器化平台离线交付的实施工程师、交付运维、信创适配的同行。当然就算你部署的不是 CubeStudio只要你的环境是“内网隔离 容器化交付”这套路子一样能抄。2. 部署通路怎么选镜像直传还是出网机中转2.1 两种主流通路的核心区别完全无外网的内网部署第一步要解决的就是“镜像怎么进去”。我见过的主流做法就两种一种是“镜像导出派”在有网的出网机上把镜像拉下来打成 tar 包用移动硬盘或受控 U 盘拷进内网再导入到内网私有仓库另一种是“出网机代理派”内网节点通过一台既连内网又连外网的机器俗称出网机、跳板机做 HTTP/HTTPS 代理让 docker daemon 在拉镜像的时候走代理出去。两种方案各有适用场景。镜像导出适合“交付物固定、版本锁定”的项目一次性把镜像全部准备好进去之后不依赖外网出网机代理适合“内网节点多、镜像需要按需拉取”的情况但代理链路稳定性是个隐患而且出网机自身的安全管控、审计要求往往很高需要提前跟客户确认合规边界。我们这次最终采用的是“镜像导出 Harbor 中转”的组合镜像在出网机拉取、打包、校验拷贝进内网后推送到 Harbor 私有仓库生产节点全部从 Harbor 拉取。这样生产网段里的所有节点都不需要接触出网机符合客户安全分区的要求也便于后续做版本回滚和镜像清理。2.2 为什么需要 Harbor 而不直接 docker load有人会问镜像都拷进内网了直接在节点上docker load不就行了为什么非得搭一套 Harbor如果 CubeStudio 只是单机部署直接 load 确实省事。但生产环境往往不止一个节点——调度节点、计算节点、存储节点分开部署每个节点都要有一份镜像你还得保证所有节点上的镜像版本完全一致。直接 load 的话每个节点都要拷一份 tar 包、逐个导入十来个镜像、四五台节点光是拷文件、导镜像就得折腾大半天而且一旦版本升级又得重来一遍。Harbor 的价值在于它是内网里的“镜像分发中心”所有节点统一从它拉取版本号集中管理推送一次、处处拉取。后面 CubeStudio 升级、扩容节点时只需要把新镜像推到 Harbor新节点配置好仓库地址就能拉运维效率完全不是一个量级。从实施角度看Harbor 本身也是容器化的离线包是现成的装起来并不复杂。唯一要注意的是它的依赖组件比较多PostgreSQL、Redis、Nginx 这些离线安装时要选对离线安装包版本后面我会讲。3. 准备工作在出网机上获取镜像并打包3.1 盘点 CubeStudio 的镜像清单动手之前先把 CubeStudio 的镜像清单理清楚。一般来说一个完整的企业大模型私有化部署会包含基础运行时镜像Python、CUDA、模型推理框架、CubeStudio 自身的后端服务镜像、前端静态资源镜像、依赖的中间件镜像Redis、MinIO、向量数据库等如果涉及模型服务可能还有模型镜像。最稳妥的方式是在出网机上先装好 docker然后把 CubeStudio 的部署编排文件通常是 docker-compose.yml 或 Helm values拿过来逐个解析里面的 image 字段。我习惯用一段简单的脚本把这堆镜像名拉出来# 以 docker-compose 为例提取所有 image 字段 grep -E ^\simage: docker-compose.yml | awk {print $2} | sort -u拿到清单之后逐个确认镜像的完整地址包括 registry 前缀和 tag。这里特别要强调一定要锁定 tag不要用latest。离线环境里没有外网连接latest在外面拉的是什么版本进去之后就是什么版本可一旦你在出网机上先拉过、后面又有人更新了这个 tagtar 包里可能就是另一个版本内网里的环境就和外网不一致了。经验之谈所有镜像都固定到具体版本号比如v2.6.0并在清单文件里记录 sha256 摘要后面校验用。3.2 docker pull 与 skopeo copy 的选择拉取镜像最常见的做法是docker pull然后docker save导出。但这次我要提一个更好用的工具skopeo。docker pull需要 docker daemon 参与镜像会先落在本机 docker 的存储目录里再通过docker save打包中间多一次落盘和转换而 skopeo 是直接把镜像从远程仓库 copy 到本地目录不经过 docker daemon格式也更纯粹。# 用 skopeo 直接拉取镜像到本地目录默认格式为 docker-archive skopeo copy docker://registry.example.com/cubestudio/api-server:v2.6.0 \ docker-archive:/data/images/cubestudio-api-server-v2.6.0.tar # 如果来源仓库需要认证 skopeo copy --src-credsusername:password \ docker://registry.example.com/cubestudio/api-server:v2.6.0 \ docker-archive:/data/images/cubestudio-api-server-v2.6.0.tarskopeo 还有一个优势docker pull在镜像层多的时候会频繁和 registry 通信处理不规范的镜像比如缺少某些 metadata时容易报错skopeo 则更底层兼容性更好。不过如果你对 skopeo 不熟用docker pull docker save也完全可行只要保证版本和平台正确docker pull registry.example.com/cubestudio/api-server:v2.6.0 docker save registry.example.com/cubestudio/api-server:v2.6.0 \ -o /data/images/cubestudio-api-server-v2.6.0.tar这里提醒一句docker save 出来的 tar 包里面是镜像的所有层和 metadata但如果镜像涉及多架构比如 amd64 和 arm64默认拉取的是当前机器架构的版本。信创环境里鲲鹏、飞腾这些 arm64 服务器很常见所以要在出网机上用docker pull --platform linux/arm64或者 skopeo 指定--override-arch拉取对应架构的镜像否则拷进内网在 arm64 节点上直接跑不起来报exec format error。3.3 打包、压缩与完整性校验所有镜像拉完之后统一放到一个目录下然后分门别类处理。我是按“基础组件”和“CubeStudio 应用镜像”两个目录来放的便于后续在 Harbor 里建不同项目。先压缩再拷贝体积能小不少。模型镜像动辄几个 GB 甚至十几个 GBtar 包压缩一下传输能省不少时间cd /data/images tar -czf cubestudio-offline-images.tar.gz *.tar压缩完成后生成校验文件这个步骤别省。拷贝过程经过硬盘、U 盘万一文件损坏内网里导入到一半才发现就非常被动sha256sum cubestudio-offline-images.tar.gz sha256sums.txt进内网之后第一步就是先校验 sha256确认和出网机上的值一致再继续。这一步能挡住 90% 的“镜像加载失败”“层损坏”问题。4. Harbor 离线搭建内网私有仓库从零到可用4.1 离线安装包的准备与版本选择Harbor 的离线安装包在 GitHub Releases 页面下载文件名一般是harbor-offline-installer-v2.x.x.tgz。离线包体积大概在 1GB 左右里面包含了 Harbor 所有组件的镜像安装时不需要联网拉镜像。版本选择上有个容易忽略的点Harbor 对 docker-compose 版本有要求v2.x 一般要求 docker-compose 1.18。信创环境里操作系统可能是 CentOS 7、麒麟 V10、统信 UOS 这些自带的 docker-compose 往往比较老。我建议直接用docker-compose单独安装不要依赖系统自带的版本。还有Harbor 官方安装脚本会检查docker、docker-compose、openssl这几个命令是否存在装系统时别用精简版否则检查过不去。另外Harbor 离线包是在 x86 架构下打包的如果你要部署到 arm64 的国产化服务器上需要确认该版本是否提供 arm64 支持。Harbor v2.6 之后的版本多架构支持做得比较好旧版本在 arm64 上运行经常有坑尽量选新一点的版本。4.2 配置 harbor.yml 并安装把离线包拷进内网服务器后解压tar -xzf harbor-offline-installer-v2.10.2.tgz cd harbor cp harbor.yml.tmpl harbor.ymlharbor.yml 里核心就改几处hostname、端口、证书、密码。hostname: 192.168.209.133 http: port: 80 # https: # port: 443 # certificate: /your/cert.pem # private_key: /your/key.pem harbor_admin_password: YourStrongPassword database: password: YourDbPassword max_idle_conns: 100 max_open_conns: 900这里要做一个关键决策内网环境到底开不开 HTTPS。如果客户安全要求高必须开而且得提前准备 CA 证书让所有内网节点信任这个 CA如果只是隔离内网、安全要求没那么严格直接 HTTP 加insecure-registries配置是性价比最高的方案。我们这次是严格隔离网络节点之间没有公网暴露面所以选用了 HTTP 明文仓库配合白名单访问控制。后面我会讲这个决策带来的连锁配置。证书方面如果必须上 HTTPS用 Harbor 自带脚本生成自签证书./prepare --with-trivy # 如果启用 trivy 漏洞扫描或者手动生成openssl req -newkey rsa:4096 -nodes -sha256 \ -keyout /data/certs/harbor-key.pem \ -x509 -days 365 \ -out /data/certs/harbor.pem \ -subj /CN192.168.209.133注意自签证书的 CN 一定要和 Harbor 的 hostname 匹配否则节点拉镜像的时候会报证书校验失败。配置好之后执行安装sudo ./install.shinstall.sh 会检查环境、启动所有 Harbor 组件。安装完成后docker ps能看到 harbor-core、harbor-portal、harbor-registry、nginx、harbor-db、harbor-redis 这些容器都在运行。第一次安装如果失败重点查docker-compose logs常见的原因是端口被占用、目录权限不对。4.3 Harbor 控制台的项目与用户配置Harbor 起来之后浏览器访问http://192.168.209.133用 admin 账号登录密码是 harbor.yml 里配的 harbor_admin_password。接下来要建项目。我习惯按模块分项目cubestudio、middleware、models每个项目设置成私有然后建一个专门的机器人账号或者普通用户用于节点拉取。如果内网节点要用 docker login 拉取镜像建议建一个只读用户权限只给到对应项目的 pull 权限不要用 admin 账号分发。生产环境安全第一一张写满 admin 密码的交接文档后面出了事根本说不清是谁动的。Harbor 的机器人账号也值得用起来。在“机器人账号”里创建只读 token配置到节点的 docker 认证文件里密码管理更方便到期可以轮换。5. 镜像导入与推送让 Harbor 真正成为镜像分发中心5.1 导入到 Harbor 而不是直接推到 Harbor镜像 tar 包拷进内网后下一步是让镜像进入 Harbor。这里有一个关键选择是先在服务器上docker load然后再docker tag docker push还是直接用skopeo copy从 tar 包推到 Harbor两条路都通。先说docker load docker push这条tar 包导入到本地 docker然后 tag 成 Harbor 的地址再 push。好处是符合大多数人的习惯排查问题直观坏处是如果镜像多、层大落盘和 push 会占很多临时空间。再说skopeo copy直接从 docker-archive 格式的 tar 包推到 Harbor不经过本地 docker daemon。这个方式在批量导入时效率高得多而且不会污染本地 docker 的镜像列表skopeo copy --dest-credsadmin:YourStrongPassword \ docker-archive:/data/images/cubestudio-api-server-v2.6.0.tar \ docker://192.168.209.133/cubestudio/api-server:v2.6.0这里要注意docker-archive 格式的 tar 包里的镜像名可能和最终要推的目标名不一致skopeo copy 不需要先改 tag直接指定目标地址即可这比 docker load 少一步。我在实际项目中两种都混着用小镜像直接 docker load push大模型镜像用 skopeo省时间。5.2 批量推送脚本与版本规划如果镜像有十几个一个个手动推太痛苦。写个循环脚本#!/bin/bash HARBOR_ADDR192.168.209.133 HARBOR_USERadmin HARBOR_PASSYourStrongPassword declare -A IMAGES( [api-server]v2.6.0 [web-console]v2.6.0 [model-server]v1.3.0 [redis]7.2.4 ) for img in ${!IMAGES[]}; do ver${IMAGES[$img]} echo uploading ${img}:${ver} skopeo copy --dest-creds${HARBOR_USER}:${HARBOR_PASS} \ docker-archive:/data/images/${img}.tar \ docker://${HARBOR_ADDR}/cubestudio/${img}:${ver} \ || echo FAILED: ${img} done推送完成后在 Harbor 控制台里能看到每个镜像的 tag、大小、层数。建议在推送完第一时间记录一份镜像清单包括镜像名、tag、sha256、推送到哪个项目作为交付文档的一部分。后面 CubeStudio 做健康检查、版本回滚全靠这份清单对照。6. 内网节点拉取与 CubeStudio 部署全流程6.1 内网节点的 docker 配置与 registry 信任所有生产节点要能拉取 Harbor 里的镜像先要让 docker 信任这台 registry。如果用 HTTP需要在每台节点的 docker daemon.json 里加insecure-registries如果用 HTTPS自签证书则需要把 CA 证书放到/etc/docker/certs.d/192.168.209.133/ca.crt两个方式二选一。推荐用 insecure-registries内网隔离环境下最省事{ registry-mirrors: [], insecure-registries: [192.168.209.133], data-root: /data/docker }改完重启 dockersudo systemctl daemon-reload sudo systemctl restart docker注意如果节点是 Windows Server 2022 且用 WSL 2 跑容器Linux containersdaemon.json 的配置位置和 Linux 不一样Windows 下是在C:\ProgramData\Docker\config\daemon.json而且 WSL 的 docker 上下文要确认是docker-desktop还是default搞错了改了配置不生效后面拉镜像照样报证书错。这个我在后面排查章节单独讲。6.2 登录认证与拉取测试配置好之后每个节点先登录 Harbordocker login 192.168.209.133 -u readonly-user -p your-password然后测试拉取一个小的镜像比如 redisdocker pull 192.168.209.133/middleware/redis:7.2.4如果这里能拉下来说明节点到 Harbor 的网络是通的认证也通过了。如果卡住先ping 192.168.209.133确认网络通再用curl http://192.168.209.133/v2/手动验证 Harbor 的 API 是否响应。这里重点说一个诊断技巧docker pull 报错时把报错信息里的 URL 拿出来在节点上直接 curl 这个 URL能快速区分是网络问题、证书问题还是 Harbor 服务本身的问题而不是在 docker 配置里瞎试。拉取测试通过后生产节点不需要保留 tar 包直接从 Harbor 拉取即可。有一个小经验如果你在内网节点上先 docker load 了同样的镜像再配置了 Harbor 拉取docker 会优先使用本地已有的镜像tag 相同的情况下可能导致 Harbor 里的新版本没被拉取到。遇到这种情况先docker rmi删掉本地镜像再重新 pull确保拿到的是 Harbor 里的最新版本。6.3 CubeStudio 编排部署与数据目录规划镜像就绪后按 CubeStudio 的部署文档执行编排。一般来说是 docker-compose 或 Helm。以 docker-compose 为例mkdir -p /opt/cubestudio/data cp docker-compose.yml /opt/cubestudio/ cd /opt/cubestudio docker compose pull docker compose up -ddocker compose pull会从 Harbor 拉取所有镜像然后up -d启动。这里要说两个细节第一数据目录要提前规划。CubeStudio 涉及模型文件、向量库、日志、数据库持久化docker-compose 里的 volume 一定要映射到宿主机独立的数据盘上别放在系统盘根目录。系统盘满了容器起不来的情况我见过太多次。至少确认这几个目录/data/cubestudio/models、/data/cubestudio/postgres、/data/cubestudio/redis、/data/cubestudio/logs。第二内存和 CPU 资源要预估。企业大模型平台的调度服务、模型服务都是吃内存的大户8GB 以下内存的节点跑起来会很勉强。部署前先free -h和nproc看一眼资源低于建议值的和客户确认清楚别等容器 OOM 了再排查那时候日志刷屏也很难定位。启动完成后先看容器状态docker compose ps docker compose logs -f --tail200 api-server等所有依赖容器都是 healthy 之后访问 CubeStudio 的 Web 控制台完成初始化配置。初始化时要配置管理员账号、存储后端对接内网的 MinIO 还是 Nas、模型服务地址等。这些配置项按照项目需求填即可核心是保证配置写入的数据库和后端存储在内网里可达、可持久化。7. 排查实录离线部署过程中最容易踩的坑7.1 Harbor 推送失败dial tcp 192.168.209.133 连接不上这个报错太典型了热词里那个harbor 推送失败 get https://192.168.209.133/v2/: dial tcp 192.168.209.133: ...的场景基本就是三类原因。第一类是网络不通或者端口没开。内网环境里节点到 Harbor 服务器之间可能隔了防火墙、安全组策略80/443 端口没放行。排查方法在客户端节点上telnet 192.168.209.133 80或者nc -vz 192.168.209.133 80通了再往下查。第二类是协议不一致。仔细看报错里面是https://但你的 Harbor 可能只开了 HTTP 端口。docker 客户端默认走 HTTPS如果你配置了insecure-registries但 daemon.json 语法写错了比如 IP 带端口写错、JSON 逗号漏了docker 还是会尝试 HTTPS然后被 Harbor 的 HTTP 端口拒绝。解决办法是确认 daemon.json 里的insecure-registries是数组格式且重启 docker 生效或者显式指定docker pushhttp://192.168.209.133/cubestudio/xxxdocker 对带协议的地址会按协议走。第三类是 Harbor 服务本身没起来比如磁盘写满导致 registry 容器反复重启。登录 Harbor 服务器看docker compose ps如果 harbor-registry 容器状态是 Exited 或 Restarting看日志定位经常是/var/lib/harbor所在磁盘满了。Harbor 的 registry 存储默认在数据目录下离线导入大镜像前先确认磁盘剩余空间是镜像总大小的 2 倍以上否则推送中途报错连排查日志都来不及。7.2 自签证书导致拉取报 x509 错误如果用 HTTPS 方案节点拉取镜像时报x509: certificate signed by unknown authority基本就是证书信任链没配好。常见错误是只把证书放到了 docker 的证书目录但没有重启 docker或者证书文件名不对。docker 要求证书目录是/etc/docker/certs.d/harbor_addr/ca.crt注意是ca.crt这个固定文件名。如果你放的是harbor.pem或者其他名字docker 不认。另外如果 Harbor 地址带端口目录名要带上端口比如/etc/docker/certs.d/192.168.209.133:443/ca.crt。这一点最容易忽略。还有一种情况节点上配置了 HTTP 代理。如果 docker daemon 环境变量里有HTTP_PROXY、HTTPS_PROXY而代理出不去或者代理本身不信任 Harbor 证书会产生非常诡异的错误——看起来是连不上实际是代理拦截。内网环境我建议所有节点不要设置代理环境变量或者至少确认NO_PROXY里包含了 Harbor 的地址段。7.3 Windows Server 2022 上容器拉取异常的注意事项这次部署还涉及 Windows Server 2022 上跑 Linux containers 的场景。Windows Server 2022 要支持 Linux 容器得启用 WSL 2 后端。有个常见的坑在 Windows 上配置了daemon.json但 Docker Desktop 用的是它自己管理的 WSL 发行版里的 docker daemon两个配置根本不互通。你改了 Windows 下的 daemon.json实际拉镜像的 WSL 里的 docker 根本没读到。确认当前 docker 上下文用一个命令就行docker context ls如果是desktop-linux上下文配置在用户目录的%USERPROFILE%\.docker\daemon.jsonDocker Desktop 统一管理如果是默认上下文才是C:\ProgramData\Docker\config\daemon.json。改之前先确认你面对的是哪个 daemon改错了配置折腾一整天都不知道问题在哪。另外Windows 上 WSL 里的 docker 和 Linux 节点上的 docker 版本可能不一致有些老版本 docker 对 Harbor 的 OCI 镜像格式支持不全拉取时可能卡在 manifest 解析。建议 Windows 节点也把 docker 升级到较新的稳定版本至少 24.x 以上。7.4 离线部署后容器反复重启的快速定位手段部署完成后容器反复重启最常见的三个原因镜像架构不对arm64 节点拉到了 amd64 镜像启动直接报 exec format error、配置的环境变量或挂载目录不对、资源不足导致 OOM。架构问题最快判断方式docker inspect container_id --format{{.Architecture}}启动报错先看日志不要反复 restartdocker logs --tail 100 container_idOOM 的话dmesg -T | grep -i oom能看到内核日志。如果是模型服务反复重启大概率是显存或内存不够要么调整部署参数限制资源要么加机器。定位问题的思路是先架构、再配置、再资源按这个顺序查基本能在十分钟内锁定方向。7.5 关于镜像完整性校验的一个实际案例这次执行中出网机上有个模型镜像 tar 包有 11GB拷贝进内网时 U 盘出了次坏道拷进去的包 10.2GB明显少了。因为我们第一步就跑了 sha256 校验和出网机上的校验值对不上当场就发现了没有污染内网环境。如果是直接导入了几台节点拉取到一半报 layer 校验失败再找原因会非常痛苦。所以这一条我放在最后强调出网机打包时生成 sha256sums.txt进内网第一件事就是sha256sum -c sha256sums.txt校验通过才允许导入。这是离线交付的生命线缺了它后面的每一步都可能白做。8. 写在最后这套离线部署方案还能怎么用这次 CubeStudio 的离线部署做完最大的感受是完全无外网的内网环境真正难的其实不是部署动作本身而是部署前那一整套“搬运-校验-分发”链条的设计。镜像导出、Harbor 中转、节点拉取每一段都有各自的技术决策点选对了后面非常顺选错了排查成本成倍增加。我个人在实际操作中的体会是离线部署一定要有一个“清单思维”镜像清单、校验值清单、Harbor 项目清单、节点配置清单缺一不可。与其在环境里试错不如在纸面上把清单理清楚再动手。另外Harbor 这层中转尽量不要省哪怕只有两台节点它帮你解决的版本一致性问题远比搭建成本更有价值。如果你后续要在这个内网环境里做 CubeStudio 的升级、模型版本迭代这套 Harbor 分发的架构完全可以直接复用——新镜像从出网机打包进来推到 Harbor节点重新 pull升级完事。甚至以后要接入其他容器化组件也是同一个流程。离线部署这条路跑通一次后面就是复制粘贴的事了。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询