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

12 KiB
Raw Blame History

[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

数据示例

{
  "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 验证通过"
      }
    ]
  }
}
{
  "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
  }
}
{
  "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 预习总览