Files
ocdp-go/database.md
Ivan087 7f238a3168 refactor: full-stack restructure with multi-tenancy, workspace management, and K8s diagnostics
- Add Workspace domain (entity, repository, service, handler, DTO)
- Add multi-tenant K8s client with tenant binding and quota management
- Add K8s diagnostics client (instance diagnostics)
- Add authorization middleware (authz package)
- Restructure frontend to feature-based architecture (features/)
- Add User Management page in configuration
- Add AccessDenied page and route guards
- Refactor shared components (form inputs, layout, UI)
- Update Tailwind config for new design system
- Add comprehensive documentation (docs/, tasks/, plans)
- Improve cluster service with better kubeconfig handling
- Add tests for crypto, config, helm client, tenant binding
2026-05-12 16:15:14 +08:00

23 KiB
Raw Permalink Blame History

OCDP 数据库结构说明

概述

OCDP (Open Container Deployment Platform) 是一个多租户容器部署平台,支持:

  • 多 Workspace 隔离
  • RBAC 权限控制 (Admin / User)
  • Kubernetes 集群管理
  • OCI Registry 集成 (Harbor)
  • Helm Chart 部署
  • Values 模板版本管理
  • 资源配额控制
  • 审计日志

数据库配置

# PostgreSQL 连接信息
Host: localhost
Port: 5430 (docker) / 5432 (local)
Database: ocdp
User: ocdp
Password: ocdp_password

表结构

1. users - 用户表

存储用户账户信息,支持多租户和角色管理。

