diff --git a/xinfra/Index.md b/xinfra/Index.md index ac42fef..52a42fd 100644 --- a/xinfra/Index.md +++ b/xinfra/Index.md @@ -5,5 +5,7 @@ | 文档 | 说明 | |------|------| | [[requirements]] | 平台需求文档(功能需求 + 非功能需求 + 架构总览) | -| [[issues/001-unified-infra-platform]] | ISSUE-001:统一基础设施平台(FullSpec) | +| [[decision-record]] | PRD 优化决策记录(方案对比与决策依据) | +| [[architecture]] | 架构文档(技术选型、分层模型、系统集成) | +| [[mvp-plan]] | MVP 方案文档(实现范围、子系统评估、对接要点) | diff --git a/xinfra/issues/001-unified-infra-platform.md b/xinfra/issues/001-unified-infra-platform.md deleted file mode 100644 index 7dfb78a..0000000 --- a/xinfra/issues/001-unified-infra-platform.md +++ /dev/null @@ -1,296 +0,0 @@ -# [Proposal][Draft] 统一基础设施平台 — 跨七机房 K8s、CI/CD、数据库与缓存管理 - ---- - -## 状态 - -`proposal` - -## 规格 - -FullSpec - ---- - -## 设计点 - -**在七机房、多集群的复杂基础设施拓扑下,如何为开发者、DBA、SRE 提供一个统一的、平台化的基础设施操作入口,消除"多工具跳转 + 命令行直操"带来的效率损耗和安全风险?** - ---- - -## 动机 / 用户故事 - -周三下午 3 点,后端开发小张发现线上服务响应变慢,排查后怀疑是 Redis 大 Key 导致。他想做三件事: - -1. **看一下 Redis 实例的慢查询**——他需要登录 CacheCloud 平台,找到对应实例,翻到诊断页面 -2. **扩容一个从节点分担读压力**——他发现自己没有 CacheCloud 的运维权限,只能提工单找 SRE -3. **顺手把昨天写好的 SQL 变更推到生产库**——他需要打开 CloudDM,手动粘贴 SQL,等 DBA 审核 - -三个操作,三个平台,三套账号体系。小张在浏览器里开了五个 Tab,来回切换了半小时才把工单都提交出去。他跟旁边的同事吐槽: - -> "我就是想改个配置、扩个 Redis、上线个 SQL,怎么比写代码还累?" - -与此同时,SRE 老李正在处理一个更头疼的事——某个服务要从机房 A 迁移到机房 B,他需要手动在 Wayne 里创建新集群的 Deployment,核对 YAML 模板版本,再用 kubectl 验证 Pod 状态。整个流程没有任何自动化,全凭经验。 - -**这些场景的共同痛点是**:基础设施操作被分散在 Wayne、CloudDM、CacheCloud、Ansible、kubectl 等多个工具中,开发者需要记忆不同平台的操作路径,而关键操作(如生产发布、数据库变更)缺乏统一的审批和审计链路。 - ---- - -## 典型场景 - -### 场景一:日常发布 - -> 小张提交了一段 Go 代码到 GitLab。他希望代码合并后自动构建镜像、推送到 Harbor、然后部署到 dev 环境。部署到 prod 时需要主管审批。 -> -> **当前做法**:手动在 GitLab 触发 CI → 等镜像构建完成 → 打开 Wayne → 找到项目 → 手动填写镜像 tag → 点击发布。如果要部署到 prod,还要在企业微信群里 @主管说"帮我批一下"。 -> -> **期望做法**:代码合并后 CI 自动触发,dev 环境自动部署;prod 环境通过 Wayne 工单流审批,审批通过后自动执行。 - -### 场景二:数据库变更 - -> 小张需要给用户表加一个索引。他写好了 `ALTER TABLE` 语句。 -> -> **当前做法**:打开 CloudDM → 选择数据源 → 粘贴 SQL → 提交审核 → 等 DBA 审核 → 手动选择执行时间窗口。如果审核规则报错,他还要回来改 SQL 再重新提交。 -> -> **期望做法**:在 CloudDM 中直接编写 SQL,实时预检规则反馈,一次提交通过后自动进入 DBA 审核队列,审核通过后在指定时间窗口自动执行,结果回填工单。全程无需离开 CloudDM。 - ---- - -## 目标用户 - -### 第一目标用户 - -| 维度 | 描述 | -|------|------| -| **角色** | 后端开发工程师 | -| **行业** | 云计算 / 互联网基础设施 | -| **使用目的** | 日常服务发布、数据库变更、缓存资源申请 | -| **技术水平** | 熟悉 K8s 基本概念,但不愿直接操作 kubectl | -| **核心诉求** | "我只想写代码和发布,不想学五套平台的操作方式" | - -### 优先验证场景 - -- 七机房 RKE2 集群中的**服务发布全流程**(CI → 镜像 → Wayne 部署) -- CloudDM 的 **SQL 审核工单流**(编写 → 预检 → 审核 → 执行) - -### 本期不面向 - -- 多云成本管控的精细化运营(FR-9 为 P1/P2,本期仅做数据采集基础) -- WAF 安全策略的深度定制(FR-7 为基础防护,不做高级规则引擎) -- 非容器化部署的虚拟机管理场景 - ---- - -## 现有做法及其不足 - -| 做法 | 工具 | 不足 | -|------|------|------| -| 直接 kubectl 操作 | kubectl + kubeconfig | 无审计、无权限隔离、易误操作、yaml 散落在本地 | -| 单集群管理面板 | Rancher Dashboard | 仅管理单集群,不支持跨机房统一视图 | -| 数据库直连执行 | Navicat / DBeaver | 无审核流程、无权限分级、生产库误操作风险极高 | -| 手动部署 Redis | SSH + 手动编译 | 无标准化、无监控、无自动故障转移 | -| 脚本化部署 | Shell 脚本 | 不幂等、无版本管理、交接成本高 | - -**本项目的核心差异**: - -1. **统一入口**:开发者不需要在 5 个平台间跳转,核心操作(发布、SQL、缓存)在同一生态内闭环 -2. **审计留痕**:所有关键操作(容器发布、数据库变更、权限申请)全程可追溯,满足合规要求 -3. **平台化自治**:自助申请资源、自助发布、自助诊断,减少人工工单流转和等待时间 - ---- - -## 本期范围(P0) - -**P0 范围:** - -| # | 交付项 | 说明 | -|---|--------|------| -| 1 | RKE2 集群标准化部署 | 七机房各一套 RKE2 集群,Canal CNI,containerd 运行时,支持 Air-gap 离线部署 | -| 2 | Wayne 多集群管理接入 | 各机房集群注册到 Wayne,RBAC 权限体系(Project → Environment → Namespace),审计日志 | -| 3 | CI/CD → Wayne 全链路打通 | GitLab CI 编译 → Harbor 推送镜像 → APIKey 调用 Wayne API 触发部署,prod 环境审批卡点 | -| 4 | CloudDM SQL 审核流水线 | Console + Sidecar 部署,54 条审核规则,SQL 工单流(编写 → 预检 → DBA 审核 → 执行),全程留痕 | -| 5 | CacheCloud 基础实例管理 | 支持 Sentinel / Cluster 两种架构的实例申请、部署、监控,Agent 心跳管理 | -| 6 | Ansible 基础 Playbook | MySQL Server 和 Redis Cluster 的标准化部署 Playbook,支持多环境 Inventory | - ---- - -## 本期明确不做 - -| # | 不做的事项 | 原因 | -|---|-----------|------| -| 1 | 多云成本看板的可视化和分析 | 成本数据采集可先行,可视化为 P1 | -| 2 | WAF 高级规则引擎和自定义策略 | 基础防护即可,深度安全策略为独立安全项目 | -| 3 | 跨机房双活流量调度 | 本期仅实现网络互联和 Pod 跨机房可达,双活调度需额外方案设计 | -| 4 | CacheCloud 跨机房双写双读 | 本期支持单机房实例管理,Cross-Room 为 P1 | -| 5 | 数据库 CI/CD(Git Push 触发) | 本期走 Web UI 工单流,自动化触发为 P1 | -| 6 | Wayne Web Shell 远程终端 | 权限模型较复杂,为 P1 | -| 7 | 非 K8s 容器运行时支持(Docker) | RKE2 默认 containerd,不额外适配 Docker | - ---- - -## 关键决策与依据 - -### 决策 1:容器编排方案——RKE2 vs 原生 K8s(kubeadm)vs K3s - -| 备选方案 | 优势 | 劣势 | -|---------|------|------| -| **原生 K8s(kubeadm)** | 社区主流,文档丰富 | 部署复杂,安全加固需额外工作 | -| **K3s** | 极轻量,边缘场景友好 | 生产级特性不足,etcd 稳定性存疑 | -| **RKE2** ✅ | 单二进制部署,FIPS 140-2 合规,安全优先 | 生态略小于原生 K8s | - -**选择结果**:RKE2 - -**理由**: -- 七机房环境对安全合规有硬性要求,RKE2 的 FIPS 140-2 合规是决策性优势 -- 单二进制 + Systemd 部署大幅降低七机房集群的运维复杂度 -- Rancher 生态成熟,节点注册、证书管理等开箱即用 -- Air-gap 离线部署能力匹配内网无外网的机房环境 - ---- - -### 决策 2:多集群管理方案——Wayne vs Rancher Dashboard vs 自研 - -| 备选方案 | 优势 | 劣势 | -|---------|------|------| -| **Rancher Dashboard** | 与 RKE2 同生态,官方维护 | 偏运维视角,开发者发布体验弱;RBAC 模型较粗 | -| **自研管理平台** | 完全可控,可定制 | 开发成本高,3-6 个月才能基本可用 | -| **Wayne** ✅ | 开源成熟,发布流程完善,API 开放 | 360 维护活跃度不确定,需内部 Fork | - -**选择结果**:Wayne(内部 Fork) - -**理由**: -- Wayne 的 Project → Environment → Namespace 三级结构天然匹配多机房、多环境的管理需求 -- 内置审计模块和 APIKey 开放接口,CI/CD 对接开箱可用 -- Beego(Go)后端与团队技术栈一致,二次开发成本可控 -- 内部 Fork 降低上游停更风险,核心模块可自行维护 - ---- - -### 决策 3:数据库管控方案——CloudDM vs Yearning vs 自研审核网关 - -| 备选方案 | 优势 | 劣势 | -|---------|------|------| -| **Yearning** | 轻量,社区活跃 | 功能偏 SQL 审核,缺少数据查询和脱敏能力 | -| **自研审核网关** | 完全可控 | 需自建权限、工单、审核规则引擎,工作量大 | -| **CloudDM** ✅ | 功能全面(查询+审核+脱敏+CI/CD),支持 20+ 数据源 | 较重,需评估资源开销 | - -**选择结果**:CloudDM - -**理由**: -- 不仅仅是 SQL 审核,数据查询、权限管控、数据脱敏一体化,避免后期再引入多个工具 -- 54 条内置审核规则 + 自定义扩展,满足当前和可预见的审核需求 -- Console + Sidecar 架构支持跨机房数据库统一管理,匹配七机房拓扑 -- 统一认证(LDAP/OIDC)可与公司现有账号体系对接 - ---- - -## 基本概念与信息结构 - -### 核心实体 - -| 实体 | 定义 | 关键属性 | -|------|------|---------| -| **Cluster** | 一个机房的 RKE2 集群实例 | clusterId, datacenter, cidr, status | -| **Project** | Wayne 中的项目分组,对应一个业务团队 | projectId, name, department, owner | -| **Environment** | 部署环境,隔离不同阶段 | envId, type(dev/staging/prod), clusterId | -| **Deployment** | 一次服务部署记录 | deployId, projectId, envId, imageTag, status, rollbackTarget | -| **SQLTicket** | CloudDM 的 SQL 审核工单 | ticketId, datasourceId, sqlContent, auditStatus, executor, scheduledAt | -| **RedisInstance** | CacheCloud 管理的 Redis 实例 | instanceId, appId, arch(sentinel/cluster), memoryMB, nodes[], status | -| **PlaybookRun** | Ansible Playbook 的一次执行记录 | runId, playbookName, inventory, status, diffOutput | - -### 数据示例 - -```json -{ - "deployment": { - "deployId": "dep-20260708-001", - "projectId": "proj-qiniu-cdn", - "environment": "prod", - "cluster": { - "clusterId": "rke2-bjdc-01", - "datacenter": "北京机房 A" - }, - "image": { - "registry": "harbor.internal.qiniu.com", - "repository": "cdn/edge-proxy", - "tag": "v2.3.1-abc1234" - }, - "replicas": 3, - "strategy": "RollingUpdate", - "status": "deploying", - "triggeredBy": "gitlab-ci", - "auditLog": [ - { - "action": "create", - "operator": "ci-bot", - "timestamp": "2026-07-08T14:00:00+08:00" - }, - { - "action": "approve", - "operator": "zhangwei@qiniu.com", - "timestamp": "2026-07-08T14:02:30+08:00", - "comment": "LGTM, 已在 staging 验证通过" - } - ] - } -} -``` - -```json -{ - "sqlTicket": { - "ticketId": "sql-20260708-042", - "datasource": { - "id": "ds-user-center-prod", - "type": "MySQL", - "host": "10.1.2.3", - "database": "user_center" - }, - "sqlContent": "ALTER TABLE users ADD INDEX idx_phone (phone) USING BTREE;", - "type": "DDL", - "auditResult": { - "passed": true, - "rulesChecked": 54, - "warnings": [ - { - "rule": "DDL-MUST-HAVE-WHERE", - "level": "info", - "message": "ALTER TABLE 语句,建议在低峰期执行" - } - ] - }, - "status": "approved", - "executor": "dba-liwei@qiniu.com", - "scheduledAt": "2026-07-09T03:00:00+08:00", - "executionResult": null - } -} -``` - -```json -{ - "redisInstance": { - "instanceId": "redis-order-cache-01", - "appId": "app-order-service", - "architecture": "sentinel", - "memoryMB": 4096, - "nodes": [ - { "role": "master", "host": "10.2.1.10", "port": 6379 }, - { "role": "slave", "host": "10.2.1.11", "port": 6379 }, - { "role": "sentinel", "host": "10.2.1.12", "port": 26379 } - ], - "status": "running", - "alerts": { - "bigkeys": 2, - "slowlogLastMinute": 0 - } - } -} -``` - ---- - -## 关联文档 - -- XINFRA 平台需求文档 -- XINFRA 预习总览