-
Karmada 是开放的多云多集群容器编排引擎,旨在帮助用户在多云环境下部署和运维业务应用。凭借兼容 Kubernetes 原生 API 的能力,Karmada 可以平滑迁移单集群工作负载,并且仍可保持与 Kubernetes 周边生态工具链协同。Karmada v1.17[1] 版本现已发布,本版本包含下列新增特性:工作负载亲和与反亲和调度Dashboard v0.3.0 发布持续的性能优化这些特性使 Karmada 在处理大规模、复杂的多集群场景时更加成熟和可靠。我们鼓励您升级到 v1.17.0,体验这些新功能带来的价值。 新特性概览 支持工作负载亲和与反亲和调度在多集群场景下,大量应用对工作负载之间的部署位置存在明确诉求,以实现高可用、低延迟、成本优化与运维隔离等目标。为满足这类精细化部署需求,本版本正式推出工作负载亲和与反亲和调度能力,让你能够精细控制工作负载在多集群间的拓扑关系。工作负载亲和(Workload Affinity)将存在关联的工作负载(如微服务与其缓存、分布式训练任务等)调度到同一集群。核心价值:降低跨集群网络延迟,显著提升性能敏感型应用的运行效率。典型场景:服务与依赖组件同集群部署、训练任务组件就近调度。工作负载反亲和(Workload Anti-Affinity)将同一逻辑组的工作负载分散到不同集群。核心价值:避免单集群故障导致关键应用整体不可用,强化多集群高可用保障。典型场景:核心服务多集群分散、多副本跨集群容灾。使用方式只需在 PropagationPolicy 中添加 workloadAffinity 配置,即可基于资源模板上的标签定义亲和组,实现工作负载的同集群部署或跨集群分散。让我们举一个工作负载亲和性的例子,假设您有一组训练任务,为了达到最佳的训练效果,您希望这一组训练任务的作业能在同一个集群上运行,您可以这样配置。启用工作负载亲和与反亲和调度功能后,Karmada 会将具有相同 app.training-group 标签值的训练任务调度到同一个集群。再来看一个工作负载反亲和性的例子,假设您运行着对停机时间非常敏感的 Flink 数据处理任务,为了保证高可用,您会部署多套相同的 Flink 任务副本。为了避免因单个集群故障导致服务完全中断,您希望同一任务的多个副本分散到不同集群上运行,您可以这样配置。启用工作负载亲和与反亲和调度功能后,Karmada 会将具有相同 karmada.io/group 标签值的 Flink 任务调度到不同集群,效果图如下:更多有关此功能的资料请参考:工作负载亲和性[2]。Dashboard v0.3.0 发布Karmada Dashboard 是一款专为 Karmada 用户设计的图形化界面工具,旨在简化多集群管理的操作流程,提升用户体验。通过 Dashboard,用户可以直观地查看集群状态、资源分布以及任务执行情况,同时还能轻松完成配置调整和策略部署。经过社区开发者的共同努力,Karmada Dashboard v0.3.0 正式发布!本次更新带来智能助手、成员集群管理等能力,多集群运维体验全面升级,更易用、更稳定、更智能!Karmada Dashboard v0.3.0 主要功能包括:智能化运维:深度集成 MCP (Model Context Protocol) 与 LLM,推出智能聊天助手。支持自然语言交互,实时响应与工具能力扩展,让多集群管理更加智能!成员集群管理能力增强:新增成员集群专用仪表盘,支持实时日志查看和终端交互,实现对子集群的精细化掌控。界面优化:采用更现代化的 UI 组件 Ant Design v6 同时升级至 React 19,界面更加美观;优化数据请求与构建性能,提升交互体验与运行效率。安全性和稳定性增强:引入全面的 E2E 测试框架维护基本功能特性,并自动升级安全依赖,减少安全风险。下面是 Karmada Dashboard v0.3.0 新版界面展示, 可以在顶部导航栏上切换成员集群,无缝切换到成员集群:更多有关 Karmada Dashboard 的资料请参考:Karmada Dashboard[3]持续的性能优化在此版本中,性能优化团队继续增强 Karmada 的性能,对控制器进行了如下改进:控制器优先级队列(ControllerPriorityQueue)特性升级至 Beta 并默认启用控制器优先级队列特性自 v1.15 版本首次推出后,历经两个版本的持续迭代与严格测试,能力已趋于成熟,本次版本正式将其升级为 Beta 版,并默认开启该特性。基于此特性,Karmada 控制器能够在重启或切主后立即响应并优先处理用户触发的资源变更,从而显著缩短服务重启和计划性升级过程中的停机时间。依赖资源分发能力性能优化通过消减并发更新依赖资源相关的 ResourceBinding 所产生的 API 冲突,依赖资源跟随分发的效率得到了显著的提升。测试环境包括 30,000 个 Workload 及其 PropagationPolicy,以及 30,000 个 ConfigMap 作为 Workload 依赖的资源。该优化将控制器首次启动的队列处理时间从20 分钟以上大幅缩短至约 5 分钟,显著提升了大规模集群下的系统响应速度。有关详细的优化内容和测试报告,请参阅 PR: [Performance] optimize the mechanism of create or update dependencies-distribute resourcebinding[4]。 致谢贡献者 Karmada v1.17 版本包含了来自 32 位贡献者的 264 次代码提交,在此对各位贡献者表示由衷的感谢: 相关链接[1] Karmada v1.17: cid:link_0[2] 工作负载亲和性调度: https://karmada.io/zh/docs/next/userguide/scheduling/propagation-policy/#workloadaffinity%E5%B7%A5%E4%BD%9C%E8%B4%9F%E8%BD%BD%E4%BA%B2%E5%92%8C%E6%80%A7[3] Karmada Dashboard: cid:link_2[4] [Performance] optimize the mechanism of create or update dependencies-distribute resourcebinding: cid:link_1 扫码回复“Karmada” 进入技术群Karmada 是CNCF 首个多云多集群容器编排项目(孵化级),旨在帮助用户像使用单个集群一样轻松管理跨云多集群,让基于 Karmada 的多云方案无缝融入云原生技术生态。社区吸引了来自华为、道客、浙江大学、滴滴、腾讯、中国电子云等60多家公司的全球贡献者,广泛分布于22个国家和地区。Karmada 现已在华为云、道客、兴业数金、中国移动、中国联通、携程、360集团、新浪、中通快递等众多企业单位生产应用,为企业提供从单集群到多云架构的平滑演进方案。Karmada官网:https://karmada.io/项目地址:cid:link_3Slack地址:https://slack.cncf.io/(#karmada)
-
欢迎阅读「从零开始理解 Agent」系列文章——我们将通过一个不到 300 行的开源项目 nanoAgent[1],逐层拆解 OpenClaw / Claude Code 等 AI Agent 背后的全部核心概念。第一篇:底层原理,只有 115 行 —— 工具 + 循环第二篇:记忆与规划 —— 182 行第三篇:Rules、Skills 与 MCP(本文)—— 265 行第四篇:SubAgent 子智能体 —— 192 行第五篇:多智能体协作与编排 —— 270 行第六篇:上下文压缩 —— 169 行★ 项目地址:cid:link_4作者:十一在前两篇中,我们一步步构建了 Agent 的核心能力:第一篇[2]用 115 行代码搭好了"工具 + 循环"的地基;第二篇[3]用 67 行增量代码装上了记忆和规划。但在第二篇结尾,我们留下了三个未解之谜:工具是硬编码的,没有行为约束,规划是被动触发的。今天我们继续进化—— agent-claudecode.py[4](265 行)。如果你用过 OpenClaw 或 Claude Code,你对 CLAUDE.md 规则文件、.agent/skills/ 技能目录、MCP 工具配置一定不陌生——这些概念正是本篇要拆解的核心。agent-claudecode.py 在前两个版本的基础上,引入了四个新概念来回答那三个问题:一、三个版本全景对比先回顾整个进化路线:二、更精细的工具集:从"能用"到"好用"agent-claudecode.py 首先在基础工具上做了大幅扩充,从 3 个增加到 7 个:base_tools = [ {"name": "read", "description": "Read file with line numbers", ...}, {"name": "write", "description": "Write content to file", ...}, {"name": "edit", "description": "Replace string in file", ...}, # 新增 {"name": "glob", "description": "Find files by pattern", ...}, # 新增 {"name": "grep", "description": "Search files for pattern", ...}, # 新增 {"name": "bash", "description": "Run shell command", ...}, {"name": "plan", "description": "Break down complex task", ...} # 新增 ]新增的工具不是随意选择的——它们恰好对应了 Claude Code 的核心工具集。其中最值得深入分析的是 edit 和改进后的 read。edit:用约束引导 LLM 行为def edit(path, old_string, new_string): try: with open(path, 'r') as f: content = f.read() if content.count(old_string) != 1: return f"Error: old_string must appear exactly once" new_content = content.replace(old_string, new_string) with open(path, 'w') as f: f.write(new_content) return f"Successfully edited {path}" except Exception as e: return f"Error: {str(e)}"这个工具有一个精妙的约束:**old_string 必须在文件中恰好出现一次**。出现零次说明目标不存在,出现多次则无法确定该替换哪一处。这个"唯一性约束"迫使 LLM 在调用 edit 之前先用 read 或 grep 确认上下文,大大降低了误编辑的概率。对比第一篇中 agent.py 的 write_file(直接覆盖整个文件),edit 精确到了字符串级别——这正是 Claude Code 中 str_replace 工具的设计思路。★ 设计启示用工具的约束来引导 LLM 的行为,比在 prompt 中告诫"小心编辑"可靠得多。约束是硬性的,prompt 是软性的。read:行号 + 分页def read(path, offset=None, limit=None): try: with open(path, 'r') as f: lines = f.readlines() start = offset if offset else0 end = start + limit if limit else len(lines) numbered = [f"{i+1:4d}{line}"for i, line in enumerate(lines[start:end], start)] return ''.join(numbered) except Exception as e: return f"Error: {str(e)}"相比第一篇中简单的 read_file,这个版本支持 offset 和 limit 分页读取,还会给每行加上行号。行号看似微不足道,但对 LLM 配合 edit 使用时极其重要——LLM 可以精确定位"第 23 行附近的那段代码"。三、Rules:教 Agent "做人的规矩"3.1 加载与注入RULES_DIR = ".agent/rules" def load_rules(): rules = [] ifnot os.path.exists(RULES_DIR): return "" try: for rule_file in Path(RULES_DIR).glob("*.md"): with open(rule_file, 'r') as f: rules.append(f"# {rule_file.stem}\n{f.read()}") return "\n\n".join(rules) if rules else"" except: return ""Rules 是存放在 .agent/rules/ 目录下的 Markdown 文件。Agent 启动时全部加载,注入到 system prompt 中:if rules: context_parts.append(f"\n# Rules\n{rules}")3.2 Rules 是什么、怎么用你可以创建这样的规则文件:<!-- .agent/rules/code-style.md --> - 使用 Python 3.10+ 语法 - 所有函数必须有 docstring - 变量命名使用 snake_case - 不要使用 print 调试,使用 logging 模块<!-- .agent/rules/safety.md --> - 永远不要执行 rm -rf / 或类似的危险命令 - 修改文件前先备份 - 不要修改 .env 文件中的密钥3.3 Rules 的本质Rules 是项目级的 system prompt 扩展。它解决了一个关键问题:不同项目、不同团队、不同场景对 Agent 的要求不同。与其每次在对话中反复叮嘱"记得用 snake_case",不如写一次规则文件,永久生效。如果你用过 OpenClaw 或 Claude Code,你一定对 CLAUDE.md 不陌生——它就是 Rules 的工程化实现。在 Claude Code 中对应 CLAUDE.md 文件和 .claude/rules/ 目录,在 OpenClaw 中也沿用了相同的约定。在 Cursor 中是 .cursorrules,在 GitHub Copilot 中是 .github/copilot-instructions.md。名字不同,本质一样——用声明式文件定制 Agent 的行为边界。回顾第二篇中 agent-plus.py 的 system prompt 构建方式,当时只有"基础指令 + 记忆"两层。现在变成了三层拼接:最终 system prompt = 基础指令 + Rules(项目规则) + Skills(技能描述) + Memory(历史记忆)四、Skills:可插拔的技能注册4.1 加载与注入SKILLS_DIR = ".agent/skills" def load_skills(): skills = [] ifnot os.path.exists(SKILLS_DIR): return [] try: for skill_file in Path(SKILLS_DIR).glob("*.json"): with open(skill_file, 'r') as f: skills.append(json.load(f)) return skills except: return []Skills 是 .agent/skills/ 目录下的 JSON 文件,以列表摘要的形式注入 system prompt:if skills: context_parts.append( f"\n# Skills\n" + "\n".join( [f"- {s['name']}: {s.get('description', '')}"for s in skills] ) )一个 Skill 文件可能长这样:{ "name": "docker-deploy", "description": "Deploy application using Docker Compose. Steps: 1) Check Dockerfile exists, 2) Run docker-compose build, 3) Run docker-compose up -d, 4) Verify containers are running.", "triggers": ["deploy", "docker", "container"] }★ 关于 Skill 的文件格式: 在 OpenClaw / Claude Code 的实际实现中,Skill 的标准格式是 Markdown(每个 Skill 目录下有一个 SKILL.md,里面详细描述执行步骤、最佳实践、示例代码等)。但 nanoAgent 原始仓库中采用的是 JSON 格式,所以代码里用 json.load() 来解析。这不影响理解核心思路——不管是 Markdown 还是 JSON,本质都是"把技能描述加载出来注入到 system prompt"。格式只是载体,思想是一样的。4.2 Skills vs RulesRules 管约束,Skills 管能力。一个告诉 Agent "做人的底线",一个告诉 Agent "做事的方法"。五、MCP:让 Agent 拥有无限工具的协议5.1 什么是 MCP?回忆第一篇中 agent.py 的工具定义方式——直接在代码里硬编码。想加一个新工具?改代码、重新部署。这在生产环境中完全不可接受。MCP(Model Context Protocol)是 Anthropic 提出的一个开放标准,它定义了 LLM 与外部工具之间的通信协议。你可以把 MCP 理解为"AI 世界的 USB 接口"——任何遵循这个协议的工具服务都可以即插即用地接入 Agent。如果你用过 Claude Code,你一定在配置文件里见过 mcpServers 这个字段——配置一个 GitHub MCP Server,Agent 就能直接操作 PR 和 Issue;配置一个数据库 MCP Server,Agent 就能执行 SQL 查询。这就是 MCP 的威力。5.2 agent-claudecode.py 中的 MCP 实现MCP_CONFIG = ".agent/mcp.json" def load_mcp_tools(): ifnot os.path.exists(MCP_CONFIG): return [] try: with open(MCP_CONFIG, 'r') as f: config = json.load(f) mcp_tools = [] for server_name, server_config in config.get("mcpServers", {}).items(): if server_config.get("disabled", False): continue for tool in server_config.get("tools", []): mcp_tools.append({"type": "function", "function": tool}) return mcp_tools except: return []配置文件 .agent/mcp.json:{ "mcpServers": { "filesystem": { "disabled": false, "tools": [{ "name": "list_directory", "description": "List contents of a directory with metadata", "parameters": { "type": "object", "properties": {"path": {"type": "string"}}, "required": ["path"] } }] }, "database": { "disabled": true, "tools": [...] } } }5.3 MCP 的精髓:一行代码all_tools = base_tools + mcp_tools这一行是整个 MCP 集成的精髓。MCP 加载的工具和基础工具使用完全相同的 JSON Schema 格式,直接拼接成一个列表传给 LLM。LLM 完全不需要知道某个工具是"内置的"还是"MCP 加载的"——对它来说,工具就是工具。5.4 nanoAgent 简化了什么需要说明的是,nanoAgent 的 MCP 实现是高度简化的——它只实现了"工具注册"(把 schema 加载给 LLM),没有实现"工具执行"(通过网络调用远程 MCP Server)。实际调用时会走到 else 分支返回 "Tool not implemented":虽然不完整,但它展示了 MCP 集成的核心思路:工具定义与工具实现的分离。在完整实现中,那个 else 分支会变成一个 MCP 客户端调用。5.5 MCP 解决的根本问题没有 MCP 的世界: 有 MCP 的世界: Agent A Agent B MCP Server: Slack MCP Server: GitHub ├── Slack (自写) ├── Slack (自写) │ │ ├── GitHub(自写) ├── Jira (自写) └───── 标准协议 ──┘ └── DB (自写) └── DB (自写) │ ┌───────┼───────┐ 每个 Agent 各写各的 Agent A Agent B Agent C N × M 的工作量 工具实现一次,全部共享 N + M 的工作量六、Plan-as-Tool:规划从"被动触发"到"自主决策"6.1 进化路径回顾三个版本中,规划经历了清晰的进化: 在 agent-claudecode.py 中,plan 出现在工具列表里:{"name": "plan", "description": "Break down complex task into steps and execute sequentially", ...}这意味着 LLM 遇到复杂任务时可以主动调用 plan 工具进行拆解,无需用户干预。6.2 递归执行与防无限循环plan 工具的执行逻辑是整个文件最复杂的部分:if function_name == "plan": plan_mode = True function_response = available_functions[function_name](**function_args "function_name") messages.append({"role": "tool", "tool_call_id": tool_call.id, "content": function_response}) if current_plan: results = [] for i, step in enumerate(current_plan, 1): messages.append({"role": "user", "content": step}) result, messages = run_agent_step( messages, [t for t in tools if t["function"]["name"] != "plan"] # 关键:排除 plan ) results.append(result) plan_mode = False current_plan = [] return "\n".join(results), messages三个关键设计:递归调用 run_agent_step。 Plan 生成的每个步骤都通过 run_agent_step 执行,每步内部仍然可以使用 read、write、bash 等工具。这形成了一个两层循环——外层是规划步骤,内层是每步的 ReAct 循环。排除 plan 工具本身。 执行步骤时的工具列表中刻意去掉了 plan,配合 plan_mode 全局变量双重保护,防止"在规划中再次规划"的无限递归。上下文跨步共享。 和第二篇中一样,messages 在所有步骤间共享。 用户: "重构项目的测试框架" │ ▼ LLM 判断任务复杂 → 主动调用 plan 工具 │ ▼ plan() 返回 4 个步骤 │ ├── Step 1: 分析当前测试结构 │ └── run_agent_step() → [glob, read, grep] │ ├── Step 2: 创建新的测试目录 │ └── run_agent_step() → [bash, write] │ ├── Step 3: 迁移现有测试文件 │ └── run_agent_step() → [read, edit, write] │ └── Step 4: 验证所有测试通过 └── run_agent_step() → [bash]七、全部模块如何组装在一起 def run_agent_claudecode(task, use_plan=False): print("[Init] Loading ClaudeCode features...") # 1. 从文件系统加载所有外部配置 memory = load_memory() # 历史记忆 rules = load_rules() # 行为规则 skills = load_skills() # 技能注册 mcp_tools = load_mcp_tools() # MCP 外部工具 # 2. 合并工具列表(基础工具 + MCP 工具) all_tools = base_tools + mcp_tools # 3. 构建 system prompt(基础指令 + Rules + Skills + Memory) context_parts = ["You are a helpful assistant..."] if rules: context_parts.append(f"\n# Rules\n{rules}") if skills: context_parts.append(f"\n# Skills\n...") if memory: context_parts.append(f"\n# Previous Context\n{memory}") messages = [{"role": "system", "content": "\n".join(context_parts)}] # 4. 执行 ...┌─────────────────────── 文件系统 ───────────────────────┐ │ │ │ .agent/rules/*.md → load_rules() → system prompt │ │ .agent/skills/*.json → load_skills() → system prompt │ │ .agent/mcp.json → load_mcp_tools()→ tools 列表 │ │ agent_memory.md → load_memory() → system prompt │ │ │ └─────────────────────────────────────────────────────────┘ │ ▼ ┌──── Agent 运行时 ────┐ │ │ │ system prompt = │ │ 基础指令 │ │ + Rules │ │ + Skills │ │ + Memory │ │ │ │ tools = │ │ base_tools (7个) │ │ + mcp_tools (N个) │ │ │ └──────────────────────┘这个架构揭示了一个重要原则:Agent 的能力由两个正交维度定义prompt 维度(知道什么):Rules、Skills、Memory 扩展的是 LLM 的认知tools 维度(能做什么):MCP 扩展的是 LLM 的行动能力两者独立变化、自由组合,构成了 Agent 的完整能力空间。八、从 115 行到 265 行的认知地图三篇文章读下来,我们在 265 行代码里看到了 Agent 的全部核心概念。用一张七层架构图来做最后的回顾:┌───────────────────────────────────────────────────────┐ │ Agent 架构全景 │ │ │ │ ┌──────────────┐ 第三篇:agent-claudecode.py │ │ │ Rules │ 行为约束层 ──── .agent/rules/ │ │ │ Skills │ 技能知识层 ──── .agent/skills/ │ │ │ MCP │ 工具扩展层 ──── .agent/mcp.json │ │ │ Plan Tool │ 自主规划层 ──── plan() 作为工具 │ │ ├──────────────┤ 第二篇:agent-plus.py │ │ │ Memory │ 持久记忆层 ──── agent_memory.md │ │ │ Planning │ 任务分解层 ──── create_plan() │ │ │ Multi-step │ 多步编排层 ──── 步骤间上下文共享 │ │ ├──────────────┤ 第一篇:agent.py │ │ │ LLM │ 推理决策层 ──── OpenAI API │ │ │ Tools │ 工具执行层 ──── bash/read/write │ │ │ Loop │ 核心循环层 ──── for + tool_calls │ │ └──────────────┘ │ └───────────────────────────────────────────────────────┘每一层都在回答一个关键问题: 这七层架构,就是当今所有主流 Agent 框架(OpenClaw、Claude Code、Cursor Agent、Devin、OpenHands 等)的共同骨架。nanoAgent 用不到 300 行 Python 代码,把这个骨架完整地呈现了出来。九、结语 如果你跟着这三篇文章走了下来,你已经理解了 Agent 最核心的架构要素。但还有一个问题我们没有触及:当任务复杂到一个 Agent 忙不过来时怎么办?能不能让 Agent 自己找帮手?这就是多智能体协作——SubAgent 的领域。在 第四篇:SubAgent 子智能体 中,我们将用不到 30 行新增代码,让主 Agent 学会"分工派活"。★ "The question is not what you look at, but what you see." — Henry David ThoreaunanoAgent README 的这句引言,放在这里再合适不过。看过这 265 行代码之后,当你再打开 OpenClaw、Claude Code、Cursor 或任何 Agent 产品时,你看到的不再是"魔法",而是——一个循环、几个工具、一段记忆、一份规则。本文基于 sanbuphy/nanoAgent 的 agent-claudecode.py 分析。完整系列:第一篇:底层原理→ 第二篇:记忆与规划 → 第三篇:Rules、Skills 与 MCP(本文) → 第四篇:SubAgent 子智能体。相关链接 [1] nanoAgent: cid:link_4 [2] 第一篇: cid:link_2 [3] 第二篇: cid:link_3[ 4] agent-claudecode.py: cid:link_4/blob/main/agent-claudecode.py AGENT交流群,一起玩转AGENT
-
欢迎阅读 「从零开始理解 Agent」系列 文章—— 我们将通过一个不到 300 行的开源项目 nanoAgent,逐层拆解 OpenClaw / Claude Code 等 AI Agent 背后的全部核心概念。第一篇:底层原理,只有 115 loc(*lines of code) —— 工具 + 循环第二篇:记忆与规划(本文)—— 182 loc第三篇:Rules、Skills 与 MCP] —— 265 loc★ 项目地址:cid:link_0作者:十一上一篇我们用 115 行代码理解了 Agent 的核心公式:LLM + 工具 + 循环。但在结尾我们也指出了它的致命缺陷——没有记忆、不会规划。如果你用过 OpenClaw 或 Claude Code,你会发现它们可以在一个长对话中持续记住之前的操作,面对复杂需求时也会先制定计划再逐步执行。这些能力不是"魔法",而是可以用很少的代码实现的架构设计。今天我们看 nanoAgent 的第二个版本 agent-plus.py(182 行),它只多了 67 行代码,却解决了两个根本问题:让 Agent 记住过去,让 Agent 规划未来。一、从 agent.py 到 agent-plus.py:多了什么?工具层完全没变——新增的 67 行全部用来构建更高层的能力。这恰好印证了第一篇的结论:工具 + 循环只是地基,记忆和规划才是让 Agent 真正可用的关键。二、记忆系统:最朴素但最本质的方案2.1 记忆的存储:一个 Markdown 文件MEMORY_FILE = "agent_memory.md"def save_memory(task, result): timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") entry = f"\n## {timestamp}\n**Task:** {task}\n**Result:** {result}\n" try: with open(MEMORY_FILE, 'a') as f: f.write(entry) except: passagent-plus.py 用了一种极其朴素的方案——把历史任务和结果追加写入一个 Markdown 文件。没有数据库,没有向量索引,就是纯文本。每次任务执行完毕,Agent 把"什么时间、做了什么、得到什么结果"追加到文件末尾:## 2026-03-12 14:30:00**Task:** 统计当前目录下的 Python 文件数量**Result:** 当前目录下共有 42 个 Python 文件。## 2026-03-12 15:00:00**Task:** 创建一个 hello.py**Result:** 已创建 hello.py,内容为打印 Hello World。2.2 记忆的加载:滑动窗口def load_memory(): ifnot os.path.exists(MEMORY_FILE): return"" try: with open(MEMORY_FILE, 'r') as f: content = f.read() lines = content.split('\n') return'\n'.join(lines[-50:]) if len(lines) > 50else content except: return ""加载出来的记忆被拼接到 system prompt 末尾,以 "Previous context" 的形式注入。LLM 在处理新任务时能"看到"之前的历史。2.4 记忆流程全景第 1 次运行 第 2 次运行─────────── ───────────用户: "创建 hello.py" 用户: "读取 hello.py 并加上注释" │ │ ▼ ▼ system prompt: system prompt: "You are a helpful "You are a helpful assistant..." assistant... Previous context: ## 2026-03-12 14:30 Task: 创建 hello.py Result: 已创建..." │ │ ▼ ▼ Agent 执行任务 Agent 执行任务 │ (知道之前创建过 hello.py) ▼ │ save_memory() ──写入──▶ agent_memory.md ◀─── save_memory()2.5 记忆的本质这个方案虽然原始,但揭示了一个根本原理:LLM 本身没有持久记忆,所有"记忆"都是通过在 prompt 中注入历史信息来实现的。无论是 Claude 的 Memory、ChatGPT 的记忆功能,还是更复杂的 RAG 系统,底层都遵循这个模式——只是在"存在哪、怎么找、搬多少"上做得更精细。我们会在文末讨论这些进化方向。三、规划系统:让 Agent 学会"先想再做"3.1 为什么需要规划?回忆第一篇中 agent.py 的工作方式:把整个任务丢给 LLM,让它在循环中自行摸索。简单任务没问题,但面对复杂任务(比如"重构整个项目的目录结构"),LLM 容易迷失在细节中,忘记全局目标。agent-plus.py 引入了一个可选的规划阶段:def create_plan(task): print("[Planning] Breaking down task...") response = client.chat.completions.create( model=os.environ.get("OPENAI_MODEL", "gpt-4o-mini"), messages=[ {"role": "system", "content": "Break down the task into 3-5 simple, actionable steps. Return as JSON array of strings."}, {"role": "user", "content": f"Task: {task}"} ], response_format={"type": "json_object"} ) try: plan_data = json.loads(response.choices[0].message.content) steps = plan_data.get("steps", [task]) print(f"[Plan] {len(steps)} steps created") for i, step in enumerate(steps, 1): print(f" {i}. {step}") return steps except: return [task]3.2 规划的设计细节这段代码有几个值得细品的地方:用 LLM 来做规划。 规划本身也是一次 LLM 调用,但不带任何工具——纯粹的"思考"。system prompt 要求 LLM 把任务拆解为 3-5 个可执行的步骤,以 JSON 格式返回。结构化输出。 通过 response_format={"type": "json_object"} 强制 LLM 返回 JSON,避免格式解析问题。优雅降级。 如果 JSON 解析失败,except 分支回退到 [task]——即不拆解,整个任务当作一步执行。这种防御性编程在 Agent 开发中非常重要。3.3 两种执行范式的对比agent.py 和 agent-plus.py 代表了 Agent 领域的两种经典范式:agent.py (ReAct) agent-plus.py (Plan-then-Execute)思考 → 行动 → 观察 规划(全局思考) ↑ │ │ └─────────┘ 步骤1 → 步骤2 → 步骤3 (每步内部仍是 ReAct)ReAct 灵活但容易迷失,Plan-then-Execute 有全局视角但规划可能不准确。agent-plus.py 通过 --plan 参数让用户自行选择——这种"默认简单,按需复杂"的设计在工程上很实用。四、多步执行:步骤之间的上下文传递4.1 从 run_agent 到 run_agent_step 的关键变化对比第一篇中 agent.py 的 run_agent 函数,agent-plus.py 的 run_agent_step 有两个关键变化:def run_agent_step(task, messages, max_iterations=5): messages.append({"role": "user", "content": task}) actions = [] for _ in range(max_iterations): response = client.chat.completions.create( model=os.environ.get("OPENAI_MODEL", "gpt-4o-mini"), messages=messages, tools=tools ) message = response.choices[0].message messages.append(message) ifnot message.tool_calls: return message.content, actions, messages for tool_call in message.tool_calls: function_name = tool_call.function.name function_args = json.loads(tool_call.function.arguments) print(f"[Tool] {function_name}({function_args})") function_response = available_functions[function_name](**function_args "function_name") actions.append({"tool": function_name, "args": function_args}) messages.append({"role": "tool", "tool_call_id": tool_call.id, "content": function_response}) return "Max iterations reached", actions, messages变化一:messages 从内部创建变为外部传入。 这意味着多个步骤可以共享同一个对话历史。步骤 1 执行 grep 搜索到的结果,在步骤 2 中仍然可见。变化二:返回值包含 messages。 函数把更新后的消息列表返回给调用方,供下一步继续使用。4.2 编排层:把步骤串起来all_results = []for i, step in enumerate(steps, 1): if len(steps) > 1: print(f"\n[Step {i}/{len(steps)}] {step}") result, actions, messages = run_agent_step(step, messages) all_results.append(result)final_result = "\n".join(all_results)save_memory(task, final_result)messages 变量在整个步骤循环中是同一个列表对象。 步骤 1 执行过程中产生的所有工具调用和结果,都会累积在这个列表中,步骤 2 的 LLM 调用能看到步骤 1 的完整执行轨迹。这引出了一个重要的概念区分——短期记忆与长期记忆: 五、完整运行时序示例以 python agent-plus.py --plan "找到所有 TODO 并整理到 todo.md" 为例:[Planning] Breaking down task...[Plan] 3 steps created 1. 使用 grep 递归搜索所有 TODO 注释 2. 整理搜索结果为 Markdown 清单格式 3. 将清单写入 todo.md[Step 1/3] 使用 grep 递归搜索所有 TODO 注释[Tool] execute_bash({"command": "grep -rn 'TODO' --include='*.py' ."}) → ./app.py:23: # TODO: add error handling → ./utils.py:7: # TODO: refactor this function → ./main.py:45: # TODO: add logging找到 3 处 TODO 注释。[Step 2/3] 整理搜索结果为 Markdown 清单格式(LLM 看到步骤 1 的 grep 结果,直接整理,无需再次搜索)已整理为以下清单:- app.py:23 - add error handling- utils.py:7 - refactor this function- main.py:45 - add logging[Step 3/3] 将清单写入 todo.md[Tool] write_file({"path": "todo.md", "content": "# TODO List\n\n..."})已将 TODO 清单写入 todo.md。注意步骤 2 没有调用任何工具——LLM 直接从 messages 中读取了步骤 1 的 grep 输出并整理。这就是上下文传递的威力。六、记忆方案的局限与进化方向nanoAgent 的记忆方案堪称"最小可行记忆",但它清晰地暴露了四个需要进化的方向:记忆无差别截断 → 向量数据库 + 语义检索。只保留最后 50 行会丢失重要的早期信息。更好的方案是把记忆存入向量数据库(如 Chroma、Pinecone),每次只检索与当前任务语义相关的记忆。这就是 RAG 的核心思路。无记忆压缩 → 记忆蒸馏。当记忆超过阈值时,用 LLM 自动压缩旧记忆——提取关键事实,丢弃细节。比如把"执行了 grep -rn TODO,找到 app.py:23、utils.py:7、main.py:45 三处"压缩为"项目中有 3 处 TODO 待处理"。全量注入 prompt → 记忆作为工具。不把记忆塞进 system prompt,而是提供一个 search_memory 工具让 Agent 按需查询。Agent 自己决定什么时候需要回忆、回忆什么。单层记忆 → 分层记忆架构。参考人类记忆的工作方式:工作记忆(当前 messages)→ 短期记忆(最近几次对话摘要)→ 长期记忆(压缩后的关键事实)。每层的信息密度和保留时间不同。七、总结与下一篇预告三个核心启示:1. 记忆的本质是"信息搬运"。 LLM 没有真正的记忆,所有记忆都是把外部存储的信息搬运到 prompt 中。不同方案的区别只在于"存在哪、怎么找、搬多少"。2. 规划让 Agent 有了全局视角。 没有规划的 Agent 像是蒙着眼走迷宫;有规划的 Agent 至少先看了一眼地图。虽然地图可能不准确,但总比没有强。3. 上下文传递是多步执行的关键。messages 列表在步骤间的共享,让后续步骤能利用前面步骤的执行结果,避免重复工作。现在我们的 Agent 有了记忆和规划能力,但还有三个问题没解决:工具是硬编码的——想接入 Slack、GitHub、数据库等外部服务怎么办?没有行为约束——不同项目、不同团队对 Agent 的要求完全不同,怎么定制?规划是被动触发的——用户必须手动加 --plan 参数,Agent 自己不知道什么时候该规划。这三个问题,引出了 Agent 架构中最后也是最精彩的三个概念:MCP(工具协议)、Rules(行为规则)、Skills(技能注册)。如果你用过 OpenClaw 或 Claude Code,你一定见过 CLAUDE.md 规则文件和 MCP 工具配置——它们正是这三个概念的工程化产物。在 第三篇:Rules、Skills 与 MCP 中,我们将看到 agent-claudecode.py 如何用 265 行代码,把 nanoAgent 进化为一个接近 OpenClaw / Claude Code 的完整 Agent 框架。*本文基于 sanbuphy/nanoAgent 的 agent-plus.py 分析。如果你还没有读过系列第一篇,建议先从 底层原理,只有 115行 开始。相关链接[1] nanoAgent: cid:link_0[2] agent-plus.py: https://github.com/GitHubxsy/nanoAgent/blob/main/agent-plus.py[3] agent.py: https://github.com/GitHubxsy/nanoAgent/blob/main/agent.py[4] 第一篇:底层原理,只有 115 行 —— 工具 + 循环: https://mp.weixin.qq.com/s/gz_vPvgTdozh4FO6vEdF-Q AGENT交流群,一起玩转AGENT
-
欢迎阅读 「从零开始理解 Agent」系列 文章,我们将通过一个不到 300 行的开源项目 nanoAgent,逐层拆解 OpenClaw / Claude Code 等 AI Agent 背后的全部核心概念。第一篇:底层原理,只有 115 loc(*lines of code)—— 工具 + 循环(本文)第二篇:记忆与规划 ——182 loc第三篇:Rules、Skills 与 MCP——265 loc★ 项目地址:cid:link_0作者:十一很多人用过 ChatGPT、Claude 这样的对话式 AI,也听说过 AI Agent 这个概念。最近 OpenClaw、Claude Code 这类 Agent 火遍了整个开发者圈子——它们能自主写代码、发邮件,完成以前需要人类手动操作的整个工作流程。但 Agent 到底和普通对话有什么区别?OpenClaw / Claude Code 这类工具的底层原理是什么?Agent 是怎么"使用工具"的?本文通过逐行解读一个仅 115 行的极简 Agent 实现—— sanbuphy/nanoAgent,带你彻底搞懂这些问题。理解了这 115 行代码,你就理解了 OpenClaw、Claude Code、Cursor Agent 等一切 Agent 的共同底座。一、先说结论:Agent 和普通对话的核心区别在深入代码之前,先建立一个直觉:一句话总结:Agent = LLM + 工具 + 循环。普通对话是"你问我答",Agent 是"你给我一个目标,我自己想办法完成"。这三个要素缺一不可。没有 LLM,就没有"思考"能力;没有工具,就无法作用于真实世界;没有循环,就做不了多步任务。接下来我们看 nanoAgent 是怎么用 115 行代码实现这三要素的。二、nanoAgent 全局架构nanoAgent 的 agent.py 只有 115 行,但五脏俱全。整体结构可以拆成四个部分:下面逐层拆解。三、逐层解读源码3.1 LLM 客户端初始化import osimport jsonimport subprocessimport sysfrom openai import OpenAIclient = OpenAI( api_key=os.environ.get("OPENAI_API_KEY"), base_url=os.environ.get("OPENAI_BASE_URL"))这里用的是 OpenAI 的 Python SDK,但通过 base_url 环境变量,可以指向任何兼容 OpenAI API 格式的服务(比如 DeepSeek、Qwen、本地 Ollama 等)。这是一个非常实用的设计——Agent 框架不绑定具体模型。3.2 工具定义:告诉 LLM "你有哪些能力"tools = [ { "type": "function", "function": { "name": "execute_bash", "description": "Execute a bash command on the system", "parameters": { "type": "object", "properties": { "command": {"type": "string", "description": "The bash command to execute"} }, "required": ["command"] } } }, # ... read_file, write_file 类似]这是 OpenAI Function Calling 的标准格式。这段 JSON Schema 本质上是一份工具说明书,它会随着每次 API 请求一起发送给 LLM。LLM 读到这份说明书后,就"知道"自己可以执行 bash 命令、读文件、写文件。nanoAgent 定义了三个工具:★ 关键洞察:LLM 本身不会执行任何代码。它只是根据工具说明书,输出一段结构化的 JSON,表达"我想调用 execute_bash,参数是 ls -la"。真正的执行发生在我们的 Python 代码里。这个"LLM 输出意图、代码执行动作"的分工,是理解所有 Agent 系统的关键。3.3 工具实现:把 LLM 的"意图"变成"行动"def execute_bash(command): try: result = subprocess.run(command, shell=True, capture_output=True, text=True, timeout=30) return result.stdout + result.stderr except Exception as e: returnf"Error: {str(e)}"def read_file(path): try: with open(path, 'r') as f: return f.read() except Exception as e: returnf"Error: {str(e)}"def write_file(path, content): try: with open(path, 'w') as f: f.write(content) returnf"Successfully wrote to {path}" except Exception as e: returnf"Error: {str(e)}"这三个函数就是工具的"真身"。几个值得注意的细节:错误处理:每个函数都用 try-except 包裹,确保即使执行出错也能把错误信息返回给 LLM,而不是让整个程序崩溃。这很重要——LLM 看到错误后可以自行修正策略。timeout=30:bash 命令有 30 秒超时限制,防止死循环或长时间阻塞。shell=True:意味着可以执行管道、重定向等复杂 shell 语法,能力很强,但安全风险也很大。接下来是一个路由表,把工具名映射到实际函数:available_functions = { "execute_bash": execute_bash, "read_file": read_file, "write_file": write_file}这个字典是工具调度的核心——当 LLM 说"我要调用 execute_bash"时,代码通过这个字典找到对应的 Python 函数并执行。3.4 Agent 核心循环:最精华的 20 行代码def run_agent(user_message, max_iterations=5): messages = [ {"role": "system", "content": "You are a helpful assistant that can interact with the system. Be concise."}, {"role": "user", "content": user_message} ] for _ in range(max_iterations): # Step 1: 把完整对话历史 + 工具列表发给 LLM response = client.chat.completions.create( model=os.environ.get("OPENAI_MODEL", "gpt-4o-mini"), messages=messages, tools=tools ) message = response.choices[0].message messages.append(message) # Step 2: 如果 LLM 没有调用工具 → 任务完成,返回文本回答 ifnot message.tool_calls: return message.content # Step 3: 如果 LLM 要调用工具 → 逐个执行,把结果追加到对话历史 for tool_call in message.tool_calls: function_name = tool_call.function.name function_args = json.loads(tool_call.function.arguments) print(f"[Tool] {function_name}({function_args})") function_response = available_functions[function_name](**function_args "function_name") messages.append({ "role": "tool", "tool_call_id": tool_call.id, "content": function_response }) return"Max iterations reached"这 20 多行代码是整个 Agent 的灵魂。让我逐步拆解这个循环里发生了什么。四、Agent 循环的运行时序(核心重点)以一个具体例子来说明。假设用户运行:python agent.py "统计当前目录下有多少个 Python 文件,并把结果写入 count.txt"Agent 的执行过程如下:第 1 轮循环发送给 LLM 的 messages:[system] You are a helpful assistant...[user] 统计当前目录下有多少个 Python 文件,并把结果写入 count.txtLLM 返回: 不是普通文本,而是一个 tool_call:{ "tool_calls": [{ "function": {"name": "execute_bash", "arguments": "{\"command\": \"find . -name '*.py' | wc -l\"}"} }]}代码执行: 调用 execute_bash("find . -name '*.py' | wc -l"),得到结果 "42\n"追加到 messages:[tool] 42第 2 轮循环发送给 LLM 的 messages: 现在包含了完整历史(system + user + assistant的tool_call + tool结果)LLM 看到结果是 42,决定写入文件:{ "tool_calls": [{ "function": {"name": "write_file", "arguments": "{\"path\": \"count.txt\", \"content\": \"Python files: 42\"}"} }]}代码执行: 调用 write_file("count.txt", "Python files: 42")第 3 轮循环LLM 看到文件写入成功,判断任务已完成,返回纯文本:"已统计完成,当前目录下共有 42 个 Python 文件,结果已写入 count.txt。"not message.tool_calls 为 True → 退出循环,返回结果。用一张图来表示:用户任务 │ ▼┌──────────────────────────────────────────────────┐│ Agent Loop ││ ││ ┌─────────┐ ┌──────────┐ ┌──────────────┐ ││ │ 发送给 │───▶│ LLM 决策 │───▶│ 有tool_call? │ ││ │ LLM │ │ │ └──────┬───────┘ ││ └─────────┘ └──────────┘ │ ││ ▲ Yes │ No ││ │ ┌─────┴─────┐ ││ │ ▼ ▼ ││ ┌────┴────────┐ ┌──────────┐ 返回文本 ││ │ 结果追加到 │◀─────────│ 执行工具 │ ──────▶ ││ │ messages │ └──────────┘ 结束 ││ └─────────────┘ │└──────────────────────────────────────────────────┘五、深入理解几个关键设计5.1 为什么需要 max_iterations?for _ in range(max_iterations): # 默认 5 次这是一个安全阀。如果 LLM 陷入死循环(比如反复执行同一个失败的命令),max_iterations 确保程序最终会停下来。在生产级 Agent 中,这个值通常更大(比如 Claude Code 可以连续执行数十步),同时会配合更复杂的终止策略。5.2 messages 列表为什么如此重要?messages 是 Agent 的短期记忆。每一轮循环,它都会累积 LLM 的回复(包括它想调用什么工具)以及工具的执行结果。当这个列表在下一轮发送给 LLM 时,LLM 能看到完整的"行动-观察"历史,从而做出更合理的下一步决策。这就是 Agent 和简单对话的本质区别——Agent 维护了一条包含行动轨迹的上下文链。但请注意,这里的 messages 只在单次运行中存在。程序退出后,一切归零。Agent 下次运行时完全不记得上次做过什么。这个"失忆"问题,正是我们在第二篇连载中要解决的。5.3 LLM 是怎么"决定"调用工具的?这是最容易产生误解的地方。LLM 并没有真的在"执行代码"或"调用函数"。实际发生的是:我们在 API 请求中传入了 tools 参数(工具说明书)LLM 经过训练,学会了在适当的时候输出一种特殊的结构化格式(tool_calls)这个格式本质上就是一段 JSON,描述"我想调用哪个函数、传什么参数"我们的代码解析这段 JSON,执行真正的函数,再把结果喂回给 LLM所以整个过程可以理解为一种协作协议:LLM 的职责:思考、决策、生成工具调用指令代码的职责:解析指令、执行工具、返回结果LLM 是"大脑",代码是"手脚"。5.4 tool_call_id 的作用messages.append({ "role": "tool", "tool_call_id": tool_call.id, "content": function_response})tool_call_id 是 OpenAI API 的要求,用于将工具返回结果与对应的调用请求关联起来。当 LLM 在一次回复中同时调用多个工具时(并行调用),这个 ID 确保每个结果能正确匹配到对应的调用。六、这个 Agent 还缺什么?nanoAgent 的极简设计让核心概念一目了然,但如果你仔细想想,会发现它有几个根本性的缺陷:1. 没有记忆。 每次运行都是一张白纸。昨天让它创建的文件,今天问它"你昨天干了什么",它一脸茫然。2. 没有规划。 面对"重构整个项目"这样的复杂任务,它只能走一步看一步,容易迷失在细节中。3. 工具是硬编码的。 只有 3 个工具,想加新工具必须改代码。没有任何扩展机制。4. 没有行为约束。 它可以执行 rm -rf /,没有任何规则告诉它什么该做、什么不该做。这些缺陷,恰好对应了 Agent 架构中更高层次的需求。nanoAgent 的作者也意识到了这一点,所以他写了两个进化版本来逐一解决。七、从 nanoAgent 看 Agent 的本质回到最初的问题:Agent 到底是什么?通过 nanoAgent 的 115 行代码,我们可以提炼出 Agent 的三个本质要素:1. 感知(Perception)—— 通过工具获取外部信息(read_file、execute_bash 的输出)2. 决策(Reasoning)—— LLM 根据任务目标和已有观察,决定下一步行动3. 行动(Action)—— 通过工具作用于外部环境(write_file、execute_bash)这三者在一个循环中不断迭代,直到 LLM 判断任务完成(不再调用工具)。这就是 Agent 最朴素、最本质的运行方式——**"思考 → 行动 → 观察"(ReAct)**范式。无论是 OpenClaw、Claude Code、Cursor 还是 Devin,底层都遵循这个范式。当你在 OpenClaw 中看到它自动 grep 搜索代码、edit 修改文件、bash 跑测试时,背后就是这样一个循环在驱动。nanoAgent 用最少的代码,把这个范式展现得淋漓尽致。八、动手试一试如果你想亲手体验,只需:如果你想亲手体验,只需:# 克隆项目git clone cid:link_0.gitcd nanoAgent# 设置环境变量(可以用任何兼容 OpenAI API 的服务)export OPENAI_API_KEY="your-key"export OPENAI_BASE_URL="https://api.openai.com/v1" # 或 DeepSeek/Qwen 等# 运行python agent.py "帮我创建一个 hello.py 文件,内容是打印当前时间"然后观察终端输出的 [Tool] 日志,你就能清晰地看到 Agent 的每一步决策和行动。下一篇预告现在我们有了一个能干活的 Agent,但它像一条金鱼——做完就忘。如何让 Agent 拥有记忆,记住之前做过的事?如何让它面对复杂任务时先规划再执行,而不是蒙头乱撞?这些问题,我们在 第二篇:记忆与规划——182 loc 中解答。代码只多了 67 行,但能力产生质变。本文基于 sanbuphy/nanoAgent 项目分析,感谢项目作者用极简的代码诠释了 Agent 的核心思想。
-
京时间2026年3月11日,KubeEdge 发布 1.23.0 版本。新版本通过深度优化 Windows 兼容性、引入设备异常检测框架以及重构边缘数据库,显著提升了边缘侧的运维能力、数据处理可靠性和整体性能。同时发布了新版本 Dashboard,在用户交互上带来全新体验。KubeEdge v1.23.0 新增特性:Windows 操作系统下的 EdgeCore 与 Keadm 能力增强 新增设备异常检测能力优化边缘侧查询节点流程,降低边云通道带宽占用使用 Gorm 替换 Beego,并重构边缘数据库升级 K8s 依赖到1.32Dashboard 新版本发布:国际化(中文)支持、性能提升与页面优化 新特性概览 ▍Windows 操作系统下的 EdgeCore 与 Keadm 能力增强在 1.23.0 版本中,我们对 EdgeCore 和 keadm 在 Windows OS 的能力进行了如下增强:提供了本地DMI服务:由于 Windows 不支持 Unix Domain Socket,我们引用了Windows 命名管道(Named Pipes)实现本地网络通信;keadm 升级/下载增强:在v1.23.0中,keadm 会检测本地 edgecore.exe 的版本信息,如果或有更高版本可用,则自动重新下载 EdgeCore 包,避免因本地已存在 edgecore.exe 而导致升级被跳过;可观测性增强:在新版本中,EdgeCore 日志会被重定向到可配置的日志文件,优化Windows环境下的运维与故障排查。➤ 更多信息可参考:cid:link_3cid:link_4cid:link_5▍新增设备异常检测能力v1.23.0 引入了设备异常检测框架,您可在 Device CRD 的 pushMethod 字段中指定异常检测相关配置apiVersion: devices.kubeedge.io/v1beta1kind: Devicespec: properties: pushMethod: anomolyDetection: ... // 指定异常检测字段,如设备工作状态等同时我们在 Mapper 中实现了设备异常检测处理逻辑,您可以定制化设计处理设备异常数据。 另外,我们在 Example 仓库提供了设备异常检测的Demo,方便您快速了解并试用新的能力。详情查看:cid:link_11➤ 更多信息可参考:cid:link_6cid:link_7▍优化边缘侧查询节点流程,降低边云通道带宽占用之前的版本中,EdgeCore 需要通过边云通道远程查询节点信息,在大规模场景下,边云通道带宽消耗尤其显著。在新版本中,EdgeCore 直接从边缘数据库查询节点,同时,CloudCore 检测到节点信息更新时会自动同步到边缘数据库,显著提升了大规模边缘场景下的系统性能和可靠性。➤ 更多信息可参考:cid:link_7▍使用 Gorm 替换 Beego,并重构边缘数据库原有的边缘数据库使用的 Beego 框架,实际上仅用到了 ORM 部分。在新版本中,我们使用更轻量的 Gorm 替换 Beego 框架。同时,对边缘数据库进行重构,在 MetaManager 中引入统一的数据库操作入口,使数据库交互更清晰、易维护。➤ 更多信息可参考:cid:link_2cid:link_8▍升级K8s依赖到1.32新版本将依赖的 Kubernetes 版本升级到 v1.32.10,您可以在云和边缘使用新版本的特性。➤ 更多信息可参考:cid:link_9▍Dashboard 新版本发布:国际化(中文)支持、性能提升与页面优化Dashboard v0.2.0 正式发布,包括如下更新:引入 Backend-for-Frontend(BFF)架构,建立数据处理中间层,优化数据处理逻辑,提升前端性能;引入国际化语言框架,并新增中文语言包支持;全面优化 Dashboard的UI 体验,统一页面风格,重点优化 PodTable、TableView 等表单组件,提升用户交互体验。➤ 更多信息可参考:cid:link_1 版本升级注意事项 v1.23.0 开始,Device CRD 的 Status 字段将分离出来,单独作为 DeviceStatus CRD 使用。该变更兼容旧版CRD,但需注意,在后续版本中设备状态需要通过新的 DeviceStatus CRD 获取。➤ 更多信息可参考:cid:link_10▍致谢感谢KubeEdge社区技术指导委员会(TSC)、各SIG成员对v1.23版本开发的支持与贡献,未来KubeEdge将持续在新场景探索与支持、稳定性、安全性、可扩展性等方面持续发展与演进!▍相关链接➤ Release Notes:cid:link_0添加小助手k8s2222回复KubeEdge进群
-
做技术选型时,很多研发、运维同学都会陷入一个困惑:同样是云端数据库,RDS 和云原生数据库到底该怎么选?前者成熟稳定,后者灵活高效,看似都能满足业务需求,但选错了不仅会增加运维成本,还可能拖累业务增长。其实两者的核心区别,本质是“传统数据库上云”和“为云而生的数据库”的差异——RDS 是把传统数据库适配到云端,而云原生数据库是从底层架构就贴合云计算的弹性、分布式特性设计的。今天就从 8 个核心维度,用通俗的语言拆解两者的差异,再给出明确的选型逻辑,帮你避开选型坑。先给大家一个直观的结论:如果业务稳定、需求明确,追求低成本和低运维门槛,选 RDS;如果业务高速增长、流量波动大,需要高弹性和高并发支撑,选云原生数据库。下面我们一步步拆解细节。 一、先搞懂:两者到底是什么?(通俗版定义)在对比之前,先明确两个概念,避免混淆,全程不涉及任何品牌,只讲通用特性:1. 云数据库 RDS:简单说,就是“传统数据库的云端托管版”。它本质还是传统关系型数据库的内核,只是把数据库部署在云服务器上,由云服务商负责服务器运维、数据库安装、备份、故障修复等基础工作,你只需要专注于业务数据的读写和管理。它就像“云端的专属数据库服务器”,服务商帮你搞定了硬件维护、系统升级,你不用操心底层环境,直接用就行,和本地部署的传统数据库用法几乎一致。2. 云原生数据库:是“为云计算量身定制的新一代数据库”。它的底层架构完全摆脱了传统数据库的束缚,贴合云计算的分布式、弹性伸缩、自动化运维特性,甚至可以和容器、微服务等云原生技术无缝融合。它更像“一个灵活的数据库集群服务”,不是单一的服务器,而是由多个节点组成的分布式系统,能根据业务需求自动扩容、缩容,故障时自动切换,无需人工干预。二、8大核心维度对比:RDS vs 云原生数据库(通俗易懂,无专业壁垒)这部分是重点,我们从“普通人能看懂”的角度,对比两者的核心差异,不堆砌专业术语,每个维度都配通俗解读:维度1:架构设计(最核心的差异)• 云数据库 RDS:单机/主从架构(集中式)。核心是“一个主节点+多个备节点”,所有数据都存储在主节点,备节点只做备份和故障切换。就像“一个主力+几个备用队员”,主力负责所有核心工作,备用队员只在主力出问题时顶上。这种架构的优势是简单、稳定,和传统数据库用法一致;缺点是扩展性有限,一旦主节点达到性能上限,扩容起来比较麻烦,且受单机硬件限制。• 云原生数据库:分布式架构(存算分离)。核心是“计算和存储分开”,计算节点负责数据的读写处理,存储节点负责数据的持久化存储,两者可以独立扩容、缩容。就像“一个团队,有人专门做计算,有人专门做存储,各司其职,还能随时加人”。这种架构的优势是突破了单机限制,能支撑海量数据和高并发;缺点是架构更复杂,对技术理解有一定要求。维度2:弹性伸缩能力(应对流量波动的关键)• 云数据库 RDS:半弹性,扩容繁琐。扩容时需要手动调整实例规格(比如增加CPU、内存、存储),部分场景下甚至需要停机,扩容周期较长(通常几分钟到几小时)。而且计算和存储必须一起扩容,哪怕只是存储不够用,也得同时升级计算资源,容易造成资源浪费。适合流量稳定的场景,比如企业内部管理系统,每天的访问量波动不大,提前规划好规格就能满足需求。• 云原生数据库:全弹性,秒级扩容。计算和存储可以独立扩容,比如存储不够了,直接增加存储节点,不影响计算;流量峰值来了,快速增加计算节点,峰值过后自动缩容,避免资源闲置。扩容过程无需停机,对业务完全透明,甚至能实现“按需伸缩”,流量多少就分配多少资源。适合流量波动大的场景,比如电商大促、短视频平台,平时流量平稳,峰值时流量能暴涨10倍以上,需要快速响应。维度3:运维复杂度(谁更省心?)• 云数据库 RDS:低运维成本,上手简单。服务商已经帮你搞定了大部分运维工作,比如服务器部署、数据库安装、备份、故障修复、版本升级等,你只需要负责数据的日常管理(比如建表、删数据、优化SQL)。哪怕是不懂底层架构的研发同学,也能快速上手,无需专业的DBA(数据库管理员)就能维护,适合中小型团队或运维资源不足的场景。• 云原生数据库:高运维门槛,需专业能力。虽然服务商也会提供基础的运维支持,但由于其分布式架构的复杂性,需要你掌握分布式系统、容器、微服务等相关知识,才能更好地进行配置优化、故障排查、性能调优。通常需要专业的DBA或云原生技术人员维护,适合大型团队或有专业运维能力的企业。维度4:性能表现(应对高并发、海量数据的能力)• 云数据库 RDS:适合中低并发、中小数据量。由于是集中式架构,受单机性能限制,当并发量达到一定阈值(比如每秒几万次请求)、数据量达到TB级以上时,性能会明显下降,容易出现卡顿、延迟。但对于常规业务(比如中小企业官网、内部OA系统),并发量每秒几千次、数据量GB级,RDS的性能完全足够,且稳定性更强。• 云原生数据库:适合高并发、海量数据。分布式架构可以通过增加节点来提升性能,并发量能轻松支撑每秒几十万次请求,数据量能达到PB级甚至EB级,且性能不会随着数据量增长而明显下降。比如短视频平台的用户行为数据、电商平台的订单数据,每天产生海量数据,高并发访问频繁,云原生数据库能轻松应对。维度5:高可用性(避免业务中断的能力)• 云数据库 RDS:高可用依赖主从切换。通常采用“一主一备”或“一主多备”架构,当主节点出现故障时,备节点会自动切换为主节点,恢复业务。但切换需要一定时间(通常几秒到几十秒),期间可能会出现短暂的业务中断,且如果主备节点在同一可用区,遇到机房故障,可能会导致数据丢失。不过对于大多数业务来说,这种高可用能力已经足够,能满足99.99%的可用性要求。• 云原生数据库:高可用更可靠,自愈能力强。采用多节点分布式部署,数据会存储在多个节点、多个可用区,哪怕某个节点、某个可用区出现故障,其他节点也能快速接管业务,切换时间可达到秒级甚至毫秒级,几乎不会影响业务。而且具备自动自愈能力,节点故障后会自动重建,无需人工干预,能满足金融、医疗等对业务连续性要求极高的场景(可用性99.999%以上)。维度6:成本投入(谁更省钱?)• 云数据库 RDS:前期成本低,长期固定成本高。采用“包年包月”或“按量付费”模式,入门级规格价格较低,适合初创团队或预算有限的企业。但由于扩容需要整体升级规格,长期来看,如果业务增长,成本会线性上升,且容易出现资源闲置(比如峰值过后,扩容的资源用不上)。• 云原生数据库:前期成本高,长期弹性成本更优。由于架构更复杂,入门级规格价格通常比RDS高,前期投入较大。但由于支持弹性伸缩,峰值时扩容,低谷时缩容,能最大限度利用资源,避免浪费,长期来看,尤其是业务波动大、数据量增长快的场景,成本会更有优势。维度7:兼容性(迁移成本高不高?)• 云数据库 RDS:兼容性极强,迁移成本低。大多支持主流的关系型数据库协议(比如MySQL、PostgreSQL),和本地部署的传统数据库用法完全一致,从本地数据库迁移到RDS,几乎不需要修改业务代码,迁移过程简单,风险低。• 云原生数据库:兼容性不一,迁移成本较高。部分云原生数据库为了追求性能,会对传统数据库协议进行修改,或者采用自定义协议,从RDS或本地数据库迁移到云原生数据库,可能需要修改业务代码、调整SQL语句,迁移过程复杂,风险较高。不过也有部分云原生数据库兼容主流协议,迁移成本相对较低,选型时可以重点关注。维度8:适用场景(精准匹配业务需求)为了更直观,我们直接分场景总结,避免大家踩坑:• 云数据库 RDS 适用场景:业务稳定,流量波动小(比如企业OA、CRM系统、官网后台);数据量不大(GB级到TB级),并发量中低(每秒几千次请求以内);团队运维资源不足,没有专业DBA,追求简单易上手;从本地传统数据库迁移,希望降低迁移成本和风险;预算有限,前期不想投入过多成本。• 云原生数据库适用场景:业务高速增长,流量波动大(比如电商、短视频、直播平台);数据量巨大(TB级以上,甚至PB级),需要支撑高并发(每秒几万次以上请求);对业务连续性要求极高(比如金融交易、医疗数据),需要99.999%以上的可用性;团队有专业的运维能力(有DBA或云原生技术人员);长期来看,希望通过弹性伸缩降低资源浪费,控制成本。三、选型逻辑:3步搞定,不踩坑看完上面的对比,可能还有同学觉得“还是不知道怎么选”,这里给大家一个简单的3步选型法,直接套用即可:第一步:明确业务核心需求先问自己3个问题:① 业务流量是否稳定?峰值和低谷的差距有多大?② 数据量有多大,未来1-3年的增长预期是什么?③ 对业务连续性的要求有多高?(比如是否能接受短暂中断)如果流量稳定、数据量不大、对连续性要求一般,优先考虑RDS;如果流量波动大、数据量增长快、对连续性要求极高,优先考虑云原生数据库。第二步:评估团队能力和预算如果团队没有专业的DBA,运维资源不足,预算有限,哪怕业务有一定增长,也建议先选RDS,避免因运维能力不足导致业务故障;如果团队有专业运维能力,且预算充足,想为未来业务增长预留空间,可以直接选云原生数据库。第三步:考虑迁移成本和未来扩展性如果目前正在使用本地传统数据库或RDS,且业务代码依赖传统数据库协议,不建议盲目迁移到云原生数据库,除非业务增长已经超出RDS的承载能力;如果是新业务,没有历史数据和代码包袱,可以直接根据业务需求选择云原生数据库,为未来扩展性铺路。四、最后总结:没有最好,只有最适合很多同学会陷入“云原生一定比RDS好”的误区,其实两者没有优劣之分,核心是匹配业务需求。RDS的核心价值是“稳定、简单、低成本”,适合大多数中小型企业、稳定型业务,是“够用就好”的选择;云原生数据库的核心价值是“弹性、高效、高可用”,适合大型企业、高速增长型业务,是“未来可期”的选择。选型的本质,就是在“业务需求、团队能力、预算成本”三者之间找到平衡——能满足业务需求、团队能驾驭、成本可控,就是最优解。
-
▍1. 前言随着大语言模型(LLM)日益成为现代应用的核心,支持它们的基础设施必须不断演进,以满足苛刻的性能、可扩展性和成本要求。在生产环境中部署 LLM 面临着独特的挑战:模型需要大量资源,推理工作负载变化显著,用户期望低延迟和高吞吐量。传统的负载均衡器和 API 网关虽然在传统 Web 服务中表现出色,但缺乏智能路由 AI 推理流量所需的感知能力。Kthena[1] Router 正面应对这些挑战。它是一个 Kubernetes 原生的独立推理Router,专为 LLM 服务工作负载而设计。与通用代理或负载均衡器不同,Kthena Router 具有模型感知能力,根据推理引擎的实时指标做出智能路由决策。这使得其能够实现复杂的流量管理策略,显著提高吞吐量、降低延迟并降低运营成本。Kthena Router 能够与现有 API 网关基础设施无缝集成,同时提供专为 AI 工作负载设计的高级功能:模型感知路由:利用推理引擎(vLLM、SGLang、TGI)的实时指标做出智能路由决策LoRA 感知负载均衡:智能路由到已加载所需 LoRA Adapter 的 Pod,将数百毫秒的 Adapter Swap 延迟降低到接近零高级调度算法:包括Prefix Cache感知、KV Cache感知和公平性调度等PD分离:原生支持 xPyD(x-prefill/y-decode)部署模式Kthena Router 作为独立二进制文件部署,极简依赖,确保轻量级运行和简单部署。它持续监控推理引擎指标,以获取有关模型状态的实时信息,包括当前加载的 LoRA Adapter、KV Cache 利用率、请求队列长度和延迟指标(TTFT/TPOT)。这种实时感知能力使 Router 能够做出传统负载均衡器根本无法实现的最优路由决策。▍2. 架构Kthena Router 实现了一个清晰的模块化架构,专为性能和可扩展性而设计。该系统由几个核心组件协同工作,提供智能请求路由。Kthena Router 架构2.1 核心组件概述Router: 负责接收、处理和转发请求的核心执行框架。它协调所有其他组件之间的交互,并维护从初始接收到最终响应的请求生命周期。Listener: 管理 HTTP/HTTPS 监听器并处理指定端口上的传入流量。它为不同协议提供灵活的配置,并可以绑定到多个地址以服务各种类型的请求。监听器确保高效的连接处理,并支持流式和非流式请求模式。Controller: 一个 Kubernetes 原生组件,用于同步和处理 Pod 和自定义资源(CR),例如 ModelRoute 和 ModelServer。Controller监视集群中的变化,并相应地更新Router的内部状态,确保路由决策始终基于当前的集群拓扑。Filters: 包含两个关键子模块,在请求到达后端之前处理请求:Auth:处理流量认证和授权,支持 API Key、JWTRateLimit:管理全面的速率限制策略,包括输入token和输出token限制Backend: 提供访问各种推理引擎的抽象层。它掩盖了不同框架(如 vLLM、SGLang 和 TGI)之间Metrics接口访问方法和Metrics命名约定的差异,向调度器提供统一的接口。Metrics Fetcher: 持续从模型 Pod 上运行的推理引擎端点收集实时Metrics。它收集关键性能数据,包括:KV Cache利用率当前加载的 LoRA Adapter请求队列长度延迟指标(TTFT,TPOT)Datastore: 一个统一的数据存储层,提供对 ModelServer 到 Pod 关联、Base Model/LoRA 配置和运行时Metrics的高效访问。它作为所有路由相关信息的中央存储库,并支持实时更新的回调。Scheduler: Router的大脑,实现复杂的流量调度算法。它由一个调度框架和各种可插拔的调度算法插件组成。该框架集成并运行不同的调度插件,以过滤和评分与 ModelServer 对应的 Pod 集合,选择全局最优的 Pod 作为最终访问目标。Kthena Router 组件▍3. Router APIKthena Router 的路由行为由两个关键的自定义资源定义(CRD)控制:ModelServer 和 ModelRoute。这些声明式 API 允许您使用熟悉的 Kubernetes 模式定义复杂的路由策略。3.1 ModelRouteModelRoute 根据请求特征定义流量路由规则。它根据模型名称、LoRA Adapter、HTTP Header和其他条件确定哪些 ModelServer 应该处理请求。关键字段包括:ModelName:要在传入请求中匹配的模型名称LoRAAdapters:此路由支持的 LoRA 适配器名称列表Rules:有序的路由规则列表,每个规则包含:ModelMatch:匹配请求的条件(Header、URI 等)TargetModels:要路由到的 ModelServer 列表,可选权重RateLimit:基于token的速率限制配置有关 ModelRoute 的更多详细信息,请参阅 定义[2]。3.2 ModelServerModelServer 定义推理服务实例及其访问策略。它标识运行模型的 Pod,指定正在使用的推理框架,并定义如何处理流量。关键字段包括:WorkloadSelector:通过标签标识 Pod,并支持 PD(prefill-decode)组规范Model:指定服务器托管的Base Model名称InferenceFramework:指示推理引擎(vLLM、SGLang、TGI 等)WorkloadPort:定义推理服务监听的端口TrafficPolicy:配置超时、重试策略和其他流量处理行为KVConnector:为 PD 分离部署指定 KV Connector类型(HTTP、Nixl、LMCache、Mooncake)有关 ModelServer 的更多详细信息,请参阅 定义[3]。3.3 示例:基于HTTP Header的多模型路由对于分层服务产品,根据头将用户路由到不同大小的模型:apiVersion: networking.serving.volcano.sh/v1alpha1kind: ModelRoutemetadata: name: deepseek-multi-models namespace: defaultspec: modelName: "deepseek-multi-models" rules: - name: "premium" modelMatch: headers: user-type: exact: premium targetModels: - modelServerName: "deepseek-r1-7b" - name: "default" targetModels: - modelServerName: "deepseek-r1-1-5b"---apiVersion: networking.serving.volcano.sh/v1alpha1kind: ModelServermetadata: name: deepseek-r1-7b namespace: defaultspec: workloadSelector: matchLabels: app: deepseek-r1-7b workloadPort: port: 8000 model: "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B" inferenceEngine: "vLLM" trafficPolicy: timeout: 10s---apiVersion: networking.serving.volcano.sh/v1alpha1kind: ModelServermetadata: name: deepseek-r1-1-5b namespace: defaultspec: workloadSelector: matchLabels: app: deepseek-r1-1-5b workloadPort: port: 8000 model: "deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B" inferenceEngine: "vLLM" trafficPolicy: timeout: 10s流量处理过程:请求到达,模型名称为 "deepseek-multi-models"Router检查HTTP Header中是否存在 user-type: premium高级用户 → 路由到更大的 7B 模型以获得更好的质量普通用户 → 路由到更小的 1.5B 模型以提高成本效率测试高级路由:curl http://$ROUTER_IP/v1/completions \ -H "Content-Type: application/json" \ -H "user-type: premium" \ -d '{"model": "deepseek-multi-models", "prompt": "Explain quantum computing"}'这个示例演示了 ModelRoute 和 ModelServer CRD 如何通过标准 Kubernetes API 提供对复杂路由策略的灵活声明式控制。▍4. 核心功能4.1 智能调度插件真正将 Kthena Router 与传统负载均衡器区分开的是其一套模型感知调度插件。这些插件利用实时推理引擎指标做出智能路由决策,显著提高性能。4.1.1 LoRA 亲和性调度LoRA(低秩适应)Adapter 能够在不重新部署 Base Model 的情况下实现微调的模型行为。然而,加载和卸载 Adapter 会引入延迟。LoRA 亲和性插件通过智能路由最小化这种开销。工作原理:持续跟踪每个 Pod 上当前加载的 LoRA Adapter 状态将需要特定 LoRA 的请求优先路由到已加载该 Adapter 的 Pod通过缓存命中避免 Adapter 加载/卸载操作优势:消除 Adapter Swap 延迟: 将数百毫秒的 Adapter 切换延迟降至接近零提高响应速度: 避免动态加载 Adapter 带来的额外等待时间支持多 LoRA 场景: 高效处理多个 LoRA Adapter 的混合工作负载4.1.2 Least Latency 调度Least Latency 插件根据实时延迟指标将请求路由到响应最快的 Pod,优化用户体验和整体生成速度。工作原理:持续监控推理引擎的延迟指标综合评估 TTFT(首 token 时间)和 TPOT(每输出 token 时间)将请求路由到延迟最低的 Pod动态适应 Pod 性能变化关键指标:TTFT(首 token 时间): 影响流式响应和用户感知延迟TPOT(每输出 token 时间): 决定整体生成速度和吞吐量4.1.3 Least Request 调度Least Request 插件基于请求队列状态进行负载均衡,将请求路由到最不繁忙的 Pod,确保均匀的负载分布。工作原理:监控推理引擎的 num_requests_running 和 num_requests_waiting 指标计算每个 Pod 的总待处理工作负载(运行中 + 等待中)将新请求路由到负载最低的 Pod动态平衡各 Pod 之间的工作分配优势:防止热点: 避免部分 Pod 过载而其他 Pod 空闲均衡负载: 确保所有 Pod 的利用率趋于一致提高吞吐量: 通过最优负载分配最大化整体处理能力4.1.4 GPU Usage 调度GPU Usage 插件基于 GPU 缓存使用率进行负载均衡,将请求路由到缓存压力较小的 Pod,优化 GPU 资源利用率。工作原理:持续监控每个 Pod 的 GPU 缓存使用率指标计算可用缓存容量:score = (1.0 - GPU缓存使用率) × 100 优先将请求路由到 GPU 缓存使用率较低的 Pod避免因缓存耗尽导致的性能下降和请求失败优势:防止缓存溢出: 避免将请求发送到缓存已满的 Pod提高稳定性: 减少因缓存不足导致的请求失败和重试负载均衡: 确保 GPU 缓存资源在所有 Pod 间均衡使用提升吞吐量: 保持各 Pod 在最优缓存利用率区间运行4.1.5 Prefix Cache 感知调度现代推理引擎(如 vLLM 和 SGLang)实现 Prefix Cache 机制,将常用的 Prompt 前缀缓存起来以避免冗余计算。Prefix Cache 感知插件通过智能路由策略最大化前缀缓存的命中率,显著提升推理性能。核心机制:滚动哈希生成:将 Prompt 按固定大小(默认 64 字节)划分为块使用 xxHash 算法为每个块生成滚动哈希每个哈希值结合前一个块的哈希,形成依赖链哈希匹配时保证所有前置块也匹配,实现高效前缀识别内存缓存存储:使用三层映射结构:模型 → 哈希 → Pod采用 LRU(最近最少使用)缓存策略管理内存自动清理过期条目,保持缓存效率默认缓存容量 50,000 条,返回 Top-5 最佳匹配智能评分算法:根据前缀匹配长度对 Pod 评分评分公式:score = (匹配块数 / 总块数) × 100 优先选择具有最长匹配前缀的 Pod提高缓存命中率和推理效率适用场景:多轮对话系统,用户在同一 session 中发送多个相关请求具有固定 system prompt 的应用场景问答系统中频繁使用相同上下文的查询4.1.6 KV Cache Aware 调度KV Cache Aware 插件是一个高级调度插件,通过基于token级别的块匹配来智能路由请求,最大化 KV 缓存命中率。与简单监控缓存利用率不同,该插件实现了细粒度的内容感知调度,显著提升性能。核心机制:Token 块哈希:将传入的prompt分词后按固定大小(默认128个token)划分为块使用 SHA-256 为每个块生成标准化哈希值支持可配置的最大块数(默认128块)以平衡性能和准确性分布式缓存跟踪:使用 Redis 维护全局的块到 Pod 映射Redis key 格式: matrix:kv:block:{model}@{hash} 每个 key 存储包含该块的 Pod 列表及其缓存时间戳通过 Redis Pipeline 批量查询实现高效的分布式协调智能评分算法:查找每个token块在哪些 Pod 上已缓存从第一个块开始计算连续匹配长度优先选择具有最长连续匹配前缀的 Pod评分公式: score = (匹配块数 / 总块数) × 100Tokenizer 集成:支持多种tokenizer backend(本地和远程 vLLM)自动处理不同模型的分词差异确保一致的token到块的映射优势:精确匹配: 不仅考虑缓存容量,还考虑实际缓存的内容避免冷启动: 将请求路由到已经处理过相似prompt的 Pod提升吞吐量: 减少重复计算,在long system prompt场景下可实现 2.73 倍吞吐量提升降低延迟: TTFT 可降低 73.5%,显著改善用户体验更多技术细节请参考 KV Cache Aware 插件设计文档[4]。4.1.7 插件配置这些插件通过调度器框架协同工作。您可以通过Router配置来配置启用哪些插件及其相对权重。调度器框架按顺序运行启用的插件:Filter:插件过滤不合适的 Pod(例如,缓存不足、错误的 LoRA)Score:插件根据其条件对剩余 Pod 评分Select:为请求选择得分最高的 Pod这种可组合的架构允许您根据特定的工作负载需求定制路由行为。4.2 公平性调度公平性调度确保基于token消耗历史在用户之间公平分配资源。工作原理:跟踪每个用户每个模型的累积token使用量(输入 + 输出)分配与历史使用量成反比的请求优先级将请求排队并按优先级顺序处理防止任何单个用户垄断资源用例:具有共享基础设施的多租户平台具有公平共享策略的研究集群需要基于使用量的节流的 SLA 驱动系统4.3 PD分离支持对于高级部署模式,Kthena Router 原生支持PD分离(xPyD),其中计算密集型的Prefill阶段与token生成Decode阶段分离。工作原理:从 ModelServer CRD 识别 PD 组配置将Prefill请求路由到Prefill优化的 Pod通过可配置的连接器(HTTP、Nixl 等)传输 KV 缓存状态将Decode请求路由到Decode优化的 Pod对客户端透明地协调两阶段过程优势:通过将工作负载特征与硬件匹配来优化硬件利用率通过为每个阶段使用专用硬件来减少延迟通过更好的资源分配提高成本效率4.4 基于token的RateLimitKthena Router 提供全面的RateLimit功能,以保护您的推理基础设施免受过载,并确保跨用户的公平资源分配。Input token限制:控制每个用户或 API 密钥的传入prompt token速率Output token限制:限制生成的token以管理计算成本Local RateLimit:在每个Router实例基础上实施限制。Global RateLimit:使用 Redis 等中央存储在所有Router实例之间实施共享限制。4.5 可观测性Kthena Router 提供为生产 LLM 服务设计的全面可观测性功能:指标:在 /metrics endpoint公开详细指标,包括请求延迟、token消耗、调度器插件性能和RateLimit统计信息结构化访问日志:以 JSON 或文本格式记录完整的请求生命周期,包括路由决策、用时分布和token跟踪Debug endpoint:提供 /debug/config_dump/* API 来检查内部状态、ModelRoute/ModelServer 配置和实时 Pod 等指标标准集成:与 Prometheus、Grafana、ELK 等可观测性堆栈无缝协作,用于监控、告警和故障排除▍5. 性能Kthena Router 中的 ScorePlugin 模块利用可配置的可插拔架构来实现推理请求的多维评分和智能路由。为了演示智能调度的影响,我们基于 DeepSeek-R1-Distill-Qwen-7B 模型构建了一个标准化的基准测试环境,以评估不同调度策略在长短system prompt场景下的性能。实验结果表明,在long system prompt场景中,KV Cache Aware Plugin + Least Request Plugin 组合实现了 2.73 倍的吞吐量,并将 TTFT 延迟降低了 73.5%,显著优化了整体推理服务性能,验证了Cache感知调度对大规模模型推理的核心价值。5.1 实验设置使用 DeepSeek-R1-Distill-Qwen-7B 模型构建了标准化的基准测试环境,以评估不同调度策略的性能。表 1:实验环境配置5.2 Long System Prompt Scenario(4096 token)表 2:性能指标 - Long System Prompt ▍6. 结论Kthena Router 代表了 LLM 服务基础设施的重大飞跃。通过超越简单的负载均衡,实现模型感知、指标驱动的路由,它释放了以前无法实现的显著性能改进和成本节省。它是开源的,现在就可以使用。Kthena文档[5]提供了安装、配置和部署的全面指南。Kthena-router 示例目录[6]包含用于常见场景的即用型配置。无论您是运行单个模型还是管理复杂的多租户 LLM 平台,Kthena Router 都提供了最大化性能、最小化成本和提供卓越用户体验所需的智能路由功能。作者 | YaoZengzeng 相关链接[1] Kthena: https://kthena.volcano.sh/[2] ModelRoute 定义: cid:link_1[3] ModelServer定义: cid:link_2[4] KV Cache Aware 插件设计文档: cid:link_3[5] Kthena文档: https://volcano-sh.github.io/kthena/[6] Kthena-router 示例目录: cid:link_4 扫码进群,社区小助手k8s2222
-
Volcano[1] 社区 v1.14 现已正式发布。随着 AI 业务形态从单一的离线训练向在线推理、Agent 智能体等多元化场景延伸,调度系统面临着前所未有的挑战。v1.14[2] 通过架构级的创新,在保持大规模批量计算优势的同时,补齐了对延迟敏感型业务的调度短板,向着 “AI训推、RL、Agent全场景统一调度平台” 的目标迈出了坚实一步。 版本亮点 📌 v1.14.0 版本带来以下重磅更新:统一调度平台架构多调度器架构升级:动态节点分片机制 (Alpha)AI Agent 工作负载极速调度能力 (Alpha)网络拓扑感知调度增强HyperNode 级 Binpack 策略SubGroup 级精细化拓扑感知PodGroup 与 SubGroup 多层级 Gang SchedulingVolcano Job 分区支持混部能力增强全面支持通用操作系统(Ubuntu、CentOS 等)Cgroup V2 全面适配CPU 动态压制基于 Cgroup V2 的内存 QoS支持 CPU Burst支持 systemd driver 自动检测异构硬件支持昇腾 vNPU 调度(支持 MindCluster 和 HAMi 模式)Volcano Global 增强HyperJob 多集群作业自动拆分数据感知多集群调度Volcano Dashboard 增强PodGroup 全景可视化Job / Queue 全生命周期管理▍多调度器架构升级:动态节点分片机制 (Alpha)随着 Volcano 承载的工作负载类型日益丰富、规模持续扩大,单一调度器架构逐渐显露瓶颈。批量训练、AI Agent、微服务等不同类型的工作负载,对调度时延、资源利用模式的诉求各不相同。单调度器难以兼顾,而静态资源划分又会造成利用率低下。新引入的 Sharding Controller 构建了一套可扩展的多调度器架构,能够根据集群实时状态,为每个调度器动态计算候选节点池。与传统的静态分区不同,Sharding Controller 采用动态计算的方式划分资源,而非强制硬隔离。这种灵活机制让 Volcano 真正成为"一个平台调度所有负载"的统一调度平台,同时保持高吞吐、低时延。核心能力:动态分片策略:支持多种策略来计算动态候选节点池。当前版本率先支持基于 CPU 利用率的分片策略,并采用了可扩展的架构设计,以便未来轻松集成更多分片算法。节点池化管理:引入 NodeShard CRD,为特定调度器管理专属的动态候选节点池。支持大规模集群:通过在多个调度器之间灵活分配负载,天然适配大规模集群场景。多调度器协同:支持多种调度器组合的无缝协作。无论是部署多个 Batch Scheduler 进行负载分担,还是混合部署 Agent Scheduler 与 Batch Scheduler 以应对不同业务需求,都能灵活适配。配置示例:# Sharding Controller 启动参数--scheduler-configs="volcano:volcano:0.0:0.6:false:2:100,agent-scheduler:agent:0.7:1.0:true:2:100"--shard-sync-period=60s--enable-node-event-trigger=true# 参数格式: name:type:min_util:max_util:prefer_warmup:min_nodes:max_nodes🔗 相关 PR:cid:link_9设计文档:Sharding Controller Design[3]感谢社区开发者:@ssfffss, @Haoran, @qi-min▍AI Agent 工作负载极速调度 (Alpha)AI Agent 类业务对时延极度敏感,任务创建频繁且生命周期短,对调度器的响应速度和吞吐量提出了严苛要求。原生 Volcano Batch Scheduler 专为批量计算设计,按固定周期处理 Pod,难以满足 Agent 场景的毫秒级响应需求。为打造兼容批量计算与延迟敏感型业务的统一调度平台,v1.14 引入了专用的 Agent Scheduler。它通过 Sharding Controller 与批量调度器协同工作,各司其职又无缝配合,真正实现"一个平台、多种负载"。核心能力:极速调度通道:专为延迟敏感型负载(如 AI Agent)打造的独立调度器,提供极致响应速度。多 Worker 并行处理:采用多 Worker 并发消费调度队列的架构,大幅提升调度吞吐量。乐观并发控制:引入 Conflict-Aware Binder 机制,在实际绑定前预先解决冲突,减少无效操作。增强型调度队列:优化队列机制,支持紧急任务重试,确保关键任务不阻塞。统一平台融合:通过 Sharding Controller 与批量调度器无缝协作,共享集群资源。 🔗 相关 PR: https://github.com/volcano-sh/volcano/pull/4804, cid:link_11, cid:link_12设计文档:Agent Scheduler Design[4]感谢社区开发者:@qi-min, @JesseStutler, @handan-yxh▍网络拓扑感知调度增强Volcano v1.14.0 对网络拓扑感知调度进行了进一步增强,满足分布式工作负载(包括 LLM 训练、推理、HPC 和其他网络密集型应用)日益增长的需求。核心增强:SubGroup 级精细化拓扑感知:支持在 SubGroup / Partition 粒度设置网络拓扑约束,调度颗粒度更精细。灵活的网络层级约束:新增 highestTierName,支持按名称指定允许跨越的最高网络层级。多层级 Gang Scheduling:同时支持 PodGroup 级别和 SubGroup 级别的 Gang Scheduling,确保分布式任务的整体性。Volcano Job 分区:支持将 Job 拆分为多个分区(Partition),便于管理 TP/PP/DP 等并行策略,并优化网络亲和性。HyperNode 级 Binpacking:在 HyperNode(如交换机、机架)层级进行资源装箱,减少网络碎片,提升通信效率。配置示例 - Volcano Job:apiVersion:batch.volcano.sh/v1alpha1 kind:Job metadata: name:llm-training-job spec: networkTopology: mode:hard highestTierAllowed:2 # 整个 Job 最多跨越 Tier 2 HyperNode tasks: - name:trainer replicas:8 partitionPolicy: totalPartitions:2 # 拆分为 2 个分区 partitionSize:4 # 每个分区 4 个 Pod minPartitions:2 # 至少需要 2 个分区 networkTopology: mode:hard highestTierAllowed:1 # 单个分区必须在 Tier 1 内 template: spec: containers: - name:trainer image:training-image:v1 resources: requests: nvidia.com/gpu:8 🔗 相关 PR: cid:link_13, cid:link_14, cid:link_15, cid:link_16, cid:link_17设计文档:Network Topology Aware Scheduling[5]感谢社区开发者:@ouyangshengjia, @3sunny, @zhaoqi, @wangyang0616, @MondayCha, @Tau721▍混部能力全面升级:支持通用操作系统本次发布对 Volcano 的混部能力进行了全面改进,其中一个重要里程碑是:Volcano 混部能力正式支持通用操作系统(Ubuntu、CentOS 等),不再局限于 OpenEuler。这意味着更多用户可以使用 Volcano Agent 实现在离线混部,提升集群整体资源利用率。CPU 动态压制 (CPU Suppression)在线业务流量通常具有潮汐特性。为了在保障在线业务 SLA 的同时最大化资源利用,离线 Pod 的 CPU 配额需要随在线用量动态调整:在线用量高时压制离线配额,用量回落时逐步恢复,实现自适应的资源分配。核心设计:根据节点可分配 CPU 和实时用量,动态调整 BestEffort root cgroup 的 CPU 配额。采用"监控-事件-处理"架构,并实施保守更新策略,有效抑制抖动。配置示例:cpuThrottlingConfig: enable:true cpuThrottlingThreshold:80 # BE 配额上限为可分配 CPU 的 80% cpuJitterLimitPercent:1 # 配额变化超过 1% 才触发更新 cpuRecoverLimitPercent:10 # 单次恢复上限 10%内存 QoS (Cgroup V2)基于 Cgroup V2 实现混部场景的内存隔离。新增 ColocationConfiguration CRD,支持为指定工作负载配置内存 QoS 策略。核心能力:New API:通过标签选择器定义内存隔离策略的 ColocationConfiguration CRD动态计算:memory.high = pod.limits.memory * highRatio %memory.low = pod.requests.memory * lowRatio %memory.min = pod.requests.memory * minRatio %统一接口:可靠检测和支持 Cgroup V2 环境使用示例:apiVersion:config.volcano.sh/v1alpha1 kind:ColocationConfiguration metadata: name:colo-config1 spec: selector: matchLabels: app:offline-test memoryQos: highRatio:100 # memory.high = memory.limits * 100% lowRatio:50 # memory.low = memory.requests * 50% minRatio:0 # memory.min = memory.requests * 0%CPU Burst 与 Cgroup V2 全面支持CPU Burst 能力已扩展至通用操作系统。同时,Volcano Agent 现已全面适配 Cgroup V2 环境,支持自动检测 Cgroup 版本及驱动类型(如 systemd driver),无需人工干预即可在现代 Linux 发行版上无缝运行。 🔗 相关 PR: cid:link_18, cid:link_19, cid:link_20, cid:link_21设计文档:CPU Throttle Design[6], Agent Cgroup V2 Adaptation[7]感谢社区开发者:@Haibara-Ai97, @JesseStutler, @ouyangshengjia▍昇腾 vNPU 调度v1.14 原生集成了昇腾 vNPU(虚拟 NPU)调度能力,实现昇腾 AI 处理器在多个工作负载之间的高效算力复用。提供两种模式,灵活适配不同部署场景。支持模式:1. MindCluster 模式集成自 Ascend MindCluster 调度插件:https://gitcode.com/Ascend/mind-cluster支持昇腾 310P 系列的动态虚拟化2. HAMi 模式由 HAMi 社区开发同时支持昇腾 310 和 910 系列支持异构昇腾集群(910A、910B2、910B3、310P)调度器配置:# MindCluster 模式 - name:deviceshare arguments: deviceshare.AscendMindClusterVNPUEnable:true # HAMi 模式 - name:deviceshare arguments: deviceshare.AscendHAMiVNPUEnable:true deviceshare.SchedulePolicy:binpack # 或 spread 🔗 相关 PR: cid:link_22, cid:link_23使用文档:How to Use vNPU[8] 感谢社区开发者:@JackyTYang, @DSFans2014▍Volcano Global 增强Volcano Global v0.3.0 引入了两个重要功能,通过基于计算资源和数据局部性的智能调度,显著扩展了 Volcano Global 对 AI/ML 和大数据工作负载的能力。HyperJob:多集群作业自动拆分随着 AI 训练工作负载规模和复杂性的增长,企业越来越面临跨多个异构集群管理大规模训练作业的挑战。HyperJob 是构建在 Volcano Job 之上的更高级抽象。它组合多个 Volcano Job 模板,将训练能力扩展到单集群边界之外,同时保留每个集群内现有 Volcano Job 的全部能力。核心能力:Karmada 深度集成:自动生成 PropagationPolicy,精准配置集群亲和性与副本调度。状态统一聚合:将各集群子任务状态汇总为统一的 HyperJob 状态,全局可观测。自动资源生成:根据 ReplicatedJob 定义自动创建 VCJob 和 PropagationPolicy。HyperJob 资源示例(跨 2 个集群拆分大规模训练作业,共 256 个 GPU):apiVersion:training.volcano.sh/v1alpha1 kind:HyperJob metadata: name:llm-training spec: replicatedJobs: - name:trainer replicas:2 templateSpec: tasks: - name:worker replicas:128 template: spec: containers: - name:trainer image:training-image:v1 resources: requests: nvidia.com/gpu:1数据感知调度在 AI 训练和大数据分析等高性能计算场景中,任务执行不仅依赖计算资源,还严重依赖数据资源。在多集群环境中,调度器可能会将任务分派到与数据源物理距离较远的集群,导致跨地域带宽成本过高和 I/O 延迟过高。数据感知调度框架引入 DataDependencyController,打通了逻辑数据需求与物理集群分布的壁垒。通过外部插件(如 Amoro)实时获取数据分布信息,自动将调度约束注入 Karmada,实现"计算随数据而动"的全自动工作流。核心能力:插件化架构:可扩展支持 Amoro、Hive、S3 等多种数据系统。声明式 API:DataSourceClaim / DataSource CRD,采用"声明-缓存"模式。自动亲和注入:将数据局部性转化为 ClusterAffinity 约束,注入 ResourceBinding。详见: Volcano Global v0.3.0 Release Notes[9]感谢社区开发者:@JesseStutler, @fx147, @Monokaix, @zhoujinyu, @anryko, @tanberBro▍Volcano Dashboard v0.2.0Volcano Dashboard v0.2.0 对资源管理能力进行了重大增强,使得通过 Web 界面管理 Volcano 资源更加便捷。核心增强:PodGroup 全景可视化:跨命名空间查看、搜索、过滤 PodGroup,支持 YAML 语法高亮。Job 生命周期管理:直接在界面创建、删除 Volcano Job,操作更便捷。Queue 管理增强:在线编辑 Queue 配额、权重,支持 YAML 直接修改。安全加固:默认配置 SELinux、Seccomp、非 root 运行及禁止提权,保障生产安全。详见: Volcano Dashboard v0.2.0 Release Notes[10]感谢社区开发者:@vzhou-p, @Shrutim1505, @JesseStutler, @karanBRAVO, @Sayan4444, @jayesh9747, @Alivestars24, @kuldeep, @Monokaix▍调度器稳定性与性能提升Reclaim 重构与增强对 Reclaim Action 进行了全面重构,并修复了 Capacity Plugin 中的关键逻辑问题,大幅提升多租户集群资源回收的准确性、稳定性和性能。主要改进:Reclaim Action 重构:重构了 reclaim 工作流,提高代码可读性、可维护性和测试覆盖率。增强的 Capacity Plugin 逻辑:修复了 reclaimableFn 和 preemptiveFn,正确处理标量资源并防止错误的抢占决策。稳定性提升:解决了资源计算中的边缘情况,防止调度死循环和误驱逐。 🔗 相关 PR: cid:link_24, cid:link_25, cid:link_26感谢社区开发者:@guoqinwill, @hajnalmt▍支持 Kubernetes 1.34Volcano 版本紧跟 Kubernetes 社区。v1.14 已全面支持最新的 Kubernetes v1.34,并通过完整的单元测试和 E2E 测试保障功能与稳定性。🔗 相关 PR:cid:link_27感谢社区开发者:@suyiiyii, @tunedev 总结:Volcano v1.14.0 — AI 时代的统一调度平台 Volcano v1.14 是一个里程碑式的版本。通过引入多调度器架构和 Agent Scheduler,Volcano 正式迈入统一调度平台新阶段,既能高效处理批量 AI 训练,又能满足 AI Agent 的极致时延要求。网络拓扑感知增强、通用操作系统混部支持、昇腾 vNPU 集成,进一步夯实了 Volcano 在 AI 基础设施领域的领先地位。同时,Volcano Global v0.3.0 通过 HyperJob 实现大规模分布式训练和数据感知调度,扩展了多集群能力。Volcano Dashboard v0.2.0 通过全面的资源管理功能显著改善了用户体验。立即体验 Volcano v1.14,共启 AI 时代统一调度新篇章!v1.14.0 发布地址:cid:link_8Volcano Global v0.3.0 发布地址:cid:link_6Volcano Dashboard v0.2.0 发布地址:cid:link_7 致 谢 Volcano v1.14 生态版本(含 Volcano Global v0.3.0、Dashboard v0.2.0)共有 55 位社区贡献者参与。衷心感谢每一位贡献者:相关链接[1] Volcano: https://volcano.sh/en/[2] Volcano v1.14.0: cid:link_8[3] Sharding Controller Design: cid:link_2[4] Agent Scheduler Design: cid:link_5[5] Network Topology Aware Scheduling: cid:link_0[6] CPU Throttle Design: cid:link_3[7] Agent Cgroup V2 Adaptation: cid:link_1[8] How to Use vNPU: cid:link_4[9] Volcano Global v0.3.0 Release Notes: cid:link_6[10] Volcano Dashboard v0.2.0 Release Notes: cid:link_7 扫码回复“Volcano” 进入技术群
-
作者:Kthena MaintainersKthena 是一个专为 Kubernetes 设计的云原生、高性能 LLM 推理路由和编排、调度系统。作为 Volcano 的子项目,Kthena[1] 致力于帮助 Volcano[2] 扩展除 AI 训练之外的边界,打造训推一体的完整解决方案。Kthena v0.3.0[3] 现已正式发布,标志着 Kthena 已经成为一个更加健壮且具有可扩展性的 AI 推理平台。此版本在 ModelServing、Router 和 ModelBooster 方面引入了重大增强。核心亮点包括:与 LeaderWorkerSet 的无缝集成、针对 PD 分离(Prefill-Decode Disaggregation)的高级网络拓扑感知调度,以及完善的 Router 可观测性框架。此外,本版本还带来了原生的 ModelServing 版本控制、对 vLLM 数据并行部署的支持,以及完整的 Router E2E测试套件,确保了生产环境的高稳定性和可靠性。 关键新特性概览 LeaderWorkerSet 支持:集成 LeaderWorkerSet (LWS) API,实现对分布式推理工作负载的高级管理。角色级 Gang 调度与拓扑感知:利用 Volcano 的 subGroupPolicy 新特性,实现精细化的角色级 Gang 调度和网络拓扑感知。ModelServing 分区版本控制:引入了基于 Revision 的原生 ModelServing 版本控制系统。Router 可观测性与调试:提供完善的 Router 可观测性文档和框架,并新增专用调试端口。增强的滚动更新:支持 maxUnavailable 参数,可调节更新速度以实现更快地发布。插件支持:为 ModelServing 提供灵活的插件架构,用于注入自定义配置逻辑。▍ModelServing 角色支持 LeaderWorkerSet分布式推理工作负载通常需要复杂的拓扑结构,其中一个 Leader Pod 管理多个 Worker Pod。手动配置这些关系容易出错。通过集成 Kubernetes LeaderWorkerSet (LWS) API,Kthena 简化了这些工作负载的部署和管理。核心能力:直接集成:ModelServing 角色(Role)现在可以利用 LWS 自动管理 Leader-Worker 组。简化拓扑:降低了定义需要严格协调的分布式推理服务的复杂性。相关内容:🧩 PR:cid:link_4cid:link_5贡献者: @zhiweideren▍角色级 Gang 调度与拓扑感知在 Prefill-Decode (PD) 分离场景中,Prefill 实例和 Decode 实例之间的通信开销至关重要。确保这些实例在物理位置上更接近(例如在同一个交换机或机架下)可以显著提升性能。Kthena 现在通过 Volcano 的 subGroupPolicy 实现了对 Gang 调度和网络拓扑感知的精细化、角色级控制。核心能力:声明式拓扑策略:直接在 ModelServing 规范中为整个 ServingGroup(groupPolicy)以及单个角色(rolePolicy)配置不同的网络拓扑限制。自动 Pod 分组:Controller自动为 Pod 打上 modelserving.volcano.sh/role 和 modelserving.volcano.sh/role-id 标签,使 Volcano 能够形成子组(subGroup)以进行精确的拓扑感知放置。性能优化:通过将相关任务部署在网络邻近的节点上,最小化角色间通信延迟并最大化带宽利用率,适用于高强度分布式推理任务。角色级 Gang 调度:subGroupPolicy 还强制执行角色级 Gang 调度,确保属于特定角色(例如所有 prefill-0 Pod)的所有 Pod 作为一个原子单元共同调度。这保证了角色不会出现部分部署的情况,这对于分布式推理工作负载的正确性至关重要。💡 注意:此特性需要针对 subGroupPolicy 支持的 Volcano v1.14+ 版本。相关内容:提案: Network Topology[4]🧩 PR: cid:link_6贡献者: @LiZhenCheng9527▍ModelServing 分区版本控制Kthena ModelServing 中的 partition 字段定义了滚动更新的边界,允许你对更新过程进行分区,以便在更新一部分 ServingGroup 的同时,让其他部分保持在旧版本。这主要用于金丝雀部署、分阶段发布以及在需要严格控制更新顺序的有状态应用中进行灰度更新。核心能力:Revision 追踪:自动追踪 ModelServing 配置的变更。分区保护:支持基于分区的更新,确保发布过程中的服务连续性。回滚:轻松回退到之前稳定的 Revision。相关内容:🧩 PR: cid:link_7cid:link_8cid:link_9贡献者: @FAUST-BENCHOU, @LiZhenCheng9527▍Router 可观测性与调试对推理 Router 的深度洞察对于诊断延迟问题和确保 SLA 合规性至关重要。新的可观测性框架和调试端口为运维人员提供了必要的工具。核心能力:调试端口:专用端口(默认 15000),用于实时查看路由表和上游健康状况。综合指标:提供详细的文档和配置,用于监控请求延迟、吞吐量和错误率。端到端测试:鲁棒的 E2E 测试框架涵盖了大多数路由场景,确保了可靠性。相关内容: 🧩PR & Issue:cid:link_10cid:link_11cid:link_2贡献者: @yashisrani, @FAUST-BENCHOU, @YaoZengzeng, @katara-Jayprakash 其他显著变化 [ModelServing] 支持 ModelServing 滚动更新中的 maxUnavailable 参数(@LiZhenCheng9527) PR: https://github.com/volcano-sh/kthena/pull/640 [ModelServing] 实现扩展插件框架(@hzxuzhonghu) PR: cid:link_13 [ModelServing] 支持 vLLM 数据并行部署和专家并行(Expert Parallel)模式[CLI] 为 PD 分离使用场景添加模板 (@huntersman) PR: cid:link_3 [Client] 使客户端 QPS 和 Burst 可配置 (@FAUST-BENCHOU) PR: cid:link_14 [Webhooks] 在 Helm chart 中默认启用 ModelServing Webhook (@VanderChen) PR: cid:link_15 [Infra] 通过 hack/local-up-kthena.sh 实现源码一键部署 (@FAUST-BENCHOU PR: cid:link_16 此外,Kthena v0.3.0 还对多项bug进行了修复,感谢 @WHOIM1205 @LiZhenCheng9527 @VanderChen @hzxuzhonghu @FAUST-BENCHOU。📌 即刻访问体验 Kthena v0.3.0: cid:link_1 贡献者 感谢所有为此次Release做出贡献的伙伴: 相关资料[1] Kthena: https://kthena.volcano.sh/[2] Volcano: https://volcano.sh/en/[3] Kthena v0.3.0: cid:link_1[4] Network Topology: cid:link_0 添加社区小助手回复“Kthena”进入技术交流群
-
今天,Volcano 社区[1]很高兴地宣布新的子项目 AgentCube。基于 Volcano 在大规模高性能计算调度领域多年的生产实践积累,AgentCube 将这种高并发、高吞吐的调度能力延伸至 AI 领域,构建了一套面向智能体(Agent)工作负载的 Serverless 编排层,旨在为高并发、长会话、对延迟极度敏感的智能体(Agent)工作负载提供 Serverless 化的编排与极速调度能力。 从 Kubernetes 到 Agent Native 随着大语言模型(LLM)技术的成熟,技术架构正从“无状态推理”向“自主智能体(Autonomous Agents)”演进。在这一进程中,Kubernetes 凭借其成熟的生态和对异构算力的标准化管理,已成为构建 AI 基础设施的事实标准。虽然原生 Kubernetes 提供了通用的容器编排原语以及多样化的工作负载抽象,但在面对 AI Agent 这种“高并发、短时效、强状态依赖”的新型负载时,仍存在着显著的粒度错配与机制缺位:1. 启动延迟与交互体验的矛盾: Agent 的交互通常要求毫秒级响应。然而,原生的 K8s Pod 启动流程(调度、IP 分配、镜像拉取、容器启动)往往在秒级甚至分钟级。对于需要频繁拉起 Code Interpreter(代码解释器)或临时子 Agent 的场景,这种冷启动延迟是用户无法接受的。2. 资源利用率的挑战:Agent 是典型的密集型负载。在一次会话中,90% 的时间 Agent 可能都在等待 LLM 生成 Token 或等待外部工具响应。如果在 K8s 上为每个 Agent 独占一个 Pod,会导致大量的 CPU/Memory 资源在等待期间被闲置浪费,却无法被其他任务复用。3. 会话状态管理的缺失:K8s 对“无状态(Stateless)”工作负载天然友好,但 Agent 高度依赖“上下文(Context/Memory)”。在原生 K8s 中,Pod 重启意味着内存数据丢失,开发者被迫在应用层通过外部存储重建上下文,这带来了巨大的复杂性和网络开销。4. 安全隔离难题:高级 Agent(如 Data Analyst)需要运行由 LLM 生成的不可信代码。但普通的 runC 容器如果运行 rm -rf / 具有极高风险。企业级 Agent 平台迫切需要一种既能快速启动,又能提供强隔离(如 MicroVM)的沙箱环境。为了在 Kubernetes 坚实的算力底座之上,填补上述机制空白,AgentCube 应运而生。 AgentCube 是什么?AgentCube 是一个构建在 Volcano 之上的高性能 AI Agent 编排层。它通过扩展 Kubernetes API,将 Agents 和 Tools(Code Interpreters、BrowserUse等) 提升为集群的一等公民。它不仅仅是一个 CRD,更是一套 面向 Agent 的 Serverless 操作系统。▍核心架构与抽象AgentCube 引入了两个核心的 CRD 来定义 Agent 工作负载:1. AgentRuntime: 面向长会话、复杂的对话式 Agent。支持定义会话的生命周期、资源配额以及持久化策略。2. CodeInterpreter: 面向短任务、高频的代码执行环境。强调“用完即毁”和极致的安全隔离,天然适配 MicroVM(如 Kuasar, Kata Containers, Firecracker)。AgentCube后续还将提供BrowserUse、ComputerUse、MobileUse等工作负载抽象支持。 AgentCube 关键技术亮点 为了解决上述痛点,AgentCube 在架构设计上引入了多项创新:▍1. 极速启动为了消除冷启动的挑战,AgentCube 实现了 Warm Pool(预热池) 机制。系统会预先启动并暂停一组持有基础环境的 MicroVM 沙箱。当 Agent 请求到来时,AgentCube 能够通过 "Claim-and-Go" 的方式,在毫秒级将预热的沙箱分配给会话,实现近乎零延迟的启动体验。▍2. 极速调度借助 Volcano 的 Agent Scheduler,AgentCube显著提升了Agent调度的吞吐和时延。高吞吐、低时延: 针对 Agent 突发流量,采用了乐观并发控制和精简的调度策略,大幅提升调度 TPS。统一调度支持: Volcano 的 Agent Scheduler 可以与原有的 Batch Scheduler 无缝配合,在协调 Agent 与传统的 Batch 作业潜在调度冲突的同时,确保整体集群的资源利用率和关键业务的 SLA。▍3. 原生会话管理AgentCube 引入了 Session ID 作为核心路由标识,便于保证业务上下文的连续性。请求路由: AgentCube Router 能够识别请求中的 x-agentcube-session-id,自动将其路由到对应的活跃沙箱。自动的沙箱激活: 当前会话对应的沙箱处于休眠状态时,AgentCube Router 能够自动激活沙箱。基于会话的端到端隔离: AgentCube 会自动为每个会话分配独立的沙箱环境,确保计算、内存与文件系统的完全隔离,防止跨租户的数据泄露。▍4. Serverless 化的弹性伸缩AgentCube 能够根据会话的活跃度自动管理沙箱生命周期。闲置的沙箱会被自动回收或休眠,释放物理资源供其他高优先级任务使用,真正实现资源按需分配与极致利用。 AgentCube 架构概览 AgentCube 采用了经典的控制面与数据面分离的架构设计,确保了系统的高可用性与扩展性:数据面 : 由 AgentCube Router 承载。它作为流量入口,负责鉴权、限流以及基于 Session ID 的智能路由。对于新会话,它向控制面申请资源;对于活跃会话,它直接将请求转发至对应的 Sandbox (MicroVM)。控制面 : 核心组件 Workload Manager 负责沙箱的全生命周期管理。它监控预热池 (Warm Pool) 的水位,自动补充 MicroVM 实例,并根据会话活跃度策略(如 TTL)执行沙箱的回收与垃圾清理。调度层: 集成 Volcano Agent Scheduler,通过异步并行调度和乐观锁机制,实现高并发下的毫秒级资源分配。 生态协作:共建标准化的 Agent 基础设施 作为开源中立的基础设施项目,AgentCube 旨在通过标准接口连接上下游生态,协作解决从容器编排到智能体应用落地的“最后一公里”难题。1. 南向兼容:基于标准接口的运行时适配AgentCube 坚持开放架构设计,通过深度集成 kubernetes-sigs/agent-sandbox 接口及 OCI 标准,实现对底层异构运行时的统一抽象与无感适配。运行时解耦: 支持通过 RuntimeClass 机制接入 Kuasar、Kata Containers、Firecracker 等安全容器技术,允许用户根据安全与性能需求灵活选择底层隔离方案。前沿探索: 社区正在评估 Wasm (WebAssembly) 技术,计划在未来版本中探索其在极轻量级 Agent 任务中的应用,以提供更多样化的算力供给。2. 北向集成:服务主流Agent框架在应用层,AgentCube 致力于成为 Dify、LangChain、CrewAI、LlamaIndex 等Agent框架的标准基础设施底座,相关适配工作正在快速迭代中。声明式管理: 将通过 Operator 模式提供声明式资源接口,帮助上层框架剥离底层的沙箱预热池管理与网络配置等逻辑。统一底座: 目标是实现业务编排与资源调度的解耦,使不同框架开发的应用能复用同一套云原生运维体系,降低基础设施的维护成本与碎片化程度。 灵活接入:兼顾开发与运维体验 AgentCube 设计了分层的接入接口,旨在同时满足上层业务开发者与底层平台工程师的诉求,让基础设施不再成为黑盒。1. 面向 Agent 开发者:标准 API 接入为了进一步降低接入门槛,AgentCube 提供了开箱即用的 Python SDK[2]。开发者无需深入理解 Kubernetes 的复杂概念,即可像调用本地函数一样申请、执行和释放沙箱。这使得 AgentCube 能够轻松集成到 Dify、LangChain、CrewAI、LlamaIndex 等主流框架中。📄 示例1:在agent代码中动态拉起一个CodeInterpreter并运行临时代# python from agentcube import CodeInterpreterClient # Initialize client (uses env vars for configuration) with CodeInterpreterClient() as client: # 1. Run a simple shell command print("User: whoami") print(client.execute_command("whoami")) # 2. Execute Python code code = """ import math print(f"Pi is approximately {math.pi:.4f}") """ output = client.run_code("python", code) print(f"Result: {output}")📄 示例2:通过kubectl agentcube命令行工具创建一个Agent# 1. Package an existing agent: kubectl agentcube pack -f examples/hello-agent --agent-name "my-agent" # 2. Build the container image: kubectl agentcube build -f examples/hello-agent # 3. Publish to AgentCube: kubectl agentcube publish \ -f examples/hello-agent \ --image-url "docker.io/username/my-agent" \ # 4. Invoke your agent: kubectl agentcube invoke -f examples/hello-agent --payload '{"prompt": "Hello World!"}' # 5. Check status: kubectl agentcube status -f examples/hello-agent2. 面向平台工程师:声明式 CRD 管理AgentCube 延续了云原生的声明式管理模式。运维团队可以通过 CRD (AgentRuntime, CodeInterpreter) 精细化定义资源池策略,直接复用现有的 Kubernetes 运维体系与工具链进行统一管理。📄 示例:定义一个CodeInterpreter,始终保持 10 个热备沙箱# YAML apiVersion: runtime.agentcube.volcano.sh/v1alpha1 kind: CodeInterpreter metadata: name: simple-codeinterpreter namespace: default spec: template: image: ghcr.io/volcano-sh/picod:latest sessionTimeout: "15m" maxSessionDuration: "8h" warmPoolSize: 10 # 预热水位想亲自体验?完整的安装部署文档与 Demo 示例,请访问 GitHub 仓库:cid:link_1 加入社区 AgentCube 是 Volcano 社区的一部分,遵循开源开放的原则。我们诚挚邀请对 AI Infra、Kubernetes 调度、Serverless 架构 感兴趣的开发者加入我们!GitHub: https://github.com/volcano-sh/agentcube( 欢迎Star ⭐️) Slack: CNCF Slack # volcano 频道Community Meeting: 关注 Volcano 社区双周会 [3]。让我们一起,为 AI Agent 时代构建更强大的基础设施!相关链接[1] Volcano 社区官网: https://volcano.sh/en/[2] Python SDK: cid:link_0[3] Volcano 社区双周会: https://zoom.us/j/91804791393 Volcano 是业界首个云原生批量计算引擎,也是 CNCF 首个和唯一的批量计算项目。项目主要用于 AI、大数据、基因、渲染等诸多高性能计算场景,对主流通用计算框架均有很好的支持。目前,Volcano在人工智能、大数据、基因测序等海量数据计算和分析场景已得到快速应用,已完成对 Spark、Flink、Ray、 Tensorflow、PyTorch、Argo、MindSpore、Paddlepaddle 、Kubeflow、MPI、Horovod、Mxnet、KubeGene 等众多主流计算框架的支持,并构建起完善的上下游生态。Website:https://volcano.shGitHub: cid:link_2每周例会:https://zoom.us/j/91804791393 添加社区小助手回复“Volcano”进入技术交流群
-
Karmada 用户组再迎重要新成员,商汤科技[1]正式加入。 作为云原生计算基金会(CNCF)旗下项目,Karmada 致力于为用户提供强大的多集群管理和调度能力,帮助企业在复杂的分布式环境中实现高效的应用部署和管理。 商汤科技的加入将进一步加强 Karmada 社区,为项目的持续创新注入新的活力,标志着社区发展及 Karmada 在多样化生产环境中应用的又一个重要里程碑。 关于商汤科技 商汤科技坚持“AI 基础设施(大装置)-大模型(日日新)-应用”三位一体战略。 商汤大装置作为商汤科技前瞻打造的高效率、低成本、规模化的新一代 AI 基础设施, 以大模型开发、生成、应用为核心,赋能人工智能生产新范式。 通过与大模型迭代的联合调优,打造“最懂大模型的 AI 基础设施”。2022年,作为商汤大装置重要载体的人工智能计算中心(上海临港 AIDC)正式投入运营, 成为亚洲最大人工智能计算中心之一。过去三年, 商汤持续投入建设并自持全国首个 5A 级智算中心上海临港 AIDC, 以及通过运营模式将算力总规模提升至32,000 PFlops(截至2025年12月)。 强大算力可支撑超过 20 多个千亿参数超大模型同时训练, 并支持万亿参数大模型的全生命周期生成。作为行业先行者,商汤大装置已构建起“算力-平台-方案-服务”的端到端系统化能力, 既为商汤日日新大模型的迭代提供了核心动力, 也快速承接了各行业客户的大模型创新需求, 持续赋能 AIGC、具身智能、AI4S、产业智能化等相关领域创新。 关于 Karmada 用户组 Karmada 用户组是一个由在其环境中成功采用 Karmada 的组织和用户组成的社区。作为连接社区与用户的核心纽带,Karmada 用户组致力于打造一个深度融合、开放协作的高价值平台,推动成员间的高效联动与经验共享,助力云原生多云多集群生态系统的蓬勃发展。成为 Karmada 用户组成员具有以下优势:社区认可:作为云原生多集群管理领域的领导者来展示您的组织,在 CNCF 和 Karmada 社区中获得知名度;协作与交流:与其他采用者建立联系,分享最佳实践,并在实际用例和解决方案上进行协作;保持更新:及时接收重要更新通知,包括关键功能、错误修复和安全建议;活动参与:受邀参与 Karmada 相关活动,包括 KubeCon + CloudNativeCon、网络研讨会和聚会;职位发布:有机会在 Karmada 社区支持的职位公告板上发布与 Karmada 相关的职位空缺(暂不可用);扩展商业机会:与 Karmada 生态系统的其他成员建立潜在的商业联系和合作。您可以在 GitHub 社区仓库中了解更多关于 Karmada 用户组[2] 的信息, 并在 karmada.io/adopters [3] 查看完整的公开的采用者列表。截至目前,Karmada 用户组已吸纳来自全球的 40+ 家机构和组织。更多使用场景及案例研究请查阅:https://karmada.io/adopters 加入 Karmada 用户组 Karmada 用户组对当前正在生产环境中使用 Karmada 的最终用户和供应商开放。这包括:最终用户:在其生产环境中运行 Karmada 的组织;供应商:提供基于 Karmada 的产品或服务,并有客户在生产环境中使用这些产品或服务的公司。您是否在生产环境中使用 Karmada 并有兴趣加入 Karmada 用户组?访问下方 Karmada 用户组申请表单 [4],提交 issue 申请,即可接收申请进度。手机端可扫描下方二维码快捷填写申请表单。 扫码申请加入用户组更多信息,请访问:[1] 商汤科技: https://www.sensetime.com/[2] Karmada 用户组: cid:link_0[3]Karmada 采用者列表: http://karmada.io/adopters[4]Karmada 用户组申请表单: https://github.com/karmada-io/community/issues/new?template=adopter-group-application.yamlKarmada Adopter Group 欢迎您的加入!期待与您共同创建一个友好而活跃的空间,共享知识、最佳实践和经验,为企业与社区发展缔造更多可能。如需了解更多关于 Karmada Adopter Group 的信息,请联系: Maintainer Mailing Listcncf-karmada-maintainers@lists.cncf.io Karmada 是CNCF 首个多云多集群容器编排项目(孵化级),旨在帮助用户像使用单个集群一样轻松管理跨云多集群,让基于 Karmada 的多云方案无缝融入云原生技术生态。社区吸引了来自华为、道客、浙江大学、滴滴、腾讯、中国电子云等60多家公司的全球贡献者,广泛分布于22个国家和地区。Karmada 现已在华为云、道客、兴业数金、中国移动、中国联通、携程、360集团、新浪、中通快递等众多企业单位生产应用,为企业提供从单集群到多云架构的平滑演进方案。Karmada官网:https://karmada.io/项目地址:cid:link_1Slack地址:https://slack.cncf.io/(#karmada) 扫码回复“Karmada” 进入技术群
-
面对互联网大促,技术团队最为焦虑的莫过于“系统能否扛住”,如何打破“峰值体验差”与“资源成本失控”的魔咒?沙特家电零售巨头 Alsaif Gallery 借助华为云 CCE Autopilot,实现系统时延降低 75%、日常运维负担减少 80%、成本优化 30%。当2025年沙特国庆日销售战绩定格在单日5万订单时,Alsaif Gallery 技术团队感受到的不仅是喜悦,更是一种久违的从容。就在数月前,同样的流量洪峰还意味着紧绷的神经与对系统中断的深深焦虑。如今,这一切已成为历史。运维工作从过去如“黑盒”般不可预测,到如今“智驾”般自动高效,曾经困扰 Alsaif Gallery 许久的“流量峰值用户体验”和“失控的资源成本”两大难题,已不再是平台业务爆发增长的绊脚石。这家沙特家电零售巨头的数字化转型之路,因一次关键的云迁移而彻底提速。业务狂奔,技术绊脚作为沙特前三的家电零售商,Alsaif Gallery线上业务增长迅猛。日均超3万笔订单的电商平台,是其当之无愧的业务核心引擎。然而,这台引擎的基础设施却长期饱受压力。原有云架构的复杂性,让技术团队在每次大促前都如履薄冰。他们面临着三重挑战:排障如“黑盒”:平台故障排查依赖原第三方厂商跨国支持,响应迟缓,排障效率低,并且缺乏全链路观测工具,定位问题如同大海捞针。运维靠“人扛”:中东本地资深的K8s与SRE专家稀缺,导致现有K8s集群只能维持基本运行,无法进行深度性能优化。同时,高度复杂且耦合的系统,运维严重依赖少量核心人员,使得性能瓶颈与运维风险并存。成本“过山车”:面对突发流量,原有基于虚拟机的资源模式扩缩速度慢,人工配置的扩缩策略难以自适应多变的流量。促销时资源“扩不上去”,影响用户体验;促销后资源“缩不下来”,白白浪费成本。对于依赖“斋月”、“白色星期五”等关键销售季的中东零售业而言,这不仅是技术问题,更是直接关乎品牌声誉的业务风险。Alsaif Gallery&华为云:一场始于信任的“无感迁移”面对与旧云服务深度捆绑的复杂架构,Alsaif Gallery对迁移最初持谨慎态度。华为云团队用专业与诚意破除了这层顾虑。这不是简单搬家,而是联创设计。华为云交付团队与架构师提前介入,通过超10次的深度技术交流与业务梳理,将客户“提升系统稳定性、降低运维成本”的核心诉求,转化为一套量身定制的“上云+优化”组合方案。不回避难题,而是逐一攻克。针对容器搬迁、函数改造、安全配置等十余项具体技术挑战,华为云拉通产品专家驻场支持,将迁移风险一一化解。这种直面复杂性的务实态度,赢得了客户的最终信任,决心将核心容器业务迁至华为云CCE Autopilot。系统运维跃迁:从“手动挡”到“智能驾驶”系统整体迁移仅仅花费一个月,但变化效果立竿见影。华为云CCE Autopilot的Serverless能力,为Alsaif Gallery带来了运维模式的根本性变革:全面自动化:节点、操作系统、集群升级全面自动化,让技术团队从繁琐的基础设施维护中解放出来。无缝兼容:100%兼容K8s生态,原有应用平滑迁移,业务0改造。精准弹性:基于真实负载的秒级伸缩,实现所得即所需的理想状态。迁移后,Alsaif Gallery成果直接体现在三个关键指标上:负担锐减:日常运维工作量降低80%,让技术团队得以聚焦创新。成本优化:凭借按需计费与精准弹性,资源利用率提升20%,成本降低30%以上。体验提速:系统时延从120ms大幅降低至30ms以内,用户端操作响应更加流畅。通过此次迁移,让Alsaif Gallery技术专家角色由此转变:从过去疲于奔命的“消防员”,转型成为了驾驭高效引擎、驱动业务增长的“设计师”。持续共建:从云迁移到长期战略合作本次迁移的成功,不是终点,而是Alsaif Gallery与华为云更长远合作的起点。基于建立起的信任,双方合作正向纵深发展:从大数据治理中挖掘零售电商高增长业务,到构建AI知识库提升内部效率,一系列新的数字化规划已提上日程。而华为云在其中的独特价值在于:不仅是技术的提供者,更是深谙本地市场的同行者。在沙特,华为云拥有超过200名本地技术专家,能提供7*24小时无时差响应,并深刻理解区域合规与市场特性,真正做到了“全球能力,本地服务”。云计算新范式:从“资源开销”变成“业务引擎”在沙特“2030愿景”掀起的数字化浪潮中,企业的竞争本质上是效率与敏捷性的竞争。华为云通过CCE Autopilot,为Alsaif Gallery提供的不仅是一个更强大的云平台,更是一套将复杂运维自动化、让运营成本可视可控的系统。这标志着一种全新范式的转变:云计算从“资源开销”变为企业真正的“业务引擎”。当数字基石稳固而智能,企业的增长便只需聚焦于前方更广袤的市场。
-
作者:Volcano Maintainers今天,我们激动地向全球开发者和 MLOps 工程师宣布,Volcano 社区迎来了一个新的子项目 Kthena!Kthena 是一个专为 Kubernetes 设计的云原生、高性能 LLM 推理路由和编排、调度系统。它旨在解决在生产环境中大规模编排、部署和服务 LLM 所面临的核心挑战,通过其独特的超节点拓扑感知的亲和性调度,KV Cache 感知的流量调度、Prefill/Decode 分离路由等高级功能,显著提升 GPU/NPU 资源利用率和吞吐,降低推理延迟,赋予企业前所未有的灵活性和控制力。作为 Volcano 的子项目,Kthena 将致力于帮助 Volcano 扩展除 AI 训练之外的边界,打造训推一体的完整解决方案。 LLM 服务化的“最后一公里”困境 大语言模型(LLM)正在以前所未有的速度重塑各行各业,但将其高效、经济地部署在生产环境中,特别是基于 Kubernetes 的云原生平台上,仍然困难重重。开发者们普遍面临以下挑战:1. 资源利用率低:LLM 推理,尤其是其独特的 KV Cache 机制,对 GPU、NPU 显存的占用是动态且巨大的。传统的负载均衡一般采用Round-Robin算法,无法感知这种负载特性,导致 GPU、NPU 资源闲置与请求排队并存,成本高昂。2. 延迟与吞吐量难以兼顾:LLM 推理分为“Prefill”(处理输入提示)和“Decode”(生成 Token)两个阶段,前者是计算密集型,后者是访存密集型。将两者混合调度,常常导致无法针对性优化,影响整体服务的响应速度和吞吐能力。因此PD分离的部署已经成为主流,但如何高效路由和调度,仍是一个难题。3. 多租户与多模型管理复杂:在企业环境中,通常需要同时提供多个不同模型、不同版本或经过 LoRA 微调的模型。如何实现请求的公平调度、优先级管理以及动态路由,是一个复杂的工程难题,业界甚至有些方案将AI网关与大模型一一对应。4. 缺乏K8s原生集成:许多现有的解决方案要么是外部系统,与 Kubernetes 生态割裂;要么过于复杂,无法满足生产级所需的简单易用性和灵活运维。 Kthena:云原生 LLM 推理的智能大脑 为了攻克上述难题,Kthena 应运而生。它并非要取代现有的 LLM 服务框架(如 vLLM, sgLang),而是作为它们上层的智能“交通枢纽”和“调度中心”,深度集成于 Kubernetes 之中。Kthena 架构图Kthena 的核心由两大组件构成:1)Kthena Router:一个独立、高性能面向多模型的router,负责接收所有推理请求,并根据 ModelRoute 规则,智能地将请求分发到后端的 ModelServer。2)Kthena Controller Manager:Kubernetes 控制平面的控制器,它主要包含多种控制器,负责 LLM 工作负载的编排与生命周期管理。它持续调谐并联动多类 CRD(如 ModelBooster、ModelServing、AutoScalingPolicy/AutoScalingPolicyBinding、以及 ModelRoute/ModelServer),将声明式API转化为运行时资源:ModelServing 控制器编排 ServingGroup 与 Prefill/Decode 角色分组;支持网络拓扑亲和调度和Gang调度、滚动升级与故障恢复;基于 AutoScalingPolicy 实现弹性扩缩容。这种架构使得 Kthena 成为连接用户请求与 LLM 模型的高度可编程的桥梁。 核心特性与优势 Kthena 的强大之处在于其专为 LLM 推理场景设计的核心功能:1) 生产级推理编排(ModelServing)LLM工作负载三层架构设计:ModelServing -> ServingGroup -> Role,一个API,支持LLM原生部署、PD分离部署,乃至大EP部署等多种部署形态,简化管理多LWS的负担。例如对于PD分离的大规模部署,可用一个ModelServing表示,根据负载的大小每个ModelServing可以包含任意数目的 ServingGroup(xPyD 分组), 每个ServingGroup包含多个角色(Prefill Decode,他们通常部署在同一个超节点内以提升推理性能),相同的角色可以等价为一个LeaderWorkerSet,支持TP/PP/EP等多节推理并行计算。原生支持Prefill-Decode分离部署:将计算密集型的 Prefill 实例调度到配备高性能计算卡的节点组,而将访存密集型的 Decode 实例调度到配备高带宽显存的节点组,实现资源的最佳匹配和极致的端到端延迟优化。另可以独立伸缩,动态调整Prefill-Decode的比例,更灵活的应对各种复杂的业务场景(如长短句混合、实时推理等)。多并行范式支持:TP/PP/DP/EP 等并行模式灵活配置,最大化提升资源利用率和SLO内置拓扑感知、Gang 调度支持:Gang调度确保ServingGroup/Role“成组原子化”落地,避免资源浪费;拓扑感知调度通过将Role内的一组Pod调度到网络拓扑更优的节点,提升并行计算的数据传输时延。2) 开箱即用的模型上线(ModelBooster)针对主流的大模型,提供包括PD分离在内的多种部署范式模板,自动生成ModelRoute/ModelServer/ModelServing/Autoscaling等路由策略和生命周期管理资源覆盖通用的部署场景,至于更灵活的编排可通过ModelServing进行细粒度的控制3) 智能、模型感知的路由(Kthena Router)多模型路由:兼容OpenAI API,根据请求头或Body体内容,将流量调度到不同的基础模型。插件化调度算法:提供最少请求、最小时延、KV Cache 感知、Prefix Cache 感知、LoRA 亲和、GPU 利用率感知、公平调度等多种负载均衡算法,满足用户不同业务场景和部署形态的需求LoRA 模型热插拔无中断:感知推理引擎加载的LoRA 适配器,提供无中断的插拔和路由能力丰富的流量治理策略:基于权重的模型路由,金丝雀发布、Token级流控、故障转移·All-in-one实现架构,无需部署Envoy Gateway,原生支持PD分离的流量调度,将多层路由合并成一层,易于维护4) 成本驱动的自动扩缩容(Autoscaler)同构伸缩:支持稳定、突发双模式,按业务指标(CPU/GPU/内存/自定义)精准扩缩异构部署优化:在多推理引擎/异构加速器组合中按“成本-能力”贪心分配,最大化性价比5) 主流推理引擎与异构硬件支持支持多种主流推理引擎vLLM、SGLang、Triton/TGI 等,统一API抽象、标准化指标支持GPU/NPU 等异构混部,配合异构 Autoscaling 实现成本与 SLO 的动态平衡6) 内置流量控制与公平性调度公平调度:支持基于优先级和历史Token消耗的的公平调度,既兼顾用户的优先级,对高优先级用户提供更好的服务,又防止低优先级用户“饿死”流量控制:支持按照用户、模型、token长度进行精细化流量控制。 极致的性能提升 基于 Kthena Router 的调度插件架构,在长系统提示词场景(如 4096 tokens)下,采用“KV Cache 感知 + 最少请求”策略相较随机基线:吞吐可提升约 2.73 倍TTFT 降低约 73.5%端到端时延降低超过 60%短提示词场景差距会随提示词长度收敛,但在多轮对话、模板化生成、前缀高度相似的业务中,KV Cache 感知策略优势显著。实际收益与模型规模、Prompt长短、硬件紧密相关,但“按需组合、按场景选型”已被验证有效。 社区展望 / Call for Contribution Kthena 在项目规划和发展的初期便得到了部分社区用户单位的关注和支持,但这只是一个开始。我们计划在未来支持更高效的调度算法、更广泛的大模型最佳部署实践,并持续深耕 LLM 推理的大规模部署和性能优化。“ 开源是技术创新的源头活水,也是推动产业标准化的最强引擎。作为Volcano项目的发起单位,华为云很荣幸能够与社区其他伙伴一起推出全新的Kthena分布式推理项目。这不仅是Volcano社区技术演进的重要里程碑,更是华为云在云原生AI领域长期投入与持续创新的有力见证。它将与华为云CCE(云容器引擎)、CCI(云容器实例)等基础设施深度结合,进一步释放包括昇腾(Ascend)在内的多元算力价值,为客户提供极致的算力性价比。我们希望通过Kthena,与全球开发者与伙伴,共建、共享一个开放、繁荣的云原生AI生态,为千行万业的智能化升级构筑最坚实的算力底座。”—— 祁小波,华为云通用计算服务产品部部长“ Kthena进一步巩固了Volcano在智能计算调度领域的领先地位。我们的平台利用Volcano的统一调度与资源池化能力,一站式满足通用计算与智能计算中训练、推理等多类算力需求。这使得算力资源能够在不同场景间灵活流转,有效避免了资源割裂的问题。展望未来,我们期待 Kthena结合Volcano的弹性伸缩能力与Volcano Global的跨集群调度特性,共同推动算力资源利用率进一步提升!”—— 杨磊,中电信人工智能公司 PaaS研发总监“ Volcano 项目自诞生之日起,便始终与社区以及各类 AI 场景深度共建、同频演进,逐步沉淀出一整套面向 AI 工作负载的调度与批处理生态。今天,Kthena 的出现,不仅将这条共建链路进一步拓展到大模型推理领域,把推理这一关键一环真正纳入 Volcano 生态之中,更是在统一编排与智能路由层面,将 Volcano 在调度、弹性伸缩以及多算力适配上的多年实践,凝练成一个令人振奋的里程碑式能力。借助既有的 Kubernetes / Volcano 生态,更多团队可以用更低的成本,获得更智能的调度决策和更高效的算力利用,并在开放协作的基础上持续演进。这不仅为道客解决了在推理场景中遇到的实际问题,也是我们所期待的云原生 AI 形态——一个足够开放、足够智能、值得我们长期投入和深度参与的社区方向。”—— 徐俊杰,DaoCloud 开源团队负责人,Kubernetes 社区指导委员会成员“ 自建大模型推理服务的生产级部署和运维难题,是一个覆盖推理服务全生命周期管理(部署、运维、弹性、故障恢复等),GPU集群稳定性,资源调度效率、推理服务性能提升,推理流量智能调度、AI可观测等领域的系统工程。而这也正是Kthena项目的技术定位。早在Kthena的规划阶段,小红书云原生团队就和Kthena贡献者做了深度的沟通,在推理流量智能调度方向,一起设计了多种流量调度策略和路由实现。未来,双方将继续在AI网关方向合作,结合小红书内部业务经验,一起为社区提供更精细化的AI流量智能调度能力,模型API管理能力,MCP协议支持等多种生产可用能力。”—— 空古(陈华昌),小红书云原生业务网关负责人“ 在深入调研并试用Kthena这一云原生AI推理平台后,联通云对其展现出的前瞻能力印象深刻。我们尤为看好其与Volcano实现的联合调度特性,其网络拓扑感知与Gang Scheduling功能,能够有效解决大规模分布式模型推理场景下中,关于效率与可靠性的核心诉求,为破解复杂调度难题提供了极具潜力的解决方案。我们相信,Kthena卓越的低延迟、高吞吐与多模型智能路由能力,将为开源社区带来真正具备生产级的AI推理解决方案,助力开发者更高效地构建和管理云原生环境下的智能应用。”—— 卢照旭,联通云智算能力中心团队长“ 开放和协作是构建社区的未来、加速技术创新的核心动力。在CNCF,我们持续致力于推动基础设施向‘AI Native’演进,为整个云原生生态提供标准、中立且可扩展的基础能力。Volcano社区通过孵化Kthena子项目,将其在大规模批量计算和调度上积累的拓扑感知、Gang调度等核心经验,精准地应用到了LLM在线推理这一关键场景。Kthena的价值在于,它提供了一套专为大模型设计、可供业界参考借鉴的云原生调度原语和抽象,这有助于将复杂的LLM推理工作负载,真正以Kubernetes原生的一等公民身份进行高效管理。这不仅是Volcano项目技术演进的重要一步,更是社区生态在解决AI规模化部署挑战中贡献的一份重要实践经验。我们诚挚邀请全球的开发者、研究人员和所有云原生爱好者加入,共同贡献智慧,完善这些关键AI基础设施,加速 AI Native 进程。”—— Kevin Wang,Volcano Maintainer、CNCF TOC 副主席 立即开始探索 Kthena GitHub 仓库: cid:link_1Volcano 官网: https://kthena.volcano.sh/社区(加入我们的 Slack): https://cloud-native.slack.com/archives/C011GJDQS0N让我们一起,为 LLM 插上云原生的翅膀,释放 AI 的全部潜能! Volcano 是业界首个云原生批量计算引擎,也是 CNCF 首个和唯一的批量计算项目。项目主要用于 AI、大数据、基因、渲染等诸多高性能计算场景,对主流通用计算框架均有很好的支持。目前,Volcano在人工智能、大数据、基因测序等海量数据计算和分析场景已得到快速应用,已完成对 Spark、Flink、Ray、 Tensorflow、PyTorch、Argo、MindSpore、Paddlepaddle 、Kubeflow、MPI、Horovod、Mxnet、KubeGene 等众多主流计算框架的支持,并构建起完善的上下游生态。 更多云原生技术动向关注容器魔方
-
Karmada 是开放的多云多集群容器编排引擎,旨在帮助用户在多云环境下部署和运维业务应用。凭借兼容 Kubernetes 原生 API 的能力,Karmada 可以平滑迁移单集群工作负载,并且仍可保持与 Kubernetes 周边生态工具链协同。本系列文章将介绍Karmada的使用教程,本文介绍如何通过 Workload Rebalancer 触发重调度。目标一般情况下,工作负载类资源被调度后,会保持调度结果不变,其副本分布不会轻易发生变化。 现在,假设某些特殊情况下,您想主动触发一次重调度,可以通过使用 WorkloadRebalancer 来实现。因此,本节将指导您如何使用 WorkloadRebalancer 来触发重调度。 前提条件▍Karmada 及多个子集群已安装运行安装命令:git clone cid:link_0cd karmadahack/local-up-karmada.shexport KUBECONFIG=~/.kube/karmada.config:~/.kube/members.config 说明:在开始之前,我们应该至少安装三个 kubernetes 集群,一个用于安装 Karmada 控制平面,另外两个作为成员集群。 为了方便,我们直接使用 hack/local-up-karmada.sh 脚本快速准备上述集群。执行上述命令后,您将看到 Karmada 控制平面和多个成员集群已安装完成。教程▍第一步:创建一个 Deployment首先准备一个名为 foo 的 Deployment,您可以创建一个新文件 deployment.yaml,内容如下:apiVersion: apps/v1kind: Deploymentmetadata: name: foo labels: app: testspec: replicas: 3 selector: matchLabels: app: foo template: metadata: labels: app: foo spec: terminationGracePeriodSeconds: 0 containers: - image: nginx name: foo resources: limits: cpu: 10m memory: 10Mi---apiVersion: policy.karmada.io/v1alpha1kind: PropagationPolicymetadata: name: default-ppspec: placement: clusterTolerations: - effect: NoExecute key: workload-rebalancer-test operator: Exists tolerationSeconds: 0 clusterAffinity: clusterNames: - member1 - member2 replicaScheduling: replicaDivisionPreference: Weighted replicaSchedulingType: Divided weightPreference: dynamicWeight: AvailableReplicas resourceSelectors: - apiVersion: apps/v1 kind: Deployment name: foo namespace: default然后,运行下述命令来创建这些资源:kubectl --context karmada-apiserver apply -f deployment.yaml您可以通过下述方式来检查该步骤是否成功:$ karmadactl --karmada-context karmada-apiserver get deploy fooNAME CLUSTER READY UP-TO-DATE AVAILABLE AGE ADOPTIONfoo member1 2/2 2 2 20s Yfoo member2 1/1 1 1 20s Y可以看到,2 个副本分发到 member1 集群,1 个副本分发到 member2 集群。 ▍第二步:在 member1 集群添加 NoExecute 污点以模拟集群故障1)运行以下命令将 NoExecute 污点添加到 member1 集群:$ karmadactl --karmada-context=karmada-apiserver taint clusters member1 workload-rebalancer-test:NoExecutecluster/member1 tainted然后,由于集群故障转移,将触发重调度,并且所有副本将被分发到 member2 集群,您可以看到:$ karmadactl --karmada-context karmada-apiserver get deploy fooNAME CLUSTER READY UP-TO-DATE AVAILABLE AGE ADOPTIONfoo member2 3/3 3 3 57s Y2)运行以下命令从 member1 集群中移除上述 NoExecute 污点:$ karmadactl --karmada-context=karmada-apiserver taint clusters member1 workload-rebalancer-test:NoExecute-cluster/member1 untainted移除污点不会导致副本传播变化,因为调度结果是惰性的,所有副本将保持在 member2 集群中不变。 ▍第三步:创建一个 WorkloadRebalancer 来触发重调度为了触发上述资源的重调度,您可以创建一个新文件 workload-rebalancer.yaml,内容如下:apiVersion: apps.karmada.io/v1alpha1kind: WorkloadRebalancermetadata: name: demospec: workloads: - apiVersion: apps/v1 kind: Deployment name: foo namespace: default然后运行以下命令来创建该资源:kubectl --context karmada-apiserver apply -f workload-rebalancer.yaml您将得到 workloadrebalancer.apps.karmada.io/demo created 的结果,这意味着该资源创建成功。 ▍第四步:检查 WorkloadRebalancer 的状态运行以下命令:$ kubectl --context karmada-apiserver get workloadrebalancer demo -o yamlapiVersion: apps.karmada.io/v1alpha1kind: WorkloadRebalancermetadata: creationTimestamp: "2024-05-25T09:49:51Z" generation: 1 name: demospec: workloads: - apiVersion: apps/v1 kind: Deployment name: foo namespace: defaultstatus: finishTime: "2024-05-25T09:49:51Z" observedGeneration: 1 observedWorkloads: - result: Successful workload: apiVersion: apps/v1 kind: Deployment name: foo namespace: default因此,您可以在 workloadrebalancer/demo 的 status.observedWorkloads 字段中观察重调度的结果。 如上述结果所示,deployment/foo 已成功重新调度。 ▍第五步:观察 WorkloadRebalancer 的实际效果您可以观察 deployment/foo 的副本实际分发状态:$ karmadactl --karmada-context karmada-apiserver get deploy fooNAME CLUSTER READY UP-TO-DATE AVAILABLE AGE ADOPTIONfoo member1 2/2 2 2 3m14s Yfoo member2 1/1 1 1 4m37s Y您可以看到重调度已完成,有2个副本迁移回到 member1 集群,而 member2 集群中原有的1个副本保持不变。此外,您可以观察到由 default-scheduler 发出的调度事件,例如:$ kubectl --context karmada-apiserver describe deployment foo...Events: Type Reason Age From Message ---- ------ ---- ---- ------- ... Normal ScheduleBindingSucceed 3m34s (x2 over 4m57s) default-scheduler Binding has been scheduled successfully. Result: {member1:2, member2:1} Normal AggregateStatusSucceed 3m20s (x20 over 4m57s) resource-binding-status-controller Update resourceBinding(default/foo-deployment) with AggregatedStatus successfully. ... ▍第六步:更新并自动清理 WorkloadRebalancer假设您希望 WorkloadRebalancer 能在将来自动清理,您只需编辑资源声明并将 spec.ttlSecondsAfterFinished 字段设置为 300,例如:apiVersion: apps.karmada.io/v1alpha1kind: WorkloadRebalancermetadata: name: demospec: ttlSecondsAfterFinished: 300 workloads: - apiVersion: apps/v1 kind: Deployment name: foo namespace: default在您应用了这个修改后,这个 WorkloadRebalancer 资源将在 300 秒后自动删除。更多Karmada云原生多云容器引擎使用教程与技术交流,欢迎关注Karmada社区公众号或添加社区小助手k8s2222,回复Karmada进群。 Karmada 公众号 Karmada 是CNCF 首个多云多集群容器编排项目(孵化级),旨在帮助用户像使用单个集群一样轻松管理跨云多集群,让基于 Karmada 的多云方案无缝融入云原生技术生态。社区吸引了来自华为、道客、浙江大学、滴滴、腾讯、中国电子云等60多家公司的全球贡献者,广泛分布于22个国家和地区。Karmada 现已在华为云、道客、兴业数金、中国移动、中国联通、携程、360集团、新浪、中通快递等众多企业单位生产应用,为企业提供从单集群到多云架构的平滑演进方案。Karmada官网:https://karmada.io/项目地址:cid:link_0Slack地址:https://slack.cncf.io/(#karmada)
-
Karmada 是开放的多云多集群容器编排引擎,旨在帮助用户在多云环境下部署和运维业务应用。凭借兼容 Kubernetes 原生 API 的能力,Karmada 可以平滑迁移单集群工作负载,并且仍可保持与 Kubernetes 周边生态工具链协同。本系列文章将介绍Karmada的使用教程,本文介绍如何通过原生 Service 跨集群访问服务。在 Karmada 中,MultiClusterService 可以让用户通过原生 Service 域名(例如 foo.svc)跨集群访问服务,目的是让用户获得如在单个集群中访问服务般访问跨集群服务的流畅体验。📄 本文档提供了这样一个案例:启用 MultiClusterService 来通过原生 Service 跨集群访问服务。前提条件▍Karmada 已安装您可以参考快速入门安装 Karmada,或直接运行 hack/local-up-karmada.sh 脚本,该脚本也用于运行 E2E 测试。▍成员集群网络确保至少已有两个集群加入 Karmada,并且成员集群之间的容器网络已连通。如果您使用 hack/local-up-karmada.sh 脚本部署 Karmada,Karmada 中会有 3 个成员集群,并且集群 member1 和 member2 间的容器网络已连通。您可以使用 Submariner 或其他相关开源项目来连接成员集群之间的网络。📌 注意:为了防止路由冲突,集群中 Pod 和 Service 的 CIDR 必须互不重叠。▍在 karmada-controller-manager 中启用 MultiClusterService要在 karmada-controller-manager 中启用 MultiClusterService 功能,请运行以下命令:kubectl --context karmada-host get deploy karmada-controller-manager -n karmada-system -o yaml | sed '/- --v=4/i \ - --feature-gates=MultiClusterService=true' | kubectl --context karmada-host replace -f -📌 请注意,MultiClusterService 功能默认是禁用的,可以通过 --feature-gates=MultiClusterService=true 参数开启。如果您倾向于更谨慎的方法,请按照以下步骤操作:运行 kubectl --context karmada-host edit deploy karmada-controller-manager -n karmada-system。检查 spec.template.spec.containers[0].command 字段中是否存在 --feature-gates=MultiClusterService=true。如果没有,添加 --feature-gates=MultiClusterService=true 来开启功能。在 member1 集群中部署 Deployment我们需要在 member1 集群中部署 Deployment:apiVersion: apps/v1kind: Deploymentmetadata: name: nginx labels: app: nginxspec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - image: nginx name: nginx resources: requests: cpu: 25m memory: 64Mi limits: cpu: 25m memory: 64Mi---apiVersion: policy.karmada.io/v1alpha1kind: PropagationPolicymetadata: name: nginx-propagationspec: resourceSelectors: - apiVersion: apps/v1 kind: Deployment name: nginx placement: clusterAffinity: clusterNames: - member1部署完成后,您可以检查创建的 Pod:$ karmadactl get poNAME CLUSTER READY STATUS RESTARTS AGEnginx-5c54b4855f-6sq9s member1 1/1 Running 0 28snginx-5c54b4855f-vp948 member1 1/1 Running 0 28s在 member2 集群中部署 curl Pod让我们在 member2 集群中部署一个 curl Pod:apiVersion: apps/v1kind: Deploymentmetadata: name: curl labels: app: curlspec: replicas: 1 selector: matchLabels: app: curl template: metadata: labels: app: curl spec: containers: - image: curlimages/curl:latest command: ["sleep", "infinity"] name: curl resources: requests: cpu: 25m memory: 64Mi limits: cpu: 25m memory: 64Mi---apiVersion: policy.karmada.io/v1alpha1kind: PropagationPolicymetadata: name: curl-propagationspec: resourceSelectors: - apiVersion: apps/v1 kind: Deployment name: curl placement: clusterAffinity: clusterNames: - member2部署完成后,您可以检查创建的 Pod:$ karmadactl get po -C member2NAME CLUSTER READY STATUS RESTARTS AGEcurl-6894f46595-c75rc member2 1/1 Running 0 15s稍后,我们将在此 Pod 中执行 curl 命令。在 Karmada 中部署 MultiClusterService 与 Service现在,我们不使用 PropagationPolicy/ClusterPropagationPolicy,而是利用 MultiClusterService 来分发 Service。要在 Karmada 中启用 MultiClusterService,请部署以下 yaml:apiVersion: v1kind: Servicemetadata: name: nginxspec: ports: - port: 80 targetPort: 80 selector: app: nginx---apiVersion: networking.karmada.io/v1alpha1kind: MultiClusterServicemetadata: name: nginxspec: types: - CrossCluster consumerClusters: - name: member2 providerClusters: - name: member1从 member2 集群访问后端 Pod要从 member2 集群访问 member1 集群中的后端 Pod,请执行以下命令:$ karmadactl exec -C member2 curl-6894f46595-c75rc -it -- sh~ $ curl http://nginx.defaultHello, world!Version: 1.0.0Hostname: nginx-0在此案例中,Pod 仅位于 member1 集群。但是,使用 MultiClusterService,就可以通过原生 Service 域名从 member2 集群实现跨集群访问。更多Karmada云原生多云容器引擎使用教程与技术交流,欢迎关注Karmada社区公众号或添加社区小助手k8s2222,回复Karmada进群。 Karmada 公众号Karmada 是CNCF 首个多云多集群容器编排项目(孵化级),旨在帮助用户像使用单个集群一样轻松管理跨云多集群,让基于 Karmada 的多云方案无缝融入云原生技术生态。社区吸引了来自华为、道客、浙江大学、滴滴、腾讯、中国电子云等60多家公司的全球贡献者,广泛分布于22个国家和地区。Karmada 现已在华为云、道客、兴业数金、中国移动、中国联通、携程、360集团、新浪、中通快递等众多企业单位生产应用,为企业提供从单集群到多云架构的平滑演进方案。 Karmada官网:https://karmada.io/项目地址:cid:link_1Slack地址:https://slack.cncf.io/(#karmada)
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第三期2026/08/21 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;念擎-华为云AI开发者运营案例开发专家
本期直播内容:AI六层能力首次详细解读 + 新一代华为云开发者空间亮相 + 校园案例直播带练
即将直播
热门标签