ARTICLE DETAIL

资讯详情

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

CubeStudio信创离线部署全流程:Harbor私有仓库与中转方案

CubeStudio信创离线部署全流程:Harbor私有仓库与中转方案 上个月我接到一个很典型的任务在一台完全无外网的内网服务器上把 CubeStudio 私有化部署起来。这也是信创环境里最常见的一种场景——网络物理隔离、机房到公网一根网线都没有一切依赖包和镜像都得靠人工搬运。当时我以为就是个 docker load 的事结果从镜像导出、Harbor 仓库搭建、再到客户端推送整整折腾了一个星期踩的坑比过去一年都多。这篇就按照我实际操作顺序把 CubeStudio 信创离线部署的全流程拆开写清楚包括镜像导出、Harbor 私有仓库搭建、出口机中转方案以及各种一定会遇到但你文档里查不到的细节。如果你也在给信创环境做交付、或者在投标之后被拉来救火这篇按顺序操作基本能落地。1. 为什么内网部署 CubeStudio 会卡在第一步信创离线部署的真实难点1.1 信创环境不只是“没有网”而是整套生态都被隔离了先说清楚信创环境和我们平时手里的云服务器完全不是一回事。你面对的不只是“不能访问公网”这一个约束而是一整套国产化生态下的限制操作系统是银河麒麟、统信 UOS 这类国产 Linux命令体系虽然和 CentOS 很像但很多细节不一样系统自带的 YUM/APT 源基本都是内网源甚至根本没有源。CPU 架构可能不是 x86常见的是鲲鹏、飞腾这类 ARM 架构也有海光、兆芯这类 x86镜像必须匹配目标机的架构否则容器跑不起来。安全模块更严格麒麟系统自带的 KYSEC、AppArmor 等机制有可能直接拦截 Docker 守护进程的某些系统调用导致容器明明拉下来了却启动不了。没有公网 DNS、没有时间同步源、没有证书吊销服务很多在互联网环境里“顺手就有”的东西在这里全得手工准备。所以真正做离线部署第一件事不是急着去导镜像而是先摸清现场环境目标机是什么架构、什么操作系统、Docker 装没装、有没有离线安装包。提示去现场之前先让对接人发一份操作系统版本、CPU 架构、内存磁盘信息过来。我曾经因为没确认架构导了三个 amd64 的镜像包到飞腾机器上docker load 倒是成功了docker run 直接报 Exec format error白跑一趟。1.2 完全无外网环境的约束清单我帮你列好了为了让你对“完全无外网”有个直观概念我把实际操作中碰到的约束整理成一张清单环节公网环境完全无外网的信创内网镜像拉取docker pull 直接拉全部依赖人工拷贝或出口机中转Harbor 安装在线执行 .sh 脚本就行需要先下载离线安装包再拷入内网Docker 安装apt/yum 一条命令需要预先准备 rpm/deb 离线包系统依赖source 自动更新连 curl、openssl、htop 都要提前收集证书同步在线校验吊销列表只能自建 CA 或者直接用 insecure registry时间同步NTP 公网源需要手动设置内网 NTP 或干脆忽略漂移这张表的意思是你在公网教程里看到的“下一步下一步”流程到这里每一步都可能中断。我这次最深的感受就是——离线部署考的不是你会不会用 Docker而是你有没有把所有依赖提前收集齐。1.3 镜像平台架构信创环境最容易翻车的隐藏坑先插一个后来让我折腾半天的知识点因为我觉得它比部署流程本身更能决定成败。CubeStudio 官方镜像默认是给 x86 的 AMD64 架构准备的但在信创现场经常遇到 ARM 架构的飞腾/鲲鹏服务器。你在导出镜像之前一定要先确认docker image inspect 镜像名 --format {{.Architecture}}或者用 manifest 查看某个远程镜像支持哪些平台docker manifest inspect 镜像名:tag如果目标机是 ARM 架构而你导成 AMD64 的包带过去了表面上整套流程都走完了最后容器起不来。这个坑最烦的地方在于报错不直观docker ps 里看不到容器docker logs 也是各种奇怪的动态链接库错误。所以我的建议是所有镜像在出口机里拉取的时候就按目标机架构拉不要偷懒。如果是多架构镜像用 --platform 参数指定docker pull --platform linux/arm64 镜像名:tag2. 开局准备三台机器的角色划分与网络规划2.1 出口机中转机到底起什么作用先解决一个概念问题既然是完全无外网的内网那镜像怎么进去靠出口机。所谓出口机就是整个内网里唯一一台被安全策略允许访问公网镜像源比如 Docker Hub、Quay的服务器它同时连着内网网络。角色很单纯从公网拉镜像、把镜像推到内网 Harbor、有时再帮忙转发一些安装包下载请求。出口机的选型不用太好x86 的普通服务器即可但注意磁盘空间要给够。因为你要在它上面缓存大量镜像数据盘 500G 以下会焦虑。我这次就栽在磁盘上导一个 CubeStudio 相关镜像的时候/var/lib/docker 直接写满了push 到 Harbor 失败排查了半天才意识到是空间问题。2.2 内网 Harbor 仓库的角色与选型Harbor 在内网里的角色很简单它是所有服务器获取镜像的唯一来源。没有它你只能每周拿 U 盘挨个服务器 docker load这显然不现实。所以先把 Harbor 当作内网的镜像分发中心配置上建议满足这几点独立一台机器不要和 CubeStudio 的应用节点挤在一起。Harbor 虽然轻但后续要存大量镜像磁盘 IO 和日志增长都不小。磁盘空间按镜像总量去准备我的参考值是至少 200G 起步如果是长期维护的项目最好 500G 以上。机器架构无所谓Harbor 本身是容器化部署x86 上跑就好它只负责存储和转发不负责跑 CubeStudio 业务。我这次把 Harbor 放在 192.168.209.133端口直接用了标准的 443没有去动默认 HTTPS 端口。原因后面会解释信创环境下标准端口能少一事。2.3 目标应用服务器的准备CubeStudio 最终装在这台机器上。你需要提前确认Docker 版本比较稳妥的是 Docker CE 20.10 以上24.x 也没问题。磁盘空间Docker 数据目录至少 100G否则 CubeStudio 的镜像和容器日志很快会写满。内存我这次用的配置是 16G跑起来之后还剩不少余量。/etc/hosts 里加上 Harbor 域名的解析比如 harbor.lan 指向 192.168.209.133避免后面因为域名解析失败而推送。这里多说一句很多人喜欢在目标机上只配置 insecure-registries、然后用 IP 访问 Harbor这样确实省了证书烦恼但如果你有多个内网仓库建议还是规范一点用域名加 CA 证书的方式。后面我专门有一节讲证书。2.4 网络放行策略提前找运维开好端口别等到现场再申请信创机房的网络策略已经事先锁好了很多端口默认不通。你需要提前和网络运维确认要开放的端口清单放行方向源目标端口用途出口机 - 内网 Harbor出口机192.168.209.133443推送镜像到 Harbor目标服务器 - 内网 Harbor目标服务器192.168.209.133443拉取镜像运维终端 - Harbor办公网192.168.209.133443、80访问 Harbor 管理界面运维终端 - 目标服务器办公网目标服务器 IP22SSH 管理用户终端 - CubeStudio办公网目标服务器 IP目标端口访问 CubeStudio 页面你看到没这里有个关键点整个内网没有一条到公网的路只有出口机的策略例外。所有镜像、依赖包的流转路径都是经由出口机做单向跳板。3. 镜像导出的三条路线离线打包、出口机中转、Harbor 复制3.1 路线 A纯离线 docker save / load适合一次性小镜像最早我用的就是最朴素的路线在一台能联网的同架构机器上 pull 镜像然后 docker save 成 tar 包用 U 盘或者管理网拷进内网再 docker load。具体命令不复杂# 出口机上操作 docker pull 镜像名:tag docker save -o cubestudio_xxx.tar 镜像名:tag # 拷入内网之后 docker load -i cubestudio_xxx.tar但这条路线有很明显的限制我实际体验下来tar 包体积很容易超几十 GU 盘拷贝时间长而且 FAT32/exFAT 对大文件支持有限拷完最好 md5sum 校验一下否则 load 到一半报错心态直接崩。绝大多数场景下你需要的不是一个镜像而是一整套依赖镜像。CubeStudio 通常带了好几个基础组件如果你一个个 save 再一个个 load顺序稍乱就容易漏。后续更新很痛苦每次都要重新拷贝一遍所有 tar 包。所以我的结论很明确这条路只适合临时跑通验证或者只有一个主镜像的场景做正式交付不可取。3.2 路线 B出口机中转docker pull 之后直接 push 到内网 Harbor这是我最终采用的方式也是国内信创项目里最主流的中转方式。核心流程只有三步在出口机上拉到目标镜像。docker tag 改成 Harbor 地址。docker push 推送到内网 Harbor。# 出口机上执行 docker login 192.168.209.133:443 -u admin -p Harbor12345 docker pull 镜像名:tag docker tag 镜像名:tag 192.168.209.133:443/cubestudio/镜像名:tag docker push 192.168.209.133:443/cubestudio/镜像名:tag这里有个细节很多人第一次会犯镜像 tag 里的仓库地址必须是 Harbor 的 IP端口否则 Docker 会把镜像名开头的 192.168.209.133 当成仓库地址去访问但实际上你没带端口于是它默认走 443如果 Harbor 不是监听在 443 就挂了。路线 B 的好处非常明显目标服务器从头到尾不需要直接接触公网镜像只需要从内网 Harbor 拉取而且如果内网有多台服务器它们全走 Harbor镜像只在出口机那一次从公网拉取后续所有分发都发生在内网安全和效率都兼顾。3.3 路线 CHarbor 复制规则自动同步适合长期维护第三种路线是 Harbor 自带的复制功能如果你维护周期长、镜像更新频繁这个最省事。原理很简单出口机上的 Harbor或者出口机本身能访问公网 Docker Registry配置一条复制规则让内网 Harbor 定期或按条件从公网源拉取镜像拉完自动出现在内网 Harbor 的项目里。在 Harbor 界面的操作路径是系统管理 - 复制管理 - 新建规则源注册表填 Docker Hub 或你指定的公网镜像仓库目标注册表选本地项目资源过滤器按镜像名前缀过滤触发方式选“手动定时”。我建议如果现场环境的出口机能和外网 Docker Registry 通信就把路线 C 配好配合路线 B 手工补充基本满足所有场景。如果出口机只能访问有限的域名那就老老实实用路线 B。3.4 选型建议一句话总结场景推荐路线一次性部署镜像少目标机单台路线 A简单直接中大型信创项目内网多台服务器路线 B 为主必须搭 Harbor依赖它分发长期运维镜像需要持续更新路线 B 路线 C 组合Harbor 复制会省很多人工CubeStudio 这种带 Web 界面和多个后端组件的平台明显属于第二、第三种所以我最终先配置 Harbor、把镜像从出口机推入 Harbor再让目标服务器从 Harbor 拉取。4. Harbor 私有仓库搭建离线安装、证书配置与 insecure registry 的取舍4.1 离线安装包准备别等到现场才去找Harbor 的安装方式很简单因为官方提供了离线安装包harbor-offline-installer-v2.x.x.tgz里面已经带好了所有镜像。你要做的只是在有网环境下把这个离线安装包和 docker-compose 二进制一起下载好拷进内网。版本选择上我这次用的是 Harbor v2.8 左右的稳定版本没有上最新的。信创环境里面稳定大于一切太新的版本在国产系统上不一定有充分验证。拷入内网后的基本安装步骤tar -xzf harbor-offline-installer-v2.8.0.tgz cd harbor cp harbor.yml.tmpl harbor.yml # 修改 harbor.yml然后执行 sudo ./install.sh注意如果目标机器的 Docker 是离线装的先将离线的 docker-compose 插件放到 /usr/local/lib/docker/cli-plugins/ 目录下否则 ./install.sh 执行时会找不到 docker compose 命令。这个细节很多人漏了install.sh 会直接失败。4.2 harbor.yml 配置要点hostname 别填 localhostharbor.yml 是整个 Harbor 安装的核心我的配置经验是hostname: 192.168.209.133 http: port: 80 https: port: 443 certificate: /data/cert/harbor.crt private_key: /data/cert/harbor.key harbor_admin_password: Harbor12345 data_volume: /data/harbor几个容易踩的坑hostname 必须填目标机器在内网里能被所有客户端访问到的地址。填 localhost 会让你自己都推不进去。data_volume 提前分配足够空间最好挂独立数据盘。harbor_admin_password 不要用太简单的默认口令信创项目交付时经常有安全评测会查弱口令。如果你想省掉 HTTPS可以把 https 段落注释掉http.port 改成 80但我不推荐这样搞理由在下面。4.3 自签证书生成SAN 必须包含 IP 和域名Harbor 默认绑定了 HTTPS你用浏览器访问时如果证书不受信任会一直提示不安全连接docker 客户端访问时则会直接报 x509 错误。解决办法就是自建一套 CA给 Harbor 签发一张带 SANSubject Alternative Name的证书。我生成证书的命令直接贴给你# 生成 CA 私钥和自签 CA 证书 openssl genrsa -out ca.key 4096 openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 \ -subj /CNHarbor-CA -out ca.crt # 生成 Harbor 服务端私钥和证书签名请求 openssl genrsa -out harbor.key 2048 openssl req -new -key harbor.key -subj /CNharbor.lan -out harbor.csr # 创建 SAN 配置文件这一步非常关键 cat ext.cnf EOF [ v3_req ] subjectAltName alt_names [ alt_names ] DNS.1 harbor.lan IP.1 192.168.209.133 EOF # 签发服务端证书 openssl x509 -req -in harbor.csr -CA ca.crt -CAkey ca.key -CAcreateserial \ -out harbor.crt -days 3650 -sha256 -extfile ext.cnf -extensions v3_req这里特别要强调 SAN 配置如果你的客户端既用 IP 访问 Harbor、也可能用域名访问 HarborSAN 里两个都要写。如果只写了 CN 域名没有 SAN 里的 IP用 IP 访问时证书校验直接失败浏览器会显示“证书与站点不匹配”。然后把 harbor.crt 和 harbor.key 放到 harbor.yml 里指定的路径重新执行 ./install.sh。4.4 客户端三种方式的取舍正规 CA、insecure registry、临时跳过校验镜像要能从目标机和出口机推送到 Harbor客户端必须先信任 Harbor 的证书。有三种做法方式一把自签 CA 导入客户端系统证书在 Linux包括麒麟/UOS上执行cp ca.crt /usr/local/share/ca-certificates/harbor-ca.crt update-ca-certificates systemctl restart docker这是最正规的做法信创验收时挑不出毛病。缺点是每台机器都要导入一次服务器多了就得靠脚本批量执行。方式二配置 insecure-registries修改 /etc/docker/daemon.json{ insecure-registries: [192.168.209.133:443] }然后重启 Docker。这个做法省掉了证书链路只要 Harbor 的 HTTPS 正常docker 会跳过证书校验直接访问。我坦白讲在内网隔离环境里这样配确实能少很多坑但安全性和合规性不适合正式交付而且如果你们甲方有等保或者安全扫描这很可能被列为问题项。方式三docker push 时临时加 --tlsverifyfalse 或者用容器引擎参数强制跳过。不推荐命令每次都要带参数脚本化部署特别容易漏。我这次用的是方式一把 ca.crt 导入所有机器虽然前期多花了几分钟但后面整条链路的报错提示都明确了排查问题不用再去怀疑证书。5. Harbor 推送失败全链路排查从“dial tcp 192.168.209.133”报错开始5.1 先把报错拆开看别一上来就查防火墙这次部署过程中我最想单独写一节的就是 Harbor 推送失败排查因为它的报错很容易让人误判方向。先看一个非常典型的报错Error response from daemon: Get https://192.168.209.133/v2/: dial tcp 192.168.209.133:443: connect: connection refused很多人的第一反应是防火墙给拦了然后又是一轮端口放行申请。但你拆开这个报错看核心信息有三个客户端访问的是 https 协议。访问的地址是 192.168.209.133:443注意后面的 :443。connection refused 表示端口没有服务监听而不是被防火墙丢弃防火墙拦截通常表现为 timeout。所以当报错里的端口是 443但你的 Harbor 实际监听在 8443或者你根本没开 HTTPS、只开了 HTTP 80就会出现 connection refused。这时候你应该先回 Harbor 机器上看监听端口而不是去开防火墙。5.2 五层检查法认清问题到底出在哪一层我在现场花了大半天总结出一套排查方法简称为五层检查法。按顺序查效率最高层级检查内容关键命令网络层端口通不通ping 目标IPtelnet IP 443服务层Harbor 容器活不活docker-compose psdocker ps 看 harbor-core协议层http 还是 https 是否匹配curl -v http://IP/v2/ 或 curl -v https://IP/v2/凭证层登录认证是否成功docker login IP:443 -u admin -p 密码配额层磁盘和项目配额df -h /data查看 Harbor 项目配额网络层是最容易确认的一条 telnet 就能得出结论。如果端口不通多半是系统防火墙或者安全策略没放行如果端口通但访问还是报错再往上层查。服务层要重点看 Harbor 的容器列表尤其是否有容器重启。Harbor 容器启动顺序有依赖如果 harbor-core 没起来其他服务大概率也是异常的。cd /data/harbor docker compose ps -a docker compose logs --tail100 harbor-core5.3 那个最容易骗人的错误镜像 tag 忘了带端口号这次部署我遇到的最坑问题是出口机访问 Harbor 一直报 connection refused但我查了端口、容器都是正常的后来才发现问题出在镜像 tag 上。我想当然地以为 Harbor 监听在 443于是 docker tag 的时候写成了docker tag cubestudio/xxx:latest 192.168.209.133/cubestudio/xxx:latest docker push 192.168.209.133/cubestudio/xxx:latest结果 push 的时候 Docker 自动拼上 https:// 并且用默认的 443 端口但我的 Harbor 因为现场端口规划实际把 HTTPS 部署在了 8443 端口上。于是 tag 里没带 8443Docker 永远在往 443 上怼报错的dial tcp 192.168.209.133:443就完美地解释了为什么“端口明明开了却连接被拒”。正确写法docker tag cubestudio/xxx:latest 192.168.209.133:8443/cubestudio/xxx:latest docker push 192.168.209.133:8443/cubestudio/xxx:latest这类“tag 没带端口” / “端口和证书不一致”的错误排查的关键就是仔细读报错末尾的地址和端口不要只看到 refused 就以为网络不通。5.4 磁盘空间与 GCHarbor 上传失败的低级却又常见的原因还有一个我后来才遇到的坑Harbor 上传大镜像时提示失败看日志是insufficient storage但明明往 Harbor 上推了几十个镜像都正常。查了一圈发现是数据盘的 inode 或者空间被撑满了。df -h /data df -i /data如果 /data 分区满了Harbor 的 registry 组件在接收镜像数据时就会报错。解决办法是扩容数据盘或者做一次 Harbor 的垃圾回收GC。GC 在 Harbor 界面的系统管理 - 垃圾回收里可以手动触发但注意提示触发 GC 前最好确认没有正在进行的镜像推送任务GC 会锁数据库推送任务会被阻塞甚至失败。我就在 GC 过程中推过镜像结果任务一直卡住最后只能重启 Harbor 容器恢复。另外Harbor 的 project 可以设置存储配额如果配额设为 10G上传超过 10G 也会报配额错误处理方式是在项目设置里把配额调大或设为不限制。6. CubeStudio 在目标机的落地部署与验证6.1 部署包获取与镜像仓库地址替换镜像推入 Harbor 之后把 CubeStudio 的部署文件拷到目标服务器。部署文件通常是 docker-compose.yml、.env 或者 config 目录。拿到之后最关键的一步就是把里面所有镜像地址改成 Harbor 仓库地址。假设原文件里的镜像是image: cubestudio/web:latest线上环境通常直接写 Docker Hub 地址或官方源到了内网全都要换成image: 192.168.209.133:8443/cubestudio/web:latest如果你嫌手改容易漏可以在部署目录里批量替换sed -i s#cubestudio/#192.168.209.133:8443/cubestudio/#g docker-compose.yml .env但替换完了一定要肉眼检查一遍所有 image 字段确认没有把端口号写错、没有把项目名拼错。数据卷挂载、端口映射也在这一版检查省得后面启动还要改。6.2 先登录 Harbor 再拉取批量 pull 比启动时被动拉取更可控在目标机上先和 Harbor 建立信任关系。如果你按前面的方案导入了 CA 证书就只需要登录认证docker login 192.168.209.133:8443 -u admin -p Harbor12345然后推荐先把 compose 文件里用到的所有镜像手动拉一遍不要直接 docker compose up。原因很简单如果其中某个镜像 tag 写错了docker compose up 会卡在 pull 阶段报错信息还特别长不如你提前把镜像列表拉出来逐条 pull哪条失败就重点排查哪条。docker compose config --images | xargs -I {} docker pull {}这条命令会把 compose 文件里所有镜像都拉取到本地。几十分钟后 docker images 里能看到完整列表再执行docker compose up -d6.3 启动后的健康检查与访问验证容器启动起来不代表部署成功。我习惯用下面这套验证流程docker compose ps 查看所有容器状态确保没有 restarting 或者 unhealthy。逐个容器看启动日志尤其关注依赖类的容器比如数据库、中间件等它们 ready 了再检查 Web 服务。访问 CubeStudio 的 Web 页面用 curl 检查 HTTP 状态码确认不是 502/504。docker compose logs --tail200 curl -I http://目标机IP:端口/另外如果你和我一样碰到过“实验室里都正常现场 Web 页面打开空白”的诡异问题大概率是前端资源路径或反向代理配置里还残留公网域名的地址。去配置里把公网域名替换成内网 IP 或内网域名。这里顺带提一句也有人问能不能直接把 CubeStudio 部署在 Windows Server 2022 上用 WSL containers 跑。我的态度是如果现场有 Linux 服务器别折腾 Windows 容器路径。WSL2 那套在纯内网环境下拉镜像、网络模式、自愈恢复都有额外的坑信创项目更是几乎看不到 Windows Server 承载这种服务的直接上 Linux 主机省心得多。6.4 一份可以直接照抄的内网部署 Checklist最后给你整理一份我这次部署来回对照的检查清单部署前逐项打勾比凭感觉操作稳得多确认目标机和出口机的 CPU 架构、操作系统版本、Docker 版本。在联网机器上下载 Harbor 离线安装包、docker-compose 二进制、CubeStudio 部署包、所需镜像的清单。出口机拉取所有镜像并把版本号、sha256 记录到交付清单。内网 Harbor 安装并配置自签 CA 证书、数据盘挂载、管理员密码。所有目标服务器导入 CA 证书并重启 Docker。出口机 / 目标机 docker login 到 Harbor。出口机将镜像 git tag 后 push 到 Harbor 对应项目。目标机 docker compose config --images 拉取全部镜像。docker compose up -d逐个检查容器日志。访问 Web 页面确认功能可登录、可操作。把镜像清单、版本号、证书备份、部署文档一并归档交付。这套流程走完CubeStudio 基本就能在生产内网里稳定跑起来了。最后再分享一点我个人的体会。信创离线部署真正难的从来不是某个命令不会写而是流程管理。镜像版本、依赖包、证书链路、端口策略任何一环没提前确认现场就会变成连环排查。把所有镜像的 sha256、Harbor 地址、证书路径都记录成一张表交付的时候这份表既是运维手册也是后续更新迭代的依据。你按这篇的顺序准备至少能把 80% 的坑提前踩平。
返回列表