CREATE TABLE users (
    id VARCHAR(36) PRIMARY KEY,
    username VARCHAR(255) NOT NULL UNIQUE,
    password_hash TEXT NOT NULL,
    email VARCHAR(255) NOT NULL,
    role VARCHAR(20) NOT NULL DEFAULT 'user',        -- 'admin' | 'user'
    workspace_id VARCHAR(36),                         -- 所属工作空间admin 为 NULL 表示全局
    is_active BOOLEAN NOT NULL DEFAULT TRUE,          -- 账户是否激活
    must_change_password BOOLEAN NOT NULL DEFAULT FALSE, -- 首次登录必须修改密码
    revoked_after TIMESTAMP NOT NULL DEFAULT '1970-01-01 00:00:00', -- 全局 Token 撤销时间
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
字段 类型 说明 示例
id VARCHAR(36) 主键 UUID 550e8400-e29b-41d4-a716-446655440000
username VARCHAR(255) 用户名,唯一 admin
password_hash TEXT bcrypt 密码哈希 $2a$10$...
email VARCHAR(255) 邮箱 admin@ocdp.local
role VARCHAR(20) 角色admin/user admin
workspace_id VARCHAR(36) 所属工作空间 ID workspace-uuid
is_active BOOLEAN 账户是否激活 true
must_change_password BOOLEAN 首次登录必须修改密码 false
revoked_after TIMESTAMP Token 撤销时间(修改密码后自动撤销旧 Token 2024-01-01 10:00:00
created_at TIMESTAMP 创建时间 2024-01-01 10:00:00
updated_at TIMESTAMP 更新时间 2024-01-01 10:00:00

索引:

  • idx_users_username - 用户名查询
  • idx_users_role - 角色筛选
  • idx_users_workspace_id - 工作空间筛选
  • idx_users_is_active - 激活状态筛选

角色说明:

  • admin: 管理员,可管理所有 Workspace 和资源workspace_id 为 NULL
  • user: 普通用户,仅可访问自己 Workspace 内的资源

2. workspaces - 工作空间表

租户/团队隔离单元。

CREATE TABLE workspaces (
    id VARCHAR(36) PRIMARY KEY,
    name VARCHAR(255) NOT NULL UNIQUE,
    description TEXT,
    created_by VARCHAR(36),
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
字段 类型 说明 示例
id VARCHAR(36) 主键 UUID workspace-uuid
name VARCHAR(255) 工作空间名称,唯一 team-alpha
description TEXT 描述 Alpha 团队工作空间
created_by VARCHAR(36) 创建者用户 ID user-uuid
created_at TIMESTAMP 创建时间 2024-01-01 10:00:00
updated_at TIMESTAMP 更新时间 2024-01-01 10:00:00

索引:

  • idx_workspaces_name - 名称查询

3. workspace_quotas - 工作空间配额表

每个 Workspace 的资源配额限制。

CREATE TABLE workspace_quotas (
    id VARCHAR(36) PRIMARY KEY,
    workspace_id VARCHAR(36) NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
    resource_type VARCHAR(50) NOT NULL,              -- 'cpu' | 'gpu' | 'gpu_memory'
    hard_limit DECIMAL(10,2) NOT NULL,               -- 硬限制0 表示无限制)
    soft_limit DECIMAL(10,2) NOT NULL,               -- 软限制(警告阈值)
    used DECIMAL(10,2) NOT NULL DEFAULT 0,           -- 当前使用量
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(workspace_id, resource_type)
);
字段 类型 说明 示例
id VARCHAR(36) 主键 UUID quota-uuid
workspace_id VARCHAR(36) 所属工作空间 ID workspace-uuid
resource_type VARCHAR(50) 资源类型cpu/gpu/gpu_memory cpu
hard_limit DECIMAL(10,2) 硬限制0=无限制) 10.00
soft_limit DECIMAL(10,2) 软限制(警告阈值) 8.00
used DECIMAL(10,2) 当前使用量 5.00
created_at TIMESTAMP 创建时间 2024-01-01 10:00:00
updated_at TIMESTAMP 更新时间 2024-01-01 10:00:00

配额检查逻辑:

  1. 部署实例前检查 used + new_request <= hard_limit
  2. 超过硬限制返回 403 Forbidden
  3. 超过软限制发送警告通知
  4. 实例删除后释放配额

4. clusters - Kubernetes 集群表

管理 Kubernetes 集群连接信息。

CREATE TABLE clusters (
    id VARCHAR(36) PRIMARY KEY,
    workspace_id VARCHAR(36),                        -- 所属工作空间NULL 表示全局共享
    owner_id VARCHAR(36),                            -- 创建者用户 ID
    name VARCHAR(255) NOT NULL UNIQUE,
    host TEXT NOT NULL,                              -- Kubernetes API Server URL
    ca_data TEXT,                                    -- CA 证书Base64 编码)
    cert_data TEXT,                                  -- 客户端证书Base64 编码)
    key_data TEXT,                                   -- 客户端密钥Base64 编码)
    token TEXT,                                      -- Bearer Token与证书认证二选一
    description TEXT,
    isolation_mode VARCHAR(20) NOT NULL DEFAULT 'namespace', -- 'namespace' | 'cluster'
    default_namespace VARCHAR(255),                  -- 默认 namespace 前缀
    is_shared BOOLEAN NOT NULL DEFAULT FALSE,        -- 是否为共享集群
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
字段 类型 说明 示例
id VARCHAR(36) 主键 UUID cluster-uuid
workspace_id VARCHAR(36) 所属工作空间 ID workspace-uuid
owner_id VARCHAR(36) 创建者用户 ID user-uuid
name VARCHAR(255) 集群名称,唯一 prod-k8s
host VARCHAR(255) Kubernetes API URL https://k8s.example.com:6443
ca_data TEXT CA 证书 Base64 LS0tLS1...
cert_data TEXT 客户端证书 Base64 LS0tLS1...
key_data TEXT 客户端密钥 Base64 LS0tLS1...
token TEXT Bearer Token eyJhbGci...
description TEXT 描述 生产环境集群
isolation_mode VARCHAR(20) 隔离模式namespace/cluster namespace
default_namespace VARCHAR(255) 默认 namespace 前缀 team-alpha
is_shared BOOLEAN 是否共享admin 创建供多 Workspace 使用) false
created_at TIMESTAMP 创建时间 2024-01-01 10:00:00
updated_at TIMESTAMP 更新时间 2024-01-01 10:00:00

隔离模式说明:

  • namespace: 共享集群模式,多个 Workspace 使用不同 namespace
    • 部署时自动分配:{default_namespace}-{instance_name}
  • cluster: 私有集群模式,每个 Workspace 独立集群或独立凭证

认证方式:

  1. 证书认证:ca_data + cert_data + key_data
  2. Token 认证:token

5. registries - OCI Registry 表

