topfans/k8s
2026-07-06 13:26:46 +08:00
..
helm/topfans feat:增加k8s部署 2026-07-06 13:26:46 +08:00
jobs/pg-sequence-sync feat:增加k8s部署 2026-07-06 13:26:46 +08:00
scripts feat:增加k8s部署 2026-07-06 13:26:46 +08:00
deploy.sh feat:增加k8s部署 2026-07-06 13:26:46 +08:00
README.md feat:增加k8s部署 2026-07-06 13:26:46 +08:00

TopFans K8s / Helm 部署手册 (Phase 1)

Phase 1: 单 namespace topfans 合并部署, 10 个 Go 服务 + gateway 共享一套基础设施, Postgres / Redis 走阿里云 RDS / ElastiCache ExternalName。

设计文档: ../docs/superpowers/specs/2026-06-08-docker-to-k8s-migration-design.md

⚠️ Phase 2 (按组隔离) 不在本手册范围, 见设计文档第十一章。

目录结构

k8s/
├── README.md                          # 本文件
├── deploy.sh                          # Helm / K8s 部署脚本 (主入口)
├── helm/
│   └── topfans/                       # 单个 chart, 覆盖整个 Phase 1
│       ├── Chart.yaml
│       ├── values.yaml                # 默认值 (CI/Dev 用)
│       ├── values-prod.example.yaml   # 模板 (空值, 部署时 cp 后填)
│       └── templates/
│           ├── _helpers.tpl
│           ├── 00-namespace.yaml
│           ├── gateway/ ...           # 13 个服务各自子目录
│           ├── hpa/ ...               # 3 个 HPA
│           ├── secrets/ ...           # 4 个 Secret
│           ├── external-db/ ...       # postgres / redis ExternalName
│           ├── ingress.yaml
│           ├── pg-sequence-sync.yaml  # 切流量前必跑的 hook Job
│           ├── oss-cors-init/job.yaml
│           └── future-services/ ...   # 4 个未来服务 .gitkeep
└── jobs/
    └── pg-sequence-sync/              # 独立手动跑版本 (备份用)
        ├── script.sh
        └── job-template.yaml

首次部署 (Checklist)

按顺序完成:

1. 集群与基础设施

  • 阿里云 ACK 测试集群创建 (按设计文档 §六 Step 1, 推荐)
  • nginx-ingress-controller (Helm, 集群级别)
  • cert-manager (Helm, 集群级别)
  • 创建 ClusterIssuer letsencrypt-prod (用 DNS-01 校验)
  • 创建 namespace topfans (helm install 时自动 create, 也可提前 kubectl create ns topfans)
  • 创建阿里云 RDS (PostgreSQL) + 用阿里云 DTS 把 VM 的数据迁过去
  • 创建阿里云 ElastiCache (Redis), 同步数据 (如果有)
  • PG 端连通验证: psql -h <rds-endpoint> 确认能连上, schemata 在

2. CI 镜像仓库

  • 阿里云 ACR 创建 namespace topfans, registry 是 registry.cn-shanghai.aliyuncs.com
  • CI (GitHub Actions / 阿里云云效) 配 ACR push 凭据, 跑通 gateway:v1.0.0 一个 image
  • (Dockerfile.services 多阶段构建已 OK, 无需改)

3. 真值 values-prod.yaml

推荐用交互脚本生成 (避免在 example 里写假值被误部署):

./k8s/scripts/fill-values-prod.sh
# 交互式提示输入 DB / Redis / JWT / OSS / Dify / OpenAI / SMS 真值
# 写完自动 chmod 600 + 检查 .gitignore + 用 gitleaks/detect-secrets 扫描 (如已装)

# CI 模式: 全用环境变量
./k8s/scripts/fill-values-prod.sh --non-interactive

# 写完用 sops 加密 (加密文件可入 git)
./k8s/scripts/fill-values-prod.sh --sops

# 只看不写
./k8s/scripts/fill-values-prod.sh --dry-run

手写版 (不推荐, 易出拼错):

cd k8s/helm/topfans
cp values-prod.example.yaml values-prod.yaml
chmod 600 values-prod.yaml
$EDITOR values-prod.yaml
# 重点字段:
#   global.dbExternalEndpoint: rm-xxxxxx.mysql.rds.aliyuncs.com
#   global.redisExternalEndpoint: r-xxxxxx.redis.rds.aliyuncs.com
#   services.<service>.image.tag: (CI 注入, 或先用 latest)
#   secrets.* : DB / JWT / OSS / AI / SMS 真值

⚠️ values-prod.yaml 不进 git (.gitignore 已加, 脚本会二次确认)。

4. 首次部署

cd /path/to/repo
./k8s/deploy.sh install

