Add new frontend pages for the multi-tenant OCDP platform: - Charts page (/charts): Browse Harbor OCI registries to list Helm chart repositories and versions, with deploy modal to launch charts on selected clusters - Monitoring page (/monitoring): Display cluster metrics (CPU/Memory/GPU usage) and per-node details with resource utilization bars - Chart References page (/chart-references): CRUD for chart metadata references - Values Templates page (/templates): CRUD for Helm values templates with version history and rollback support - Sidebar: Add Charts navigation, update Storage and Templates links - api.ts: Add all API client functions (clusterApi, registryApi, instanceApi, monitoringApi, storageApi, chartReferenceApi, valuesTemplateApi, workspaceApi, userApi) with full TypeScript types Note: deploy flow and values template rollback not yet end-to-end tested.
23 KiB
23 KiB
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$... |
| 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 为 NULLuser: 普通用户,仅可访问自己 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 |
配额检查逻辑:
- 部署实例前检查
used + new_request <= hard_limit - 超过硬限制返回 403 Forbidden
- 超过软限制发送警告通知
- 实例删除后释放配额
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 独立集群或独立凭证
认证方式:
- 证书认证:
ca_data+cert_data+key_data - 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 -- 首次登录必须修改密码
);