首页 / 资讯中心 / 文章详情

基于Django的运维平台实战:资产管理、任务执行与发布流程

基于Django的运维平台实战:资产管理、任务执行与发布流程 ★ FEATURED ARTICLE
简介这份资源是一套基于Django框架开发的轻量级运维平台源码面向具备Python基础、希望了解Web运维系统实现思路的开发者与运维人员可用于学习主机管理、服务监控、日志查看、任务调度、权限控制、资源统计、脚本执行与故障告警等常见运维模块的落地方式。压缩包共164个文件以39个py后端代码、38个js与23个css前端资源为主另含11个html模板、18个png图片及字体图标文件整体约3.63MB采用前后端不分离架构Django视图与模板紧密结合目录结构清晰便于按模块阅读。已有2718人学习下载说明其作为入门级实战项目具有一定参考价值。解压后可直接查看模型定义、视图函数与静态资源组织方式适合作为课程设计、毕业设计原型或小型运维工具的二次开发起点帮助读者理解Python Web开发与日常运维场景的结合路径。1. 运维平台为什么值得用 Django 重写一遍很多团队最初的运维工具是一堆散落的 shell 脚本加几张 Excel 资产表机器一多就开始翻车谁改过配置、哪台机器上跑的是哪个版本、发布失败该回滚到哪一步全靠人脑记。这套方案要解决的就是把「脚本 表格 口头交接」收敛成一个可登录、可审计、可扩展的 Web 运维平台用 Python 和 Django 把资产管理、任务执行、发布流程、监控看板串成一条线。它适合两类人正在做毕设或课程设计、需要一个结构完整且能讲清楚技术选型的同学以及小团队里要交付一版内部运维工具、后续还得自己维护的工程师。DevOps 工具链里最不缺的就是单点脚本缺的是一个能把权限、日志、执行结果统一收口的入口这也是我选 Django 而不是 Flask 或 FastAPI 的核心原因——后台管理、ORM、权限体系、表单校验都是现成的省下来的时间可以全砸在任务执行和流程编排上。2. 需求拆解与技术选型四个模块撑起一个平台2.1 从真实痛点倒推功能边界做运维平台最容易犯的错是一上来就想做「全能面板」结果三个月过去连资产录入都没跑通。我一般会先把需求压到四条主线上每条线只保留最小可用闭环模块核心能力最小闭环后续可扩展资产管理主机、分组、标签、凭据手工录入 批量导入自动发现、CMDB 同步任务执行批量命令、脚本分发、结果回传单机执行 日志落库并发调度、失败重试发布流程应用、版本、环境、审批单应用单环境发布灰度、回滚编排监控看板主机存活、任务成功率定时探测 图表展示告警规则、通知渠道这张表的作用不是给老师看的是给自己划边界。资产模块必须先于任务模块完成因为任务执行的对象就是资产记录发布流程又依赖任务执行的结果回传否则审批通过了却不知道有没有发成功。依赖顺序理清楚开发排期就不会出现「页面都画完了发现底层没数据」的尴尬。技术选型上Web 框架用 Django理由前面说过权限和 Admin 能直接复用任务执行层不引入 Celery 这类重型组件毕设和中小团队场景下用 Django 自带的线程池加 subprocess 就够部署少一个中间件就少一个故障点数据库用 MySQL 或 PostgreSQL 都行资产和日志表结构不复杂SQLite 在演示阶段也能跑但并发写入日志时容易锁表正式一点还是上 MySQL前端不搞前后端分离Django 模板加 Bootstrap 足够省掉一套构建链路答辩时也少解释一个技术栈。2.2 数据模型设计先把表结构钉死运维平台的数据模型决定了后面所有功能好不好写。核心就四张表主机、主机组、任务、任务执行记录。主机和主机组是多对多一台机器可以属于多个业务分组任务和执行记录是一对多一次批量任务会产生多条执行明细。下面这段模型定义可以直接作为起点# models.py from django.db import models class HostGroup(models.Model): name models.CharField(max_length64, uniqueTrue) remark models.CharField(max_length255, blankTrue) class Host(models.Model): ip models.GenericIPAddressField(uniqueTrue) hostname models.CharField(max_length128) port models.IntegerField(default22) username models.CharField(max_length64) # 凭据不存明文实际项目里走加密字段或外部密钥管理 credential_ref models.CharField(max_length128) groups models.ManyToManyField(HostGroup, blankTrue) is_active models.BooleanField(defaultTrue) created_at models.DateTimeField(auto_now_addTrue) class Task(models.Model): name models.CharField(max_length128) command models.TextField() targets models.ManyToManyField(Host) created_by models.CharField(max_length64) created_at models.DateTimeField(auto_now_addTrue) class TaskRecord(models.Model): task models.ForeignKey(Task, on_deletemodels.CASCADE, related_namerecords) host models.ForeignKey(Host, on_deletemodels.CASCADE) status models.CharField(max_length16, defaultpending) # pending/success/failed stdout models.TextField(blankTrue) stderr models.TextField(blankTrue) duration_ms models.IntegerField(default0) finished_at models.DateTimeField(nullTrue, blankTrue)几个设计点值得展开。credential_ref存的是凭据引用而不是密码本身这是血泪经验——早期图省事直接存明文后面做导出功能时差点把密码带出去。TaskRecord单独建表而不是把结果塞进Task的 JSON 字段是为了让「按主机查历史」「按状态筛失败记录」这类查询能走索引日志量上来之后差别很明显。status用字符串而不是布尔值是因为后面大概率要加timeout、canceled这些状态布尔值改起来要动数据迁移。2.3 权限与审计别等出事才补Django 自带的auth体系够用但运维平台的角色划分要更细一点。通常的做法是建三个组管理员、运维、只读。管理员能管资产和用户运维能建任务和发布只读只能看记录。用 Django 的Group加自定义权限就能实现不需要引入第三方权限库。审计这块所有写操作都通过信号或者中间件记一条操作日志字段包括操作人、动作、对象、时间、来源 IP。这个表在答辩时是加分项在实际使用中是后悔药——出了事故第一件事就是查谁在什么时候动了什么。3. 任务执行引擎从点击按钮到结果落库3.1 执行链路拆解任务执行是整个平台最容易翻车的部分链路必须拆清楚前端提交任务 → 后端校验目标主机和命令 → 创建Task和一批TaskRecord状态 pending→ 线程池并发执行 → 每台主机执行完更新对应记录 → 前端轮询或刷新看结果。这里的关键决策是「同步还是异步」。同步执行在主机少的时候没问题但批量十台以上就会把请求卡住浏览器超时。我一般用线程池做异步任务提交后立即返回前端拿任务 ID 去轮询状态。# executor.py import subprocess, time from concurrent.futures import ThreadPoolExecutor from django.utils import timezone from .models import TaskRecord POOL ThreadPoolExecutor(max_workers8) def run_on_host(record: TaskRecord): start time.time() try: # 演示用本地 subprocess实际项目替换为 SSH 客户端调用 proc subprocess.run( record.task.command, shellTrue, capture_outputTrue, textTrue, timeout30 ) record.stdout proc.stdout[-4000:] # 截断避免日志表膨胀 record.stderr proc.stderr[-4000:] record.status success if proc.returncode 0 else failed except subprocess.TimeoutExpired: record.status failed record.stderr execution timeout finally: record.duration_ms int((time.time() - start) * 1000) record.finished_at timezone.now() record.save(update_fields[stdout, stderr, status, duration_ms, finished_at]) def dispatch(task): for record in task.records.filter(statuspending): POOL.submit(run_on_host, record)这段代码有几个参数需要按场景调。max_workers8是并发上限设太大容易把目标机器打满设太小批量任务排队时间长一般按目标主机数量的三分之一到二分之一来定。timeout30是单机执行超时长任务要单独放宽但必须有上限否则一个卡死的命令会占住线程。[-4000:]截断日志是防止某条命令输出几十兆把数据库撑爆完整日志应该落文件而不是落库。update_fields指定更新字段能减少写放大日志表写入频繁时这个细节有用。3.2 结果回传与前端展示执行结果落库后前端用简单的轮询就能展示。任务详情页每三秒请求一次状态接口返回各主机的执行状态和耗时页面用表格渲染失败的行标红。这里不需要 WebSocket毕设场景下轮询足够实现成本低答辩时也好解释。状态接口要做分页一次批量任务可能涉及上百台主机全量返回会让页面卡顿。提示轮询接口要加缓存或者限流否则多个页面同时开着会把数据库读压力放大简单做法是接口层加 2 秒的结果缓存。3.3 发布流程怎么接进来发布流程本质上是「带审批的任务执行」。建一张Release表字段包括应用名、版本号、目标环境、关联任务、审批状态、审批人。运维提交发布单后状态是待审批管理员审批通过才触发任务执行执行结果回写到发布单上。回滚就是把上一个成功版本的发布单重新执行一遍不需要单独设计回滚逻辑。这个设计的好处是发布和任务共用一套执行引擎代码量少逻辑也统一。4. 监控看板与资产联动让数据自己说话4.1 存活探测与定时任务监控看板的第一版不需要接 Prometheus用 Django 的 management command 加系统定时任务就能做主机存活探测。写一个probe_hosts命令遍历活跃主机对 IP 和端口做 TCP 连接测试结果写进一张HostStatus表记录时间、是否可达、响应耗时。系统 crontab 每分钟跑一次看板页面按最近一次探测结果渲染在线率和耗时趋势。# 每分钟探测一次输出追加到日志便于排查 * * * * * cd /path/to/project python manage.py probe_hosts /var/log/probe.log 21探测超时设 3 秒比较合适太短会误判网络抖动太长会让一轮探测拖过一分钟。探测结果表要定期清理只保留最近七天的数据否则表会无限增长。这个清理动作也写成 management command每天凌晨跑一次。4.2 看板指标怎么选看板上的指标不在多在于能回答「现在有没有问题」。我一般放四块主机在线率、近 24 小时任务成功率、失败任务 Top 5 主机、最近发布记录。前两个是健康度第三个是定位入口第四个是变更上下文。图表用 ECharts 或者 Chart.js 都行数据接口返回聚合后的 JSON前端只负责渲染。聚合查询用 Django ORM 的annotate和Count就能完成不需要手写 SQL。4.3 资产与任务的联动细节资产表里有个容易被忽略的字段是「标签」比如envprod、roleweb。任务创建时支持按标签选目标比一台台勾选高效得多。实现上就是Host.objects.filter(groups__nameweb)这类查询前端把标签做成多选。这个功能在演示时很出彩因为它体现了「资产不是死数据是执行的目标源」。另外主机下线时不要物理删除把is_active置 false历史任务记录还能关联到它否则外键一删审计链路就断了。5. 避坑与排查那些演示时看不出来的问题5.1 任务状态永远停在 pending现象是提交任务后前端一直显示执行中刷新也没用。原因通常是线程池提交失败或者执行函数抛了未捕获异常记录没被更新。解决方法是给run_on_host整体包一层 try/except任何异常都把记录置为 failed 并写入错误信息同时在dispatch里检查POOL.submit的返回值提交失败要立即标记。排查时直接看TaskRecord里finished_at为空的记录基本能定位到卡住的那批。5.2 日志表把数据库撑爆现象是平台跑两周后查询变慢磁盘告警。原因是每条执行记录都存了完整 stdout/stderr批量任务一多单表轻松上百万行。解决办法是双管齐下写入时截断到固定长度完整日志落文件并在记录里存文件路径同时加定期归档任务把三个月前的记录迁到历史表或者直接清理。这个坑我在第一个版本就踩过后来把日志字段改成TextField加截断查询速度立刻回来了。5.3 权限配了但接口没校验现象是只读用户通过直接调接口能触发任务执行。原因是视图函数只在前端隐藏了按钮后端没加permission_required或者自定义校验。解决办法是所有写操作视图统一加装饰器并且在测试用例里专门写一条「只读用户调用写接口应返回 403」的断言。这类问题在答辩时被问到会很尴尬提前用测试覆盖掉最省心。5.4 批量导入资产时 IP 重复报错中断现象是导入 CSV 时遇到一条重复 IP 整个事务回滚前面导入的全没了。原因是用了create而不是update_or_create且没做逐行异常处理。解决办法是导入逻辑改成逐行处理重复的走更新格式错误的记录收集起来最后统一提示不要因为一行脏数据废掉整批。5.5 定时探测把目标机器当攻击源现象是探测频率调高后目标机器的安全策略把平台服务器拉黑。原因是每分钟对同一 IP 发起连接频率过高。解决办法是探测间隔不低于一分钟同一轮探测内串行执行并加短延迟重要主机可以单独配置探测频率。这个细节在方案文档里写一句能体现对生产环境的敬畏。6. 验收与答辩怎么证明这套平台真的能用验收这件事我一般分三层来做层层递进答辩时按这个顺序讲评委跟得上自己也不慌。第一层是功能验收对着需求表逐条走。资产模块要演示新增、批量导入、按标签筛选任务模块要演示单机执行、批量执行、失败记录查看发布模块要演示提交、审批、执行、回滚完整链路看板要演示在线率和成功率随数据变化。每条验收都准备一条具体的测试数据比如「三台模拟主机、一个故意失败的脚本」现场跑一遍比截图有说服力。第二层是异常验收专门演示出问题时的表现。停掉一台模拟主机看探测是否标红提交一条超时命令看状态是否变 failed用只读账号调写接口看是否返回 403。这一层最能体现方案的完整度因为大部分课程设计只演示正常流程异常路径一問就露馅。第三层是数据验收检查审计日志和任务记录是否完整。随便挑一条历史任务能查到谁建的、什么时候执行的、每台主机的输出是什么、耗时多少。这一步证明平台不是「演示玩具」而是有可追溯性的工具。答辩陈述控制在八分钟以内结构建议是两分钟讲痛点和模块划分三分钟演示主链路两分钟讲一个踩坑和解决过程一分钟讲后续扩展方向。踩坑那段是加分项讲清楚「日志表膨胀怎么发现、怎么定位、怎么改」比堆功能列表更能说明你真的动手做过。验收项通过标准演示方式资产导入100 条 CSV 导入成功重复 IP 走更新现场导入并查列表批量任务10 台目标全部返回结果失败可见跑一条混合成功失败的命令发布回滚回滚后版本号回到上一版走完整发布再回滚权限隔离只读账号写接口返回 403切换账号调接口审计追溯任意任务可查到操作人和明细随机点一条历史记录从那以后我每次做这类平台都会在开发前先把验收表写出来功能按表开发答辩按表讲中间少了很多「做完了发现没东西可演示」的返工。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站