管理 Docker/OCI 镜像仓库(支持 Harbor

CREATE TABLE registries (
    id VARCHAR(36) PRIMARY KEY,
    workspace_id VARCHAR(36),                        -- 所属工作空间NULL 表示全局共享
    owner_id VARCHAR(36),                            -- 创建者用户 ID
    name VARCHAR(255) NOT NULL UNIQUE,
    url TEXT NOT NULL,                               -- Registry URL
    description TEXT,
    username VARCHAR(255),                           -- 认证用户名
    password TEXT,                                   -- 认证密码(加密存储)
    insecure BOOLEAN DEFAULT FALSE,                  -- 是否跳过 TLS 验证
    is_shared BOOLEAN DEFAULT FALSE,                 -- 是否为共享 Registry
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
字段 类型 说明 示例
id VARCHAR(36) 主键 UUID registry-uuid
workspace_id VARCHAR(36) 所属工作空间 ID workspace-uuid
owner_id VARCHAR(36) 创建者用户 ID user-uuid
name VARCHAR(255) Registry 名称,唯一 harbor-prod
url TEXT Registry URL https://harbor.example.com
description TEXT 描述 生产环境 Harbor
username VARCHAR(255) 认证用户名 admin
password TEXT 认证密码(加密) encrypted...
insecure BOOLEAN 跳过 TLS 验证 false
is_shared BOOLEAN 是否共享 false
created_at TIMESTAMP 创建时间 2024-01-01 10:00:00
updated_at TIMESTAMP 更新时间 2024-01-01 10:00:00

6. instances - Helm 实例表

部署的 Helm Release 管理。

CREATE TABLE instances (
    id VARCHAR(36) PRIMARY KEY,
    workspace_id VARCHAR(36),                        -- 所属工作空间
    owner_id VARCHAR(36),                            -- 创建者用户 ID
    cluster_id VARCHAR(36) NOT NULL,
    registry_id VARCHAR(36) NOT NULL,
    chart_reference_id VARCHAR(36),                  -- 引用的 Chart 引用
    values_template_id VARCHAR(36),                  -- 使用的 Values 模板

    name VARCHAR(255) NOT NULL,                      -- Helm Release 名称
    namespace VARCHAR(255) NOT NULL,                 -- Kubernetes 命名空间
    repository TEXT NOT NULL,                        -- OCI Repository (e.g., charts/app)
    chart VARCHAR(255) NOT NULL,                     -- Chart 名称
    version VARCHAR(255) NOT NULL,                   -- Chart 版本
    description TEXT,
    values JSONB,                                    -- Helm Values (JSON)
    values_yaml TEXT,                                -- Helm Values (YAML)
    user_override_yaml TEXT,                         -- 用户额外覆盖配置

    status VARCHAR(50) NOT NULL,                     -- 实例状态
    status_reason TEXT,                              -- 状态说明
    last_operation VARCHAR(50),                      -- 最后操作类型
    last_error TEXT,                                 -- 最近错误
    revision INTEGER NOT NULL DEFAULT 1,             -- Helm Release Revision

    cpu_requested DECIMAL(10,2) NOT NULL DEFAULT 0,  -- CPU 请求量 (cores)
    memory_requested VARCHAR(50) NOT NULL DEFAULT '0Mi', -- 内存请求量
    gpu_requested DECIMAL(10,2) NOT NULL DEFAULT 0,  -- GPU 请求量 (cards)
    gpu_memory_requested VARCHAR(50) NOT NULL DEFAULT '0Mi', -- GPU 内存请求量

    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,

    CONSTRAINT fk_cluster FOREIGN KEY (cluster_id) REFERENCES clusters(id) ON DELETE CASCADE,
    CONSTRAINT fk_registry FOREIGN KEY (registry_id) REFERENCES registries(id) ON DELETE CASCADE,
    UNIQUE (cluster_id, name, namespace)
);
字段 类型 说明 示例
id VARCHAR(36) 主键 UUID instance-uuid
workspace_id VARCHAR(36) 所属工作空间 ID workspace-uuid
owner_id VARCHAR(36) 创建者用户 ID user-uuid
cluster_id VARCHAR(36) 所属集群 ID cluster-uuid
registry_id VARCHAR(36) 所属 Registry ID registry-uuid
chart_reference_id VARCHAR(36) Chart 引用 ID chart-ref-uuid
values_template_id VARCHAR(36) Values 模板 ID template-uuid
name VARCHAR(255) Release 名称RFC 1123 my-app
namespace VARCHAR(255) Kubernetes 命名空间 team-alpha-my-app
repository TEXT OCI Repository harbor.example.com/charts/nginx
chart VARCHAR(255) Chart 名称 nginx
version VARCHAR(255) Chart 版本 1.0.0
description TEXT 描述 Nginx 应用
values JSONB Values JSON {"replicas": 2}
values_yaml TEXT Values YAML replicas: 2
user_override_yaml TEXT 用户覆盖配置 replicas: 3
status VARCHAR(50) 状态 deployed
status_reason TEXT 状态说明 Install complete
last_operation VARCHAR(50) 最后操作 install
last_error TEXT 错误信息 -
revision INTEGER Helm Revision 1
cpu_requested DECIMAL(10,2) CPU 请求 2.00
memory_requested VARCHAR(50) 内存请求 1Gi
gpu_requested DECIMAL(10,2) GPU 请求 0
gpu_memory_requested VARCHAR(50) GPU 内存 0Mi
created_at TIMESTAMP 创建时间 2024-01-01 10:00:00
updated_at TIMESTAMP 更新时间 2024-01-01 10:00:00

状态说明:

状态 说明
deployed 部署成功
failed 部署失败
pending-install 安装中
pending-upgrade 升级中
pending-rollback 回滚中
pending-delete 删除中
uninstalled 已卸载
superseded 已被取代
unknown 未知

7. storage_backends - 存储后端表

NFS/PV/HostPath 存储配置。

CREATE TABLE storage_backends (
    id VARCHAR(36) PRIMARY KEY,
    workspace_id VARCHAR(36),
    owner_id VARCHAR(36),
    name VARCHAR(255) NOT NULL,
    type VARCHAR(50) NOT NULL,                      -- 'nfs' | 'pv' | 'hostPath'
    config JSONB NOT NULL,                          -- 存储配置
    description TEXT,
    is_default BOOLEAN NOT NULL DEFAULT FALSE,      -- 是否默认存储
    is_shared BOOLEAN NOT NULL DEFAULT FALSE,       -- 是否共享
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(workspace_id, name)
);

Config 结构:

// NFS
{"nfs": {"server": "192.168.1.100", "path": "/data"}}

// PV
{"pv": {"storageClassName": "nfs", "capacity": "10Gi", "accessModes": ["ReadWriteMany"]}}

// HostPath
{"hostPath": {"path": "/mnt/data"}}

8. chart_references - Chart 引用表

管理可用的 Helm Chart 引用。

CREATE TABLE chart_references (
    id VARCHAR(36) PRIMARY KEY,
    workspace_id VARCHAR(36),
    registry_id VARCHAR(36),
    repository VARCHAR(500) NOT NULL,               -- OCI repository path
    chart_name VARCHAR(255) NOT NULL,
    description TEXT,
    is_enabled BOOLEAN NOT NULL DEFAULT TRUE,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(workspace_id, registry_id, repository)
);

9. values_templates - Values 模板表

Helm Values 模板,支持版本管理。

CREATE TABLE values_templates (
    id VARCHAR(36) PRIMARY KEY,
    workspace_id VARCHAR(36),
    owner_id VARCHAR(36),
    chart_reference_id VARCHAR(36),
    name VARCHAR(255) NOT NULL,
    description TEXT,
    values_yaml TEXT NOT NULL,
    version INTEGER NOT NULL DEFAULT 1,             -- 模板版本号
    is_default BOOLEAN NOT NULL DEFAULT FALSE,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(workspace_id, chart_reference_id, name)
);

版本管理:

  • 每次更新创建新版本version + 1
  • 支持回滚到历史版本

10. user_config_overrides - 用户配置覆盖表

用户个人配置覆盖。

CREATE TABLE user_config_overrides (
    id VARCHAR(36) PRIMARY KEY,
    workspace_id VARCHAR(36),
    user_id VARCHAR(36),
    target_type VARCHAR(50) NOT NULL,               -- 'storage' | 'template' | 'global'
    target_id VARCHAR(36),
    config JSONB NOT NULL,                          -- 覆盖配置
    priority INTEGER NOT NULL DEFAULT 0,            -- 优先级
    is_active BOOLEAN NOT NULL DEFAULT TRUE,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

11. audit_logs - 审计日志表

记录所有操作行为。

CREATE TABLE audit_logs (
    id VARCHAR(36) PRIMARY KEY,
    workspace_id VARCHAR(36),
    user_id VARCHAR(36),
    action VARCHAR(100) NOT NULL,                   -- 'create' | 'update' | 'delete' | 'deploy' | 'scale'
    resource_type VARCHAR(50) NOT NULL,             -- 'cluster' | 'registry' | 'instance' | ...
    resource_id VARCHAR(36),
    resource_name VARCHAR(255),
    details JSONB,
    ip_address VARCHAR(50),
    user_agent TEXT,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

12. schema_migrations - 迁移版本表

数据库版本记录。

CREATE TABLE schema_migrations (
    version VARCHAR(50) PRIMARY KEY,
    applied_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

ER 关系图

┌─────────────────────────────────────────────────────────────────────────┐
│                              workspaces                                  │
│  (id, name, description, created_by, created_at, updated_at)          │
└────────────────────────────────────┬────────────────────────────────────┘
                                     │ 1:N
        ┌────────────────────────────┼────────────────────────────┐
        │                            │                            │
        ▼                            ▼                            ▼
┌───────────────────┐    ┌───────────────────┐    ┌───────────────────┐
│   workspace_quotas│    │     clusters      │    │    registries    │
│ (workspace_id,    │    │ (workspace_id,    │    │ (workspace_id,   │
│  resource_type,   │    │  owner_id, name,  │    │  owner_id, name, │
│  hard_limit,      │    │  host, is_shared) │    │  url, is_shared) │
│  soft_limit, used)│    └─────────┬─────────┘    └────────┬─────────┘
└───────────────────┘              │                       │
                                   │                       │
       ┌───────────────────────────┼───────────────────────┘
       │                           │
       ▼                           ▼
┌───────────────────┐    ┌───────────────────┐
│     instances     │    │   storage_backends│
│ (workspace_id,    │    │ (workspace_id,    │
│  owner_id,        │    │  owner_id, name,  │
│  cluster_id,      │    │  type, config)    │
│  registry_id,     │    └───────────────────┘
│  values_template) │
└───────────────────┘

┌─────────────────────────────────────────────────────────────────────────┐
│                                users                                     │
│  (id, username, password_hash, email, role, workspace_id, is_active)  │
└────────────────────────────────────┬────────────────────────────────────┘
                                     │
        ┌────────────────────────────┼────────────────────────────┐
        │                            │                            │
        ▼                            ▼                            ▼
┌───────────────────┐    ┌───────────────────┐    ┌───────────────────┐
│   chart_references│    │ values_templates  │    │   audit_logs      │
│ (workspace_id,    │    │ (workspace_id,    │    │ (user_id, action,│
│  registry_id,     │    │  owner_id,        │    │  resource_type)  │
│  repository)      │    │  chart_ref_id)    │    └───────────────────┘
└───────────────────┘    └───────────────────┘

资源可见性规则

用户角色 可见范围
Admin 所有 Workspace 的所有资源workspace_id 为 NULL 或有值都能看到)
User 仅自己 Workspace 的资源
共享资源 is_shared=TRUE 时,同 Workspace 内可见

常用 SQL 操作

查询用户及其 Workspace

SELECT u.id, u.username, u.role, w.name as workspace_name
FROM users u
LEFT JOIN workspaces w ON u.workspace_id = w.id
WHERE u.is_active = TRUE;

查询 Workspace 配额使用情况

SELECT w.name as workspace,
       q.resource_type,
       q.hard_limit,
       q.soft_limit,
       q.used,
       CASE WHEN q.hard_limit > 0 THEN ROUND(q.used / q.hard_limit * 100, 2) ELSE 0 END as usage_percent
FROM workspace_quotas q
JOIN workspaces w ON q.workspace_id = w.id;

查询用户可用的集群

-- Admin: 所有集群
SELECT * FROM clusters;

-- User: 自己 Workspace 的集群 + 共享集群
SELECT * FROM clusters
WHERE workspace_id = 'user-workspace-id'
   OR is_shared = TRUE;

查询实例状态统计

SELECT status, COUNT(*) as count
FROM instances
WHERE workspace_id = 'workspace-id'
GROUP BY status;

查询审计日志

SELECT a.created_at, u.username, a.action, a.resource_type, a.resource_name
FROM audit_logs a
JOIN users u ON a.user_id = u.id
WHERE a.workspace_id = 'workspace-id'
ORDER BY a.created_at DESC
LIMIT 50;

迁移历史

版本 说明 日期
v1.0.0 初始版本(单租户) 2024-01
v2.0.0-multi-tenant 多租户迁移:添加 workspaces, quotas, 扩展 users/clusters/registries/instances 2025-04

初始数据

创建 Admin 用户

-- 默认密码: admin123 (bcrypt hash 需由应用设置)
INSERT INTO users (id, username, password_hash, email, role, workspace_id, is_active, must_change_password)
VALUES (
    '00000000-0000-0000-0000-000000000001',
    'admin',
    '$2a$10$placeholder',  -- 由应用初始化时设置
    'admin@ocdp.local',
    'admin',
    NULL,   -- admin 的 workspace_id 为 NULL表示全局
    TRUE,
    TRUE    -- 首次登录必须修改密码
);