会自动按顺序:

  1. helm.sh/hook pre-install 创建 namespace
  2. helm.sh/hook pre-install 跑 PG sequence sync (如果 pgSequenceSync.enabled=true)
  3. helm.sh/hook pre-install 跑 oss-cors-init (Job 跑完即退)
  4. 创建所有 Service / Deployment / Secret / ConfigMap / HPA
  5. helm.sh/hook pre-install (其实是 Install 阶段) 跑完等 Pod Ready

5. Ingress 域名与 TLS

# 改 ingress 内的 host
$EDITOR k8s/helm/topfans/values-prod.yaml
# ingress.hosts[0].host: api.example.com
# ingress.tls[0].hosts[0]: api.example.com

# 解析到 nginx-ingress-controller 的 external IP
kubectl get svc -n ingress-nginx
# api.example.com A 记录 → <EXTERNAL-IP>

./k8s/deploy.sh upgrade --reuse-values

升级流程 (日常)

# 1. CI 已经把镜像推到 ACR:
#    registry.cn-shanghai.aliyuncs.com/topfans/gateway:v1.0.1
#    registry.cn-shanghai.aliyuncs.com/topfans/userservice:v1.0.1
#    ... (13 个 image 都标 v1.0.1)

# 2. 把所有 service 的 image tag 改成新版本:
./k8s/deploy.sh upgrade v1.0.1

#    实质执行:
#    helm upgrade topfans ./helm/topfans \
#        -f values-prod.yaml \
#        --set global.image.tag=v1.0.1 \
#        --wait --timeout 10m

helm upgrade --wait 会按 readinessProbe 等到所有 Pod Ready 才返回, 失败的话 Exit code 非 0, deploy.sh 提示回滚。

回滚

# 看历史
./k8s/deploy.sh history
# (helm history 通过 deploy.sh status 子命令也看得到)

# 回滚到上一版
./k8s/deploy.sh rollback

# 回滚到指定 revision
./k8s/deploy.sh rollback 3

PostgreSQL 序列同步 (Hard Blocker)

CLAUDE.md 强制规范 + 设计文档 §10.3 标记为 Hard Blocker 任何手动 INSERT id 都必须配套 setval; 切流量前必跑。

./k8s/deploy.sh sync-pg        # 同步 + 验证
./k8s/deploy.sh sync-pg --status  # 只验证

挂在 Helm 上的版本 (设计文档 §六 Step 4 提到的方案):

  • helm install / upgrade 自动跑 templates/pg-sequence-sync.yaml (helm hook, weight=-8)
  • 失败 abort deployment

何时必须手动跑 (用 deploy.sh sync-pg):

  1. 首次切流量前
  2. 任何 backfill SQL (含手动 INSERT) 后
  3. 数据迁移测试期间, 反复切换期间

Secret 管理 (最低要求)

真值 必须 通过以下任一方式入 K8s,严禁把 values-prod.yaml 入 git:

方式 说明 适用
kubectl create secret 手 kubectl create secret 加 Secret, helm 不管 1-2 人小团队
CI/CD 注入 CI 流水线 kubectl apply / helm install --set 注入 推荐
SOPS + Git values-prod.yaml sops -e 加密后入 git, CI decrypt 多环境共享
External Secrets Operator 接阿里云 KMS, 动态拉真值 Phase 2+

当前 Phase 1 默认用 kubectl create secret (最快上手), 后续切 SOPS。

监控 / 日志 (设计文档 §六 Step 6, 可选)

不阻塞 Phase 1 上线, 上线后补:

  • Prometheus Operator (集群级)
  • Grafana dashboard (按 dubbo / DB / Redis 分类)
  • Loki + Promtail (日志聚合)
  • 阿里云 ARMS (一键接入, 推荐)

常见问题

Q: helm install 报 duplicate key on secret / ServerTimeout

A: 上一次 helm install 没清干净。helm uninstall topfans 再重试。

Q: PG 序列同步失败, 报 setval: sequence_name not found

A: 说明该 BIGSERIAL 表要么不存在, 要么 sequence 名拼错, 可能表没建好。 连 RDS 验证: \d+ assets 看最下方的 Sequence: assets_id_seq 是否对得上。

Q: 容器启动后卡在 Init 或 CrashLoopBackOff

A: 看日志: kubectl logs -n topfans <pod> --previous 常见:

  • DB 连接不上: 检查 secrets/db/db.password 是否对, RDS 安全组是否放行 K8s 节点 CIDR
  • OSS 配置缺: oss-credentials Secret 没建, helm uninstall + 重装

Q: HPA 不工作

A: kubectl get hpa -n topfans 看是不是 Unknown, 通常是没有 metrics-server。 Phase 1 实施时安装 metrics-server (Helm, 一般 ingress-nginx chart 一起装)。

Q: 各服务的 healthcheck 通不过

A: 各服务的 healthcheck path 不一致, 见 values.yaml.services.<svc>.healthPath:

  • 大多数用 /health
  • statisticservice / notificationservice/healthz
  • moderationservice/ (历史原因, 不修, 见设计文档 §10.4)

参考

最后更新: 2026-07-06 (Phase 1 首版)