# OCDP 数据库结构说明 ## 概述 OCDP (Open Container Deployment Platform) 是一个多租户容器部署平台,支持: - 多 Workspace 隔离 - RBAC 权限控制 (Admin / User) - Kubernetes 集群管理 - OCI Registry 集成 (Harbor) - Helm Chart 部署 - Values 模板版本管理 - 资源配额控制 - 审计日志 ## 数据库配置 ```yaml # PostgreSQL 连接信息 Host: localhost Port: 5430 (docker) / 5432 (local) Database: ocdp User: ocdp Password: ocdp_password ``` --- ## 表结构 ### 1. users - 用户表 存储用户账户信息,支持多租户和角色管理。 ```sql 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 - 工作空间表 租户/团队隔离单元。 ```sql 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 的资源配额限制。 ```sql 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 集群连接信息。 ```sql 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)。 ```sql 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 管理。 ```sql 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 存储配置。 ```sql 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 结构**: ```json // 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 引用。 ```sql 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 模板,支持版本管理。 ```sql 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 - 用户配置覆盖表 用户个人配置覆盖。 ```sql 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 - 审计日志表 记录所有操作行为。 ```sql 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 - 迁移版本表 数据库版本记录。 ```sql 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 ```sql 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 配额使用情况 ```sql 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; ``` ### 查询用户可用的集群 ```sql -- Admin: 所有集群 SELECT * FROM clusters; -- User: 自己 Workspace 的集群 + 共享集群 SELECT * FROM clusters WHERE workspace_id = 'user-workspace-id' OR is_shared = TRUE; ``` ### 查询实例状态统计 ```sql SELECT status, COUNT(*) as count FROM instances WHERE workspace_id = 'workspace-id' GROUP BY status; ``` ### 查询审计日志 ```sql 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 用户 ```sql -- 默认密码: 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 -- 首次登录必须修改密码 ); ```