# docker-scheduler **Repository Path**: clynn_dev/docker-scheduler ## Basic Information - **Project Name**: docker-scheduler - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-10 - **Last Updated**: 2026-03-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Docker Scheduler System 基于 Docker、FastAPI 和 Vue3 的容器优先级调度与管理平台。专为边缘云场景优化,支持低功耗设备运行。 ## 功能特性 ### 核心调度系统 (FastAPI + Docker SDK) - **容器管理**: 创建、启动、停止、重启、删除容器 - **镜像管理**: 从本地 Tar 包加载镜像,列出本地镜像 - **优先级调度**: 支持 LOW/MEDIUM/HIGH/CRITICAL 四级优先级 - **资源监控**: 实时监控 CPU 和内存使用情况 - **自动驱逐**: 资源紧张时自动驱逐低优先级容器 - **手动锁定**: 可手动锁定容器防止被调度器驱逐 - **手动驱逐**: 支持用户手动驱逐指定容器 - **手动调整优先级**: 支持实时修改已导入容器的优先级 - **数据持久化**: 使用 SQLite 持久化存储任务状态,重启不丢失数据 - **容器审计**: 记录所有容器操作事件日志 - **智能重试**: 容器启动失败时自动退避重试,避免频繁失败 ### 边缘云优化 (v2.0) - **SQLite WAL 模式**: 启用 Write-Ahead Logging,提升并发读写性能 - **Write-Back 缓存**: 内存缓存 + 后台批量刷盘,减少磁盘写入 60-90% - **自适应调度周期**: 根据负载动态调整监控/调度间隔(2-60秒) - **/proc 读取优化**: 预分配缓冲区 + 手动字符串解析,减少 GC 压力 - **边缘配置文件**: 提供 `.env.edge` 专用配置,充分利用边缘设备资源 ### 前端 (Vue3 + TypeScript + Element Plus) - 容器管理界面:查看容器列表、操作容器、查看日志 - 镜像管理界面:查看本地镜像列表 - 调度器管理界面:提交任务、查看状态、导入容器 - **任务管理界面**:查看所有任务(含 FAILED 状态)、重置任务、编辑配置、查看事件历史 - 响应式设计,简洁易用 ## 项目结构 ``` Scheduler/ ├── app/ # 后端 (FastAPI + Docker SDK) │ ├── api/ # API 路由 │ │ ├── scheduler.py # 调度器相关接口 │ │ ├── containers.py # 容器管理接口 │ │ └── images.py # 镜像管理接口 │ ├── services/ # 业务逻辑 │ │ ├── scheduler_service.py # 调度核心 (支持持久化 + 自适应调度) │ │ └── docker_service.py # Docker 服务 │ ├── repositories/ # 数据访问层 │ │ ├── database.py # 数据库连接和初始化 (WAL 模式优化) │ │ ├── db_models.py # SQLAlchemy 模型 │ │ ├── scheduled_task_repository.py # 任务数据访问 │ │ ├── event_repository.py # 事件日志数据访问 │ │ └── cached_repository.py # 写回缓存层 (新增) │ ├── models/ # Pydantic 模型 │ ├── config/ # 配置 │ ├── utils/ # 工具 (日志等) │ ├── data/ # 统一数据目录 │ │ ├── db/ # SQLite 数据库 (运行时创建) │ │ └── docker-images/ # 镜像 tar 包 │ └── main.py # 应用入口 ├── frontend/ # Vue3 前端 │ └── src/ │ ├── views/ # 页面组件 │ ├── api/ # API 封装 │ └── router/ # 路由配置 ├── log/ # 日志目录 (运行时创建) ├── requirements.txt # Python 依赖 (调度器后端) ├── start.sh # 一键启动脚本 ├── .env.edge # 边缘设备专用配置 ├── README.md # 本文档 └── CLAUDE.md # Claude Code 指导文档 ``` ## 关联模块 以下模块已分离到独立仓库: - **Decoder** (视频流解码器): 独立仓库,RTSP 视频流解码容器 - **Reporter** (推理结果上报器): 独立仓库,从共享内存读取推理结果并通过 WebSocket 批量上报 - **Shm Manager** (共享内存管理库): 独立仓库,高性能 POSIX 共享内存管理库 ## 快速开始 ### 前置要求 - Python 3.8+ - Node.js 18+ - Docker (需要运行 Docker daemon) ### 安装与启动 #### 方式一:使用启动脚本 (推荐) ```bash # 赋予执行权限 chmod +x start.sh # 启动后端和前端 ./start.sh start # 查看状态 ./start.sh status # 停止服务 ./start.sh stop # 重启服务 ./start.sh restart ``` #### 方式二:手动启动 **后端启动:** ```bash # 安装依赖 pip install -r requirements.txt # 启动后端 python -m app.main ``` **前端启动:** ```bash cd frontend # 安装依赖 npm install # 启动开发服务器 npm run dev ``` #### 边缘设备启动 对于资源受限的边缘设备,使用专用配置: ```bash # 使用边缘配置启动 cp .env.edge .env # 然后正常启动 ./start.sh start ``` ### 访问地址 - 前端界面: http://localhost:5173 - 后端 API: http://localhost:8000 - API 文档: http://localhost:8000/docs ## API 接口 ### 调度器接口 | 方法 | 路径 | 描述 | |------|------|------| | POST | `/scheduler/task` | 提交调度任务 | | POST | `/scheduler/containers/{name}/override` | 手动锁定/解锁容器 | | POST | `/scheduler/containers/{name}/evict` | 手动驱逐容器 | | POST | `/scheduler/containers/{name}/priority` | 更新容器优先级 | | GET | `/scheduler/status` | 获取调度器状态 | | GET | `/scheduler/unmanaged-containers` | 获取未被管理的容器列表 | | POST | `/scheduler/import-container` | 导入正在运行的容器 | | DELETE | `/scheduler/containers/{name}` | 删除调度器管理的容器 | ### 任务管理接口 | 方法 | 路径 | 描述 | |------|------|------| | GET | `/scheduler/tasks` | 获取所有任务(含 FAILED、COMPLETED 状态) | | GET | `/scheduler/tasks/{task_id}` | 获取单个任务详情 | | POST | `/scheduler/tasks/{task_id}/reset` | 重置任务(清除驱逐计数,重新入队) | | PUT | `/scheduler/tasks/{task_id}` | 更新任务配置(优先级、最大驱逐次数、资源限制等) | | DELETE | `/scheduler/tasks/{task_id}` | 删除任务(停止并删除容器,清除数据库记录) | | GET | `/scheduler/tasks/{task_id}/events` | 获取任务的事件历史 | ### 容器接口 | 方法 | 路径 | 描述 | |------|------|------| | POST | `/containers` | 创建并启动容器 | | GET | `/containers` | 列出容器 | | GET | `/containers/{container_id}` | 获取容器详情 | | POST | `/containers/{container_id}/start` | 启动容器 | | POST | `/containers/{container_id}/stop` | 停止容器 | | POST | `/containers/{container_id}/restart` | 重启容器 | | GET | `/containers/{container_id}/logs` | 获取容器日志 | | DELETE | `/containers/{container_id}` | 删除容器 | ### 镜像接口 | 方法 | 路径 | 描述 | |------|------|------| | POST | `/images/load` | 从 Tar 加载镜像 | | GET | `/images/list` | 列出本地镜像 | ## 优先级说明 | 优先级 | 值 | 描述 | |--------|----|------| | LOW | 1 | 低优先级,资源紧张时优先被驱逐 | | MEDIUM | 5 | 中等优先级 (默认) | | HIGH | 10 | 高优先级 | | CRITICAL | 20 | 关键优先级,不会被自动驱逐 | ## 配置说明 ### 标准配置 可通过环境变量或 `.env` 文件配置: ```env # Docker 配置 DOCKER_BASE_URL=unix://var/run/docker.sock DOCKER_API_VERSION=auto DOCKER_TIMEOUT=60 # 默认资源限制 DEFAULT_CPU_LIMIT=1.0 DEFAULT_MEM_LIMIT=512m # 镜像存储路径 IMAGE_TAR_STORAGE_PATH=/opt/docker-images # 环境模式 APP_ENV=development ``` ### 边缘云优化配置 使用 `.env.edge` 配置文件,针对低功耗设备优化: ```env # 高水位 - 边缘设备可以设得更高一些(充分利用资源) HIGH_WATERMARK_MEM=90 HIGH_WATERMARK_CPU=95 # 低水位 LOW_WATERMARK_MEM=70 LOW_WATERMARK_CPU=80 # 最大驱逐次数 - 边缘场景可以允许更多重试 MAX_EVICTIONS=5 # 写回缓存:true 启用,false 禁用(直接写入) DB_WRITE_BACK_CACHE_ENABLED=true # 刷盘间隔(秒):越大写入越少,但数据丢失风险越高 DB_FLUSH_INTERVAL=10 # 最大待写入数:超过此数立即刷盘 DB_MAX_PENDING_WRITES=50 ``` ## 调度策略 ### 标准策略 1. **高水位驱逐**: 内存 > 85% 或 CPU > 90% 时,按优先级从低到高驱逐容器 2. **低水位唤醒**: 内存 < 60% 且 CPU < 70% 时,可尝试恢复低优先级任务 3. **队列调度**: 新任务优先处理高优先级,资源紧张时延迟低优先级任务 4. **老化机制**: 相同优先级任务按创建时间排序,等待时间长的优先执行 5. **退避重试**: 容器启动失败后指数退避重试,最大 60 秒 ### 边缘云自适应策略 - **监控间隔**: 高负载时 2 秒,低负载时最长 15 秒 - **调度间隔**: 有任务或高负载时 3 秒,空闲时最长 60 秒 - **低负载判定**: 连续 5 个周期负载 < 50% 后进入节能模式 ### 驱逐优化策略 - **停止不删除**: 驱逐时仅停止容器,保留容器数据和配置 - **快速恢复**: 资源缓解时优先启动已停止的同名容器 - **最大驱逐次数**: 可配置任务最大驱逐次数,超过后标记为 FAILED ## 持久化机制 ### 数据存储 - 使用 SQLite 数据库存储任务状态,默认位置:`app/data/db/scheduler.db` - 任务状态、驱逐计数、手动锁定状态等信息均会持久化 - 支持容器操作事件审计日志 ### 一致性保证 - **先写数据库,后操作 Docker**:确保任务记录先存在再执行容器操作 - **失败回滚**:Docker 操作失败时会回滚数据库状态 - **启动恢复**:服务重启时自动从数据库加载任务并与 Docker 实际状态同步 ### 写回缓存 (边缘云专用) - **工作原理**: 读请求先查内存缓存,写请求先写内存再后台批量刷盘 - **合并更新**: 同一任务的多次更新合并为一次数据库写入 - **配置项**: 刷盘间隔 10 秒,最大待写入 50 条 - **禁用方式**: 设置 `DB_WRITE_BACK_CACHE_ENABLED=false` ### 任务状态 - `PENDING`: 等待队列中 - `STARTING`: 正在启动 - `RUNNING`: 正在运行 - `EVICTING`: 正在驱逐 - `EVICTED`: 已被驱逐,等待重试 - `COMPLETED`: 正常完成 - `FAILED`: 失败超过最大重试次数 ### 任务模型新增字段 - `last_failed_at`: 上次失败时间戳,用于退避重试 - `retry_backoff`: 退避时间(秒),指数退避策略 - `container_id`: Docker 容器 ID,驱逐后保留用于快速恢复 ## SQLite 性能优化 ### WAL 模式配置 - `journal_mode=WAL`: 启用 Write-Ahead Logging,读写不阻塞 - `synchronous=NORMAL`: 平衡性能与数据安全 - `cache_size=-5000`: 分配约 40MB 缓存 - `temp_store=MEMORY`: 临时表放内存 - `busy_timeout=5000`: 减少锁等待错误 ## 开发说明 ### 后端开发 ```bash # 代码格式检查 (可选) # 使用你喜欢的 linter # 运行后端 (支持热重载) python -m app.main ``` ### 前端开发 ```bash cd frontend # 类型检查 npm run build # 代码格式化 (可选) # 使用你喜欢的 formatter ``` ## License MIT