Skip to content

私有化部署 — 交付基线与购机清单

面向采购客户机器的同事。规格由我们定 —— 这样兼容测试面才收敛,200 个客户跑的是同一种环境。

装好机器之后的部署由 nuwa 下发,chart 与排障看 Helm Chart 指南


〇、先看时间线:备案是长杆项

采购本身半天就能点完,但有两件事排在前面,必须在合同签订当周就启动:

前置项周期谁做
ICP 备案1~3 周客户(主体是客户,我们只能协助)
域名注册/转入1~3 天客户
云账号实名认证1 天客户
买机器 + 装半天我们

域名解析到中国大陆境内的服务器,没有 ICP 备案就访问不了 80/443 —— 不是"可能被查",是云厂商在接入层直接拦。买了机器装完了,客户打不开页面,这是交付里最常见的"莫名其妙延期两周"。

用境外区域(AWS 新加坡/东京等)不需要备案,但要先确认客户接受数据出境与延迟。这是商务决定,不是技术决定。

一、先定部署形态,再买机器

买什么机器完全取决于走哪一种。签合同前就要问清楚客户有没有 DBA、愿不愿意为 RDS 付月费。

形态 A:全自建形态 B:云托管中间件
MySQL集群内 Pod + 云盘RDS
Redis / RabbitMQ集群内云 Redis / 自建(见下)
机器1 台 8C16G1 台 4C16G + RDS
月成本高约 40%~80%
数据可靠性靠我们做备份云厂商托管,多可用区
出事谁扛我们云厂商
chart 配置默认mysql.deploy: false + external.host

默认推荐形态 B 的 MySQL 部分。 数据库是整个系统里唯一"丢了就完了"的组件,把它交给云厂商换来的是:不用自己做主从、不用自己盯磁盘、客户半夜删库能用云厂商的时间点恢复。多出来的月费远低于一次数据事故的代价。

RabbitMQ 反过来 —— 云托管版本各家差异大、价格贵,我们用得也浅(就是个可靠队列),留在集群内即可。Redis 两可,客户已有云 Redis 就用,没有就集群内。

形态之间可以后期切换,服务侧零改动(见 Chart 指南 §三),只需要一次数据迁移。所以拿不准时先上形态 A 也不算错。

二、容量怎么算出来的

规格不是拍脑袋。按 chart 里各服务实际声明的 requests 累加:

L1 底座(必装)

组件副本CPU requests内存 requests
gateway2400m1.0 Gi
public21000m2.0 Gi
admin-ui150m64 Mi
Nacos1250m1.0 Gi
小计1.7 C4.1 Gi

L2 业务应用:默认每个 200m / 512Mi requests、1Gi limit。整条 vem 链(user + finance + vem + socket)约 +0.8C / +2Gi requests,limits 到 4Gi。

再加上:k3s 系统组件(coredns / metrics-server / local-path)约 0.5C / 1Gi;形态 A 还要加集群内 MySQL + Redis + RabbitMQ,保守留 1.5C / 4Gi

于是:

形态requests 合计说明
B(RDS) + 底座~2.2C / 5.1Gi4C16G4C8G 装上两三个应用就开始 Pending
B + 全部应用~3.5C / 9Gi8C16G
A(集群内 MySQL) + 底座~3.7C / 9.1Gi8C16G
A + 全部应用~5C / 13Gi8C32G

内存永远比 CPU 先不够。 全是 JVM,CPU 大部分时间闲着,内存是硬占用。所以选**通用型(1:4)**而不是计算型(1:2)。

⚠️ chart 目前没有给三个 bitnami 子 chart 显式设置 resources,用的是 bitnami 自己的 preset。集群内 MySQL 在默认 preset 下对生产偏小。走形态 A 的客户,建议在客户 values 里显式压上 mysql.primary.resources,别让它按默认值跑。

三、通用采购清单

不分云厂商,每个客户都要走一遍:

  • [ ] ECS 一台,通用型(vCPU:内存 = 1:4),规格按上表
  • [ ] OS:Ubuntu 22.04 LTS —— 三家云都有、k3s 一等公民。不要 CentOS / Alinux / Amazon Linux,k3s 在这些发行版上的问题排查成本不值得
  • [ ] 系统盘 100G SSD(ESSD / SSD云硬盘 / gp3)
  • [ ] 数据盘独立一块,挂 /data不要合进系统盘 —— 重装系统时数据不丢,扩容也独立
    • 形态 A:200G 起(MySQL 数据 + 镜像 + 日志)
    • 形态 B:100G 够(镜像 + 日志 + Nacos)
  • [ ] 弹性公网 IP 一个,绑到 ECS
  • [ ] VPC:ECS 与 RDS 必须同 VPC,RDS 走内网地址
  • [ ] 安全组:仅开 22 / 80 / 443(详见 §六)
  • [ ] 对象存储 Bucket 一个(OSS / COS / S3),存 mysqldump 备份,私有读写
  • [ ] 形态 B 追加:RDS MySQL 8.0 高可用版,配置见 §五
  • [ ] 不买 SLB / CLB / ALB —— k3s 自带 servicelb,Service type=LoadBalancer 直接绑节点 80/443 + 弹性 IP。每客户每月省数百元,单节点部署下负载均衡器没有意义

