Files
Qiniu/xinfra/issues/001-unified-infra-platform.md
T

304 lines
12 KiB
Markdown
Raw Normal View History

2026-07-08 14:11:13 +08:00
---
tags: [xinfra, issue, proposal]
create time: 2026-07-08 14:03
status: proposal
spec: FullSpec
---
# ISSUE-001:统一基础设施平台(XINFRA)
---
## 状态
`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
}
}
}
```
---
## 关联笔记
- [[requirements|XINFRA 平台需求文档]]
- [[technical/xinfra-preview|XINFRA 预习总览]]