topfans/docs/superpowers/specs/2026-06-08-docker-to-k8s-migration-design.md

589 lines
23 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Docker → Kubernetes 迁移 设计文档
- 日期: 2026-06-08
- 涉及模块: `docker/` 全部产物、新增 `k8s/` 目录、未来四个新服务
- 现状: `docker-compose.prod.yml` 在单台 VM (`101.132.250.62`) 上跑 10 个 Go 服务 + Postgres + Redis
- 目标: 迁移到 Kubernetes,支持按"明星组"分服务器扩展,为新服务(admin/review/ai-image-gen/ai-chat)预留接入位
---
## 一、背景与动机
### 1.1 业务背景
TopFans 是一个"明星粉丝平台"。不同明星的粉丝量差异极大:
- **头部明星**: 单明星可占整平台 50%+ 流量,需要独立扩展
- **腰部明星**: 几个明星可共享资源池
- **尾部明星**: 大量冷启动明星,合并部署降低成本
运营方希望:**针对不同明星组,可以独立分配服务器资源、互不影响。**
### 1.2 当前架构瓶颈
`docker-compose.prod.yml` 是单机部署,本质限制:
| 能力 | Docker Compose | Kubernetes |
|---|---|---|
| 多机部署 | ❌ | ✅ |
| 按业务线隔离资源 | ❌ | ✅ (namespace + ResourceQuota) |
| 自动扩缩容 | ❌ | ✅ (HPA/KEDA) |
| 滚动升级 | 手动 | ✅ |
| 故障自愈 | 手动 | ✅ |
| 新增业务线 | 改 compose | helm install |
### 1.3 即将到来的新服务
代码或 PRD 中已提及、未来需要独立部署的:
| 服务 | 作用 | 复用关系 |
|---|---|---|
| `admin` | 后台管理平台(运营、客服) | 复用 userservice / 独立 DB schema |
| `review` | 审核工作流(UGC 内容审核) | 调用 assetservice / 独立 DB |
| `ai-image-gen` | AI 图片生成(镭射卡) | 当前嵌在 gateway 调用 MiniMax,可独立 |
| `ai-chat` | AI 对话(粉丝互动) | 当前是 aichatservice,可拆分 |
---
## 二、候选方案 (三个架构 + 优缺点对比)
### 2.1 方案 A:单租户架构 (应用层多租户)
**结构**: 集群里只部署**一份**完整的微服务栈,所有明星组共享,通过 `group_id` 在应用层和数据层做隔离。
```
namespace: topfans
├── gateway, userservice, assetservice, galleryservice, ...
├── postgres (一份,所有组数据混在一起,用 group_id 区分)
└── redis (一份,key 加 group: 前缀)
```
**优点**:
1. **部署最简单**: 只有一套 deployment,运维心智负担最低
2. **资源利用率最高**: 没有"为低流量组预留资源"的浪费
3. **代码改动最小**: 完全沿用现有 docker-compose 的服务间调用方式
4. **配置最少**: 只需要一份 values.yaml
**缺点**:
1.**吵市占率问题严重**: 头部明星的爆款活动会拖慢所有其他明星
2.**无法"按明星分服务器"**: 这正是用户提的核心需求
3.**故障爆炸半径大**: gateway 单点故障影响所有组
4.**扩容粒度粗**: 只能整体扩,无法精准给某个组加机器
5.**合规/数据隔离弱**: 某些明星可能有合规要求(肖像、隐私),数据物理混在一起不好处理
6.**不满足用户的根本需求**: 用户明确说"分服务器使用",此方案做不到
**适用场景**: 业务初期、流量小、组少(<3)、无合规要求
**结论**: **不推荐**与用户需求正面冲突
---
### 2.2 方案 B:共享基础服务 + 按组隔离数据服务 ⭐ 推荐
**结构**: 平台型服务全集群一份( `topfans-shared`),数据敏感型服务按组复制( `topfans-group-*`)。
```
namespace: topfans-shared (平台共享,1 份)
├── admin (未来)
├── review (未来)
├── ai-image-gen (未来)
├── ai-chat (未来)
└── (Postgres / Redis 走外部托管,K8s 内只放 ExternalName 占位)
namespace: topfans-group-<group-name> (每组 1 个,1+ 明星)
├── gateway ← 入口,组内独享
├── userservice, assetservice, galleryservice,
│ socialservice, activityservice, starbookservice,
│ taskservice, aichatservice, lasercompositor
├── ResourceQuota ← 防吵市占率
└── LimitRange ← 单 Pod 上限
Ingress (集群级)
├── *.api.example.com → 按 Host 路由
└── admin.api.example.com → topfans-shared/admin
```
**优点**:
1. **核心数据服务可按组独立扩缩容** (用户核心需求)
2. **Gateway 也按组分**,Dubbo tri:// 协议栈短 DNS 名就够用,应用代码零改动
3. **共享服务复用**: AI 模型权重不可能每组复制, shared 反而合理
4. **故障隔离**: 一个组的 gateway 挂了不影响其他组
5. **可加新组成本极低**: `helm install` 一行,无需改应用代码
6. **运维友好**: 每组 namespace 独立,`kubectl config set-context --namespace=...` 即可隔离操作
7. **ResourceQuota + LimitRange 双层防爆**: 既控总量又控单 Pod
8. **新服务天然接入**: `admin / review / ai-*` shared,一次部署全集群可用
**缺点**:
1. **管理面多**: 每组要单独做一次 helm install(可由 CI/CD 自动化)
2. **Pod 数量较多**: 9 数据服务 × N = 较多 Pod, K8s 调度能 handle
3. **DB 仍是中心化**: Postgres 走外部托管,流量大时需做读写分离或拆库(后续可加 K8s 内的只读副本 Service)
4. **AI 服务被多个组共享**: 需要做 rate limit / quota 防止某组把 AI 资源吃光(可在 gateway 层加限流)
5. **首次配置稍复杂**: 要给每组填一份 values.yaml,但模板化后还好
**适用场景**: 中型平台有明显头部尾部差异需要合规隔离为未来扩展留空间。**完全匹配用户需求**。
**结论**: **强烈推荐**
---
### 2.3 方案 C:完全独立每组(含 AI/审核/管理也复制)
**结构**: 每个明星组独立一个 namespace,里面有**完整**的服务栈,包括 admin / review / AI
```
namespace: topfans-group-a
├── gateway, userservice, assetservice, ... (9 个数据服务)
├── admin, review, ai-image-gen, ai-chat (平台服务也复制)
└── (无外部 DB,每组有独立 PG/Redis)
```
**优点**:
1. **物理级隔离**: 任何资源共享都不存在
2. **故障爆炸半径最小**: 一组全挂不影响其他组
3. **合规最优**: 数据完全分开
4. **可独立选择技术栈**: 每组可用不同版本
**缺点**:
1. **AI 模型权重不可能每组复制**: 一个 LLaVA/SD 模型几十 GB,几个组就是几 TB,启动慢内存贵
2. **运维噩梦**: N 个组要维护 N 套全栈,版本同步配置漂移都是问题
3. **资源严重浪费**: 小流量组根本用不上那么多资源
4. **新服务接入要 N 次部署**: 加一个 ai-image-gen N namespace 改一遍
5. **与用户实际需求不匹配**: 用户没要求"AI 也每组独立"
**适用场景**: 金融医疗政企等强合规且客户付费意愿足够高的场景
**结论**: **不推荐**对本业务过度设计
---
## 三、方案对比总结表
| 维度 | 方案 A 单租户 | 方案 B 共享+按组隔离 | 方案 C 完全隔离 |
|---|---|---|---|
| 部署复杂度 | 最低 | ⭐⭐ 中等 | ⭐⭐⭐ 最高 |
| 资源利用率 | ⭐⭐⭐ 最高 | ⭐⭐ 中等 | 最低 |
| 按组扩缩容 | 不支持 | 完美支持 | 完美支持 |
| 故障爆炸半径 | | (按组) | (按组) |
| 吵市占率 | 严重 | (ResourceQuota ) | 几乎无 |
| AI 资源浪费 | | (共享) | 严重(每组一份) |
| 新服务接入成本 | 1 | 1 ( shared) | N (每组) |
| 数据合规隔离 | | (逻辑隔离) | (物理隔离) |
| "分服务器"需求匹配 | | | |
| **推荐度** | | ✅✅✅ 强烈推荐 | |
---
## 四、推荐方案 (B) 详细设计
### 4.1 集群拓扑
```
K8s 集群
├── namespace: topfans-shared
│ ├── (未来) admin — Deployment + Service
│ ├── (未来) review — Deployment + Service
│ ├── (未来) ai-image-gen — Deployment + Service
│ ├── (未来) ai-chat — Deployment + Service
│ ├── postgres-ext — Service (ExternalName → RDS endpoint)
│ ├── redis-ext — Service (ExternalName → ElastiCache endpoint)
│ ├── db-credentials — Secret
│ └── oss-credentials — Secret
├── namespace: topfans-group-<group-name> (例: topfans-group-a)
│ ├── ResourceQuota (CPU/内存/Pod 总上限)
│ ├── LimitRange (单 Pod 默认值)
│ ├── gateway — Deployment + Service (ClusterIP) + ConfigMap + Secret
│ ├── userservice — Deployment + Service (ClusterIP) + ConfigMap
│ ├── assetservice — 同上
│ ├── galleryservice — 同上
│ ├── socialservice — 同上
│ ├── activityservice — 同上
│ ├── starbookservice — 同上
│ ├── taskservice — 同上
│ ├── aichatservice — 同上
│ └── lasercompositor — 同上
└── Ingress (集群级,Gateway API 或传统 Ingress)
├── group-a.api.example.com → topfans-group-a/gateway:8080
├── group-b.api.example.com → topfans-group-b/gateway:8080
├── admin.api.example.com → topfans-shared/admin:80
└── ... (按 Host 头或 path 路由)
```
### 4.2 关键设计点
#### 4.2.1 Gateway 放在每组 namespace 内 (而不是 shared)
**原因**: Dubbo `tri://` TCP 二进制协议,K8s Ingress / Service 无法做基于 HTTP Host/Path 的智能路由
gateway 放在组内,可以让组内服务间用短 DNS 名调用:
```yaml
# 组内 gateway 的环境变量 (相对原 compose 几乎无改动)
DUBBO_USER_SERVICE_URL: tri://userservice:20000 # 同 ns 短名
DUBBO_ASSET_SERVICE_URL: tri://assetservice:20003
DUBBO_SOCIAL_SERVICE_URL: tri://socialservice:20002
DUBBO_GALLERY_SERVICE_URL: tri://galleryservice:20001
DUBBO_ACTIVITY_SERVICE_URL: tri://activityservice:20004
DUBBO_TASK_SERVICE_URL: tri://taskservice:20006
DUBBO_STARBOOK_SERVICE_URL: tri://starbookservice:20005
DUBBO_AI_CHAT_SERVICE_URL: tri://aichatservice:20008
LASER_COMPOSITOR_URL: http://lasercompositor:7002
```
**应用代码零改动** 相对原 `docker-compose.prod.yml` 只需把服务名换成 K8s DNS
#### 4.2.2 Postgres / Redis 走外部托管
K8s 内只创建 `ExternalName` Service 占位:
```yaml
# topfans-shared/postgres-external.yaml
apiVersion: v1
kind: Service
metadata:
name: postgres
namespace: topfans-shared
spec:
type: ExternalName
externalName: rm-xxxxxx.mysql.rds.aliyuncs.com # 阿里云 RDS endpoint
```
**好处**:
- K8s 不需要管 StatefulSet / PVC / 备份 / 主从切换(全部交给云服务)
- 所有组共享同一份数据库,通过 `group_id` schema 层面区分
- 后续压力大了,云上一键升配即可,无需迁移数据
**所有组数据如何隔离**: 在现有表上加 `group_id` 字段,应用层做行级过滤。**这是应用层改动,不在本次 K8s 迁移范围**,但需要在设计文档里记录
#### 4.2.3 ResourceQuota + LimitRange 双层防护
```yaml
# topfans-group-a/resource-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: group-a-quota
namespace: topfans-group-a
spec:
hard:
requests.cpu: "10" # 总 CPU 申请
requests.memory: 20Gi # 总内存申请
limits.cpu: "20"
limits.memory: 40Gi
pods: "50" # 最多 50 个 Pod
persistentvolumeclaims: "5"
---
apiVersion: v1
kind: LimitRange
metadata:
name: group-a-limits
namespace: topfans-group-a
spec:
limits:
- type: Container
default:
cpu: 500m
memory: 512Mi
defaultRequest:
cpu: 100m
memory: 128Mi
max:
cpu: 2
memory: 4Gi
```
#### 4.2.4 镜像构建与推送策略
**两种选择**:
- **方式 1 (推荐)**: CI 构建镜像推送阿里云 ACR,Helm 通过 `image.tag` 引用
- **方式 2**: 维持当前 `deploy.sh` "本地 build SSH 推到服务器"流程,服务器装 containerd/nerdctl
**推荐方式 1**,原因:
- 镜像版本化管理 (`:v1.0.0`)
- 利用镜像分发,build 一次,所有 K8s 节点共享
- rollback 简单: `helm rollback topfans-group-a 1`
需要在 `Dockerfile.services` 增加 base 镜像 tag 参数(目前是 `FROM --platform=linux/amd64 alpine:3.19`, OK), CI 脚本里改 tag 即可
#### 4.2.5 健康检查修正
`docker/Dockerfile.services` 中存在 **HEALTHCHECK 端口错配 bug**:
| 服务 | 应用监听 | Dockerfile HEALTHCHECK | 状态 |
|---|---|---|---|
| galleryservice | 20001 | 21001 | 错的,会一直 fail |
| socialservice | 20002 | 21002 | 同上 |
| activityservice | 20004 | 21004 | 同上 |
| taskservice | 20006 | 21006 | 同上 |
| starbookservice | 20005 | 21005 | 同上 |
| aichatservice | 20008 | 21008 | 同上 |
其他服务端口配置正确: gateway 8080userservice 20000assetservice 20003lasercompositor 7002
K8s 迁移时,改用 `livenessProbe` / `readinessProbe` 显式配置,**顺便修复这个 bug**。
#### 4.2.6 Secrets 管理
```yaml
# topfans-group-a/gateway-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: gateway-secrets
namespace: topfans-group-a
type: Opaque
stringData:
DB_PASSWORD: <从 base64 或外部 secret store 注入>
REDIS_PASSWORD: ...
JWT_SECRET: ...
OSS_ACCESS_KEY_ID: ...
OSS_ACCESS_KEY_SECRET: ...
DIFY_API_KEY: ...
MINIMAX_API_KEY: ...
QWEN_API_KEY: ...
```
**生产建议**: 配合 [External Secrets Operator](https://external-secrets.io/) 或阿里云 KMS,不要把明文 secret 提交到 git本期先用原生 Secret 加密,后续接 secret manager
### 4.3 数据层多租户设计 (应用层改动,不在本次范围)
本次 K8s 迁移只解决编排层多组数据隔离需要在应用层做配套改动,简要列出:
| | group_id 字段 | 中间件透传 group_id |
|---|---|---|
| users | | JWT 携带 group_id |
| galleries / assets / stars | | Dubbo attachment 透传 |
| 评论/点赞/收藏 | | 同上 |
建议在另一份专门的设计文档中详细设计,**本文档不展开**。
---
## 五、目录结构
```
k8s/ (新目录,根目录同级)
├── README.md 运维使用手册
├── helm/
│ ├── topfans-shared/ Chart 1: 共享服务
│ │ ├── Chart.yaml
│ │ ├── values.yaml 默认值
│ │ ├── values-prod.yaml 生产覆盖
│ │ ├── values-dev.yaml 开发覆盖
│ │ └── templates/
│ │ ├── _helpers.tpl
│ │ ├── external-db/
│ │ │ ├── postgres-external.yaml ExternalName → RDS
│ │ │ └── redis-external.yaml ExternalName → ElastiCache
│ │ ├── admin/ (未来,.gitkeep 占位)
│ │ ├── review/ (未来)
│ │ ├── ai-image-gen/ (未来)
│ │ ├── ai-chat/ (未来)
│ │ └── secrets/
│ │ ├── db-credentials.yaml
│ │ └── oss-credentials.yaml
│ │
│ └── topfans-group/ Chart 2: 每组一份
│ ├── Chart.yaml
│ ├── values.yaml 默认值 + 文档
│ ├── values-group-a.yaml 实际组 A 配置示例
│ ├── values-group-b.yaml 实际组 B 配置示例
│ └── templates/
│ ├── _helpers.tpl
│ ├── namespace.yaml 创建组 namespace
│ ├── resource-quota.yaml
│ ├── limit-range.yaml
│ ├── gateway/ deployment + service + configmap + secret
│ ├── userservice/
│ ├── assetservice/
│ ├── galleryservice/
│ ├── socialservice/
│ ├── activityservice/
│ ├── starbookservice/
│ ├── taskservice/
│ ├── aichatservice/
│ └── lasercompositor/
└── ingress/
└── ingress.yaml 集群级 Ingress(可放 helm 也可 kubectl apply)
```
**原则**:
- `docker/` 目录保留,继续支撑本地开发 (`docker-compose.local.yml`)
- `k8s/` 是新增的部署维度, `docker/` 并存
- 未来四个新服务**不在本次实现**,只留 `.gitkeep` 占位 + README 说明
- 镜像构建继续走 `docker/Dockerfile.services` (多阶段),不重复造轮子
---
## 六、迁移计划 (建议分 4 步走)
### Step 1: K8s 基础设施 (本期)
- [ ] 在阿里云 ACK 创建测试集群 (或自建 k3s)
- [ ] 部署 nginx-ingress / cert-manager (HTTPS)
- [ ] 创建 `topfans-shared` namespace + ExternalName 占位
- [ ] 编写 `topfans-shared` Helm chart (不含未来服务)
- [ ] 编写 `topfans-group` Helm chart (含全部 9 个数据服务 + gateway)
- [ ] 准备 `values-group-a.yaml` 模板 (用现有 .env.prod 内容填充)
- [ ] 修复 Dockerfile 健康检查端口错配 bug
- [ ] 编写 README: 加新组的步骤 (`helm install` 一行)
### Step 2: 灰度切换 (本期可一并做)
- [ ] 把现有 .env.prod 的所有密钥搬到 K8s Secret
- [ ] 准备 DNS 切换预案 (`group-a.api.example.com` 先解析到 K8s, VM 保留回滚)
- [ ] 1 个非关键组(如内部测试组)切到 K8s, 1~2
- [ ] 验证: 业务功能 / 性能 / 故障恢复
### Step 3: 全量切换
- [ ] 切所有组到 K8s
- [ ] VM 上的 `docker-compose`
- [ ] 释放 VM 资源
- [ ] 第一次: 取消注释 `init-db.sql` 中所有序列同步(从手工迁移数据开始时, CLAUDE.md 规范)
### Step 4: 后续优化 (本期不做)
- [ ] External Secrets Operator
- [ ] Prometheus + Grafana
- [ ] Loki 日志收集
- [ ] ArgoCD / Flux GitOps
- [ ] HPA (HPA + 自定义指标:KEDA)
- [ ] 实施应用层多租户改造(group_id 透传)
---
## 七、风险与待定项
| 风险/待定 | 影响 | 缓解 |
|---|---|---|
| 现有 docker-compose 在生产跑,切换期间需双轨 | 资源消耗 | 测试组先切,观察 1~2 周再切正式组 |
| Postgres 走外部 RDS,数据迁移 | 数据一致性 | 用阿里云 DTS 做实时同步,切换时切流量 |
| Gateway K8s ,Dubbo ns 调用 | 服务发现 | DNS + ns 部署,无问题 |
| 镜像构建走 CI 还是保留 deploy.sh | 流程变更 | 推荐 CI,本期可先保留 deploy.sh 过渡 |
| 新服务具体技术栈未定 | 模板不完整 | `.gitkeep` 占位,后续按需填 |
| 集群选型:ACK / TKE / 自建 k3s | 成本/可控性 | 建议先 ACK 测试,稳定后定型 |
| HPA 是否启用 ( CPU / 自定义指标) | 资源效率 | 本期不开,观察流量稳定后加 |
| 多集群 / region 容灾 | 灾备 | 暂不考虑,后续规划 |
---
## 八、用户已确认的关键决策
1. **按"组"隔离资源**,每组 1 个或多个明星,可灵活组合
2. **配置格式: Helm Chart**
3. **数据库: 外部托管 (RDS/ElastiCache)**
4. **Gateway 放在每组 namespace 内** (而非 shared)
5. **新服务 (admin / review / ai-image-gen / ai-chat) 放在 `topfans-shared`**
6. **保留 `docker/` 目录,继续支撑本地开发**
---
## 九、不在本次范围
- 新服务 (admin / review / ai-image-gen / ai-chat) 的实现
- 应用层多租户改造 (group_id 字段添加与透传)
- CI/CD 流水线改造 (CI 自动构建镜像)
- 监控/日志/告警接入
- 灾备多集群
- K8s 内的 StatefulSet (Postgres/Redis 用云服务,不自己跑)
---
## 十、Spec Review Refinements
本文档经 spec-document-reviewer 审查通过 (Status: Approved)。以下为审查中识别的可执行细化项,留待 writing-plans 阶段处理:
### 10.1 前置条件:`group_id` 字段已就绪
> 来自 4.2.2 节的隐含假设
Helm chart 能成功 install 并不等于 K8s 上的多组数据隔离已生效多组隔离依赖现有 schema 已含 `group_id` (或配套 migration 已先于 K8s 部署完成)。
**实施计划中需明确**: Step 1 启动前的 blocker 验证所有数据表已有 `group_id`,或先发一份 DB migration 再做 K8s 部署
### 10.2 镜像仓库路径决策
> 来自 4.2.4 的歧义
`values.yaml` `image.repository` 必须明确指向一个 registry:
- **选项 A (推荐)**: 阿里云 ACR,`image.repository: registry.cn-shanghai.aliyuncs.com/topfans/<service>`,CI 构建推送
- **选项 B**: 自建 Harbor,`image.repository: harbor.example.com/topfans/<service>`
**实施计划中需选其一**,并写明 deploy.sh 的去留:
- 选 A: 改 deploy.sh 为 CI 触发器,服务器只拉不构建
- 选 B: 保留 deploy.sh 构建逻辑,但目标改为推 Harbor 而非本地
### 10.3 Secret 落盘策略
> 来自 4.2.6 的潜在泄漏
`values-prod.yaml` 含明文密钥会污染 git。**实施计划中需**:
-`values-prod.yaml` 加入 `.gitignore`,只提交 `values-prod.example.yaml` (空值)
- 真值由 CI/CD 注入,或用 `kubeseal` / `sops` 加密后提交
- 本期最低要求: 真值不进 git
### 10.4 数据库迁移时序
> 来自 CLAUDE.md PostgreSQL 序列同步规则 + 第 6 节 Step 3
若选择"从 VM 迁数据到 RDS"路径,需明确:
- `init-db.sql``setval(...)` 同步操作放在流量切换**之前**还是**之后**
- 推荐: 切换**前**以 Job 形式跑完,验证 `pg_sequences` 全部 `is_healthy=true` 后再切流量
- 详见 CLAUDE.md 的强制规范
### 10.5 HEALTHCHECK 修复范围
> 来自 4.2.5 的歧义
K8s 用 Helm chart 里的 `livenessProbe` / `readinessProbe`,**不再依赖 Dockerfile HEALTHCHECK**。两种选择:
- **A. 只改 K8s 探针,不动 Dockerfile**: 保持向后兼容,本地 docker-compose 仍可用
- **B. 同时修 Dockerfile**: 顺手修 bug,让 compose 也能看到正确健康状态
**推荐 A** — 本次任务专注 K8s,Dockerfile 修复单独提一个 issue。
### 10.6 跨 namespace Dubbo 调用模式 (为新服务预留)
> 来自审查中识别 — 当前 spec 未明确
当未来 `admin` / `review` 部署在 `topfans-shared` 时,它们需要调用各组的数据服务(如 review 审核 group-a 的 gallery):
```yaml
# 未来 review 服务的环境变量 (在 topfans-shared namespace)
# 需要按 group 动态获取或路由
DUBBO_GALLERY_SERVICE_URL: tri://galleryservice.topfans-group-a.svc.cluster.local:20001
DUBBO_GALLERY_SERVICE_URL_GROUP_B: tri://galleryservice.topfans-group-b.svc.cluster.local:20001
```
**当前不实现**,但 `topfans-shared` 的 chart 结构需考虑: 共享服务将来需要某种方式(配置中心/服务发现)拿到各组的服务地址。本期不展开,记入"未来工作"。
### 10.7 评审通过的完整决策
| # | 决策点 | 选择 |
|---|---|---|
| 1 | K8s 隔离粒度 | 按"组" (1+ 明星/组) |
| 2 | 配置格式 | Helm Chart |
| 3 | 数据库部署 | 外部托管 (RDS/ElastiCache) |
| 4 | Gateway 位置 | 每组 namespace 内 |
| 5 | 新服务位置 | `topfans-shared` |
| 6 | 镜像仓库 | 待定 (10.2 中 A/B 选一) |
| 7 | Docker HEALTHCHECK 修复 | 本期不动,改 K8s 探针 |
| 8 | `docker/` 目录 | 保留,继续支撑本地开发 |