关于自动化开机器

原先按"3 个独立客户"判断不上 Terraform。2026-07-28 规模重估为每年 100~200 个独立部署(约每周 4 个),手工点购按理已经过线。

目前的决定是由专职同事按本清单采购,不做 IaC。这份 checklist 因此是硬约束而不是参考 —— 规格一旦漂移,200 个客户就是 200 种环境。

四、三家云对照

规格换算规则一样,只是叫法不同。认准"通用型 / 标准型,1:4",型号迭代了按这个规则找新的就行。

阿里云腾讯云AWS
4C16Gecs.g7.xlarge(通用型 g7)S6.LARGE16(标准型 S6)m6i.xlarge
8C16Gecs.c7.2xlarge(计算型)C6.2XLARGE16c6i.2xlarge
8C32Gecs.g7.2xlargeS6.2XLARGE32m6i.2xlarge
云盘ESSD PL1增强型SSD / SSD云硬盘gp3
数据库RDS MySQL 8.0 高可用版云数据库 MySQL 8.0 高可用RDS MySQL 8.0 Multi-AZ
对象存储OSSCOSS3
镜像仓库ACRTCRECR
备份快照自动快照策略定期快照EBS Snapshot Lifecycle

镜像怎么拉过去

我们的镜像在深圳的阿里云 ACR(registry.cn-shenzhen.aliyuncs.com/hiapi-cloud)。客户机器在哪,决定了走哪条路:

客户环境拉法
阿里云,同地域(深圳)用 VPC 内网地址 registry-vpc.cn-shenzhen.aliyuncs.com,免公网流量费,快
阿里云,其它地域公网地址,或开 ACR 跨地域同步
腾讯云 / AWS只能走公网地址;流量大时考虑同步一份到客户自己的 TCR / ECR
完全无外网必须提前把镜像同步进客户内网仓库,并改 global.imageRegistry这种客户在报价阶段就要识别出来,交付工作量完全不同

⚠️ hiapi-cloud-public 含 JNI 授权保护模块,任何情况下都不能推到公开仓库。admin-ui 可以公开,它不含保护逻辑。

五、MySQL 的硬要求

这一节最容易出事,建 RDS 时就要按这个填,建完再改代价很大

要求建完还能不能改
版本8.0+
字符集utf8mb4能,但已有表要逐个转
lower_case_table_names1实例初始化后不可修改,填错只能重建实例
max_connections≥ 300
时区+08:00
账号权限必须含 DDL

为什么是 8.0+:各服务打包的是 mysql-connector-j 9.1.0,官方支持矩阵已不含 5.7。实测该驱动能连上 5.7.31,但不受官方支持,不写进交付基线。客户已有 5.7 实例想复用时,明确告知不支持。

为什么账号必须有 DDL 权限:各服务是 ddl-auto: update(Hibernate 启动时建表/加列),分表逻辑还会在运行时执行 CREATE TABLE ... LIKE给一个只有增删改查权限的账号,服务起不来。 这一点常常和客户 DBA 的安全规范冲突,要在采购阶段就摊开谈,别等装的时候才发现。

这也是 P5 Flyway 改造存在的理由 —— 迁完之后就可以收权限了,但现在还不行。

max_connections 怎么算:每个服务实例一个 Druid 连接池,maxActive 用的是 Druid 默认值 8。全部应用装满约 10 个服务、十几个副本,再加 Nacos 自己的连接,300 足够,给 500 更稳

建库

不用手工建。 chart 的 hiapi-db-init Job 会按这个客户实际开启的服务把业务库建出来(ddl-auto: update 只建表不建库,所以这一步必须有人做)。

只有一种情况要手工:客户 DBA 坚持自己建库、只给一个没有 CREATE 权限的账号。这时设 dbInit.enabled=false,并请对方按 values.yamlenabled 服务的 db 字段执行:

sql
CREATE DATABASE IF NOT EXISTS hiapi_cloud_public  DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE IF NOT EXISTS hiapi_cloud_user    DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE IF NOT EXISTS hiapi_cloud_finance DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 其余按 values.yaml 里 enabled 的服务的 db 字段

漏建的表现是该服务 CrashLoop、日志报 Unknown database 'xxx'

⚠️ 即使库是 DBA 建的,账号仍然必须有 DDL 权限 —— 建表和运行时分表都要用到,这一条没有商量余地。

六、网络与安全组

公网 ──▶ 弹性 IP ──▶ ECS(k3s servicelb 占 80/443)──▶ Ingress ──▶ gateway / admin-ui

                                              同 VPC 内网 ──▶ RDS / 云 Redis

安全组只开三个端口:

端口来源用途
22仅我们的运维出口 IPSSH
800.0.0.0/0HTTP(跳转 HTTPS)
4430.0.0.0/0HTTPS

🔴 6443 绝不对公网开放。 那是 k3s 的 API Server,暴露出去等于把整个集群的控制权挂在公网上。运维走 SSH 隧道或客户的 VPN。

同理不开:3306 / 6379 / 5672 / 8848 / 15672。要连数据库就 SSH 隧道,要看 Nacos 控制台就 kubectl port-forward

RDS 的白名单只加 ECS 的内网 IP,不加 0.0.0.0/0,也不开 RDS 公网地址。

七、备份是硬性交付物

不是"建议做",是交付验收项。 尤其形态 A —— 数据库在客户自己的机器上,除了我们没人管它。

两层,缺一不可:

做法频率保留能恢复什么
云盘快照云厂商自动快照策略每天7 天整机回滚
mysqldumpCronJob → 对象存储每天30 天单库、单表

只有快照没有 dump = 客户误删一张表时只能整机回滚,把这段时间里所有其它业务数据一起回滚掉。这个场景一定会发生。

形态 B 的客户,RDS 自带备份和时间点恢复,但仍然要做 dump 到我们能访问的对象存储 —— 客户注销云账号、欠费停机时,RDS 里的备份跟着一起没了。

八、开工前要从客户拿到的信息

买机器之前先把这张表填完,少一项就会在交付当天卡住:

缺了会怎样
云厂商 + 地域阿里云 深圳
云账号(或子账号)+ 权限能建 ECS/RDS/OSS买不了机器
访问域名admin.customer-a.comIngress host 填不了
域名是否已备案是 / 否 + 备案号见 §〇,可能延期两周
SSL 证书客户提供 / 我们签 Let's Encrypt只能先跑 HTTP
购买了哪些应用user + finance + vem决定机器规格和依赖链
是否有外网有 / 无无外网时交付工作量翻倍
运维联系人姓名/电话/微信出事找不到人
客户是否有 DBA有 → 倾向形态 B决定形态

九、交付后要交接给客户的

  • [ ] 管理后台地址 + 初始管理员账号密码(要求客户首次登录即改)
  • [ ] 这套环境的资源清单(ECS / RDS / OSS 的实例 ID 与规格)
  • [ ] 备份策略说明 + 一次真实的恢复演练记录
  • [ ] 我们的运维出口 IP(客户改安全组时不要误删)
  • [ ] 升级流程与窗口约定
  • [ ] 支持渠道与响应时效

⚠️ 中间件密码不交给客户。 密码在 nuwa 里加密保管;客户要自行运维数据库时,单独给一个只读账号。

九点五、机器到手之后:装机

不要手敲 k3s 安装命令。 nuwa 下发的交付包里带 install-k3s.sh, 它顺带把本文档里这些要求做成了硬检查(不合格直接拦,而不是装完才发现):

bash
sudo ./install-k3s.sh                   # 一台机器只跑一次,幂等
sudo DATA_DIR=/data ./install-k3s.sh    # 挂了数据盘就带上,别让 PVC 落在系统盘
sudo K3S_VERSION=v1.31.5+k3s1 ./install-k3s.sh   # 按交付批次钉版本

体检项对应本文:CPU/内存(§二,内存永远比 CPU 先不够)、磁盘、80/443/6443 占用、 发行版是否为基线的 Ubuntu 22.04、NTP 是否同步(授权票据带有效期,时钟偏了会 表现成"授权无效",而没人会往这个方向想)。

装完它会等到 traefik rollout 完成、默认 StorageClass 就位才算成功 —— 少等 traefik 就会出现"脚本说装完了,但域名还不通"。

用法与后续的 ./deploy.shnuwa 教程 §6.5

十、常见踩坑

现象原因
装完了域名打不开,IP 直连正常域名没备案,被云厂商接入层拦了
Pod 一直 Pending,describeInsufficient memory机器买小了。见 §二,内存永远比 CPU 先不够
服务起不来,Unknown database 'hiapi_cloud_xxx'hiapi-db-init Job 没跑成功,或关了 dbInit.enabled 又没手工建库,见 §五
服务起不来,建表报权限错误数据库账号没有 DDL 权限,见 §五
RDS 表名大小写行为异常lower_case_table_names 建实例时没设成 1,只能重建实例
拉镜像特别慢 / 走了公网计费阿里云同地域没用 registry-vpc. 内网地址
磁盘满了,系统盘 100%数据盘没挂 /data,或 local-path 还指在系统盘
客户说"我们有 5.7 实例能不能用"不支持,见 §五