调度器深入:打分、抢占与拓扑约束
调度器(kube-scheduler)是 Kubernetes 控制平面里最容易被低估的组件。它做的事情看起来简单:把没有 nodeName 的 Pod 绑定到某个节点。但"选哪个节点"这个问题背后,隐藏着资源感知、亲和性约束、拓扑分散、优先级抢占等多维度的决策过程。 从 Kubernetes 1.19 起,调度器的内部逻辑通过 Scheduling Framework 对外暴露为一组扩展点。原来散落在代码各处的调度逻辑被重新组织成插件,每个插件只负责一个扩展点。这让调度行为既可预测,又可扩展。 本文的核心问题是:Kubernetes 调度器用什么框架选节点,当资源不足时如何通过抢占让高优先级 Pod 运行? 调度框架全景图 1234567891011121314151617181920212223242526Pod pending (no nodeName) │ ▼ Scheduler(from ActiveQ by priority) ┌──────────────────────────────────────────────────...
Pod 生命周期:从 Pending 到 Running 的完整路径
一个 kubectl apply -f pod.yaml 之后,终端里出现了 pod/my-app created。这行输出只意味着 API Server 接受了资源定义并写入 etcd——Pod 还没有运行在任何节点上,甚至还没有被任何节点知晓。从这个瞬间到容器真正响应流量,Pod 经历了一条由多个组件接力完成的状态转换链。 这条链不是黑盒。Kubernetes 把每个阶段都编码进 status.phase、status.conditions、status.containerStatuses 三个字段里,并通过 Events 记录关键节点的时间戳。理解这条链,就能在 Pod 卡住时精确定位是调度失败、镜像拉取失败、探针失败,还是 OOM Kill。 本文的核心问题是:一个 Pod 从 kubectl apply 到 Running 经历了哪些状态转换,每个状态背后是哪个组件在操作? 状态转换全景图 12345678910111213141516171819202122232425kubectl apply │ ▼ etcd (Pod phase=Pending...
控制器模式与 Informer 机制:调谐循环的工程实现
Kubernetes 的控制平面由一批控制器组成,每个控制器负责把某种资源的实际状态收敛到期望状态。Deployment 控制器确保 ReplicaSet 数量正确,ReplicaSet 控制器确保 Pod 数量正确,StatefulSet 控制器维护有序 Pod 的标识和存储绑定。这些控制器全部运行在 kube-controller-manager 进程中,共享同一个 Go runtime,但逻辑上彼此独立。 控制器的核心模式是调谐循环(Reconcile Loop):读取资源当前状态,与期望状态对比,对差异执行操作,然后等待下一次触发。这个循环不是基于轮询的——每隔几秒查一次 etcd 的方式在规模上不可持续。实际实现依赖 Informer 机制:Informer 在本地维护一份与 etcd 同步的缓存,用 Watch 接收增量变更,把变更转换成事件分发给控制器。控制器从工作队列取出事件,执行 Reconcile,写回 API Server。 这篇的核心问题是:从 etcd 的一次写入,到控制器的一次 Reconcile 调用,中间经历了哪些层次,每层解决什么问题? Info...
etcd 与持久化:集群状态的唯一事实来源
上一篇讲完了 API Server 的请求管道。管道的终点是 etcd。这一篇进入 etcd 内部。 etcd 经常被简单地描述为"分布式 KV 存储"。这个描述成立,但掩盖了一个关键点:etcd 不是 Redis,也不是 Zookeeper,它是一个强一致的、以 Raft 为共识机制的、支持 Watch 的版本化存储。Kubernetes 之所以选择 etcd,正是因为这三个性质缺一不可——缺少任何一个,API Server 的 List-Watch 机制就无法建立在它之上。 本文只问一个问题:etcd 的哪些设计让 Kubernetes 的 List-Watch 机制成为可能? etcd 在集群中的位置 123456789101112131415161718192021┌─────────────────────────────────────────────────────┐│ Kubernetes Control Plane ││ ...
API Server 与声明式 API:一切皆资源
上一篇(核心概念导读)描述了 Kubernetes 的对象体系和控制器循环。这一篇进入 API Server 内部。API Server 不是普通的 HTTP 代理;它是整个集群的唯一写入路径,也是所有控制器、kubelet、用户工具共享的信息总线。 声明式 API 经常被描述为"说你想要什么,而不是怎么做"。这个描述准确,但不完整。Kubernetes 的声明式 API 背后有一套精确的语义:冲突检测、字段所有权、幂等写入。理解这些语义,才能解释为什么 kubectl apply 不是简单的 HTTP PUT。 本文只问一个问题:一个 apply 请求经过了哪些关卡? 请求管道全貌 一个 kubectl apply 请求从客户端到 etcd 的完整路径: 12345678910111213141516171819202122232425262728kubectl apply -f deployment.yaml │ │ HTTPS (mTLS) ▼┌─────────────────────────────────...
导读:为什么 Kafka 的核心是一根日志
Kafka 不是一个消息队列。更准确的说法是:Kafka 是一个分布式追加日志(append-only log)系统,消息队列的语义只是日志操作的一种投影。 本文只抓一个问题:追加日志这个数据结构,如何成为 Kafka 全部机制的起点。 追加日志:一种最朴素的数据结构 追加日志的定义可以压成三条规则: 写入只能追加到尾部(append)。 每条记录获得一个单调递增的序号(offset)。 已写入的记录不可修改(immutable)。 用 ASCII 表示一根日志的状态: 123456offset: 0 1 2 3 4 5 6 +----+----+----+----+----+----+----+ | m0 | m1 | m2 | m3 | m4 | m5 | | ← 写入点 +----+----+----+----+----+----+----+ ^ ...
从零配置 GitHub Actions 自动部署 Hexo 博客
Hexo 博客最容易卡住的地方,通常不是 hexo generate 本身,而是生成后的 public/ 怎么稳定发布。手动 hexo deploy 能跑,但它把构建环境、网络、Git 凭据都绑在本地机器上。换一台电脑、换一个网络、换一个 Node 版本,部署结果就可能变得不可预测。 更稳的做法是把部署流程写进仓库:源码仓库只保存 Markdown、主题配置、依赖锁和 workflow;每次 push 到 main,GitHub Actions 在云端安装依赖、生成静态站点,再把 public/ 推送到 GitHub Pages 仓库。 这篇文章记录从零配置这套流程的完整路径。例子以当前博客为准: 源码仓库:magicliang/hexo-blog 站点仓库:magicliang/magicliang.github.io Hexo 版本:8.1.2(Butterfly 5.x 主题) 包管理器:Yarn 1 构建命令:npx hexo clean && npx hexo generate 部署方式:peaceiris/actions-gh-pages@v4 推...
LeCun 视角下的数据瓶颈、电子果蝇与自主学习
LeCun 对 LLM 路线的批评,表面上常被说成“文本数据不够”。这个说法太浅。真正的问题不是网页快不够了,而是数据的形态、训练目标和学习闭环都不对。 更多文本可以让模型更会说,更多代码可以让模型更会写程序,更多用户交互可以让模型更会适应产品场景。但 human-level intelligence 需要的不只是更大的语料池。它需要系统从观察和行动中持续学习,能把失败转成经验,能把经验沉淀为世界模型,而不是部署后基本冻结。 电子果蝇看起来离 LLM 很远,其实刚好提供了一个反面参照:有连接图不等于有智能,有大模型不等于有世界模型。结构必须进入动态闭环,才能解释行为。 系列总纲见:LeCun 关于 LLM 与 AGI 的观点总集成。 文本数据瓶颈说的是什么 Villalobos 等人的《Will we run out of data?》估计,如果 LLM 按既有趋势继续扩大,训练数据需求会在 2026 到 2032 年间接近公共人类文本的可用存量。这个判断不是说“明天模型就没法训练”,而是指出公共高质量文本不可能无限增长。 Chinchilla scaling law 进一步强...
LeCun 视角下的 VLA、机器人与具身智能边界
Vision-Language-Action,VLA,是 LLM/VLM 路线进入机器人之后最自然的形态:模型看见图像,读懂指令,然后输出动作。RT-2、OpenVLA、π0、FAST 这一串工作证明,大规模视觉语言预训练确实能把语义知识迁移到机器人控制里。 但从 LeCun 的标准看,VLA 还不是完整答案。它解决了一部分“语言如何接到动作”的问题,却没有彻底解决“系统如何预测行动后果、如何在内部比较多个未来、如何从失败中更新世界模型”的问题。 这篇把 VLA 放到 LeCun 的世界模型路线里看:它很重要,但更像 actor、接口或快速反应层,不像具身 AGI 的中枢。 系列总纲见:LeCun 关于 LLM 与 AGI 的观点总集成。 VLA 为什么突然重要 机器人长期有一个老问题:低层控制可以很强,但语义泛化很弱。传统机器人系统可以把一个固定零件从固定位置抓到固定盒子里,却很难理解“把苹果放到数字 3 上”“拿起能当锤子的东西”“把桌面收拾干净”这种开放语言指令。 大规模 VLM 改变了这件事。互联网图文数据里包含大量对象、属性、关系、用途和场景知识。VLA 的基本想法是...
LeCun 视角下的 LLM 边界:贝叶斯推断与因果问题
LeCun 说 LLM 不是通往人类级智能的主路,最容易被误读成一句情绪判断。真正值得展开的是技术边界:LLM 到底能推断什么,不能推断什么;它的上下文学习为什么像贝叶斯推断;它为什么又不是一台真正的世界后验机器;它能处理因果话语,为什么仍然缺少可行动的因果模型。 这篇把 LeCun 对 LLM 的批评放到三个层面上:语言分布、贝叶斯式上下文学习、因果与规划。这样看,LLM 的强大和边界可以同时成立。 系列总纲见:LeCun 关于 LLM 与 AGI 的观点总集成。 LeCun 批评的不是“统计” 许多反驳 LeCun 的说法会走向一个靶子:LLM 当然不只是背语料,它们会泛化、会推理、会写代码、会在上下文中学新任务。这个反驳本身没错,但它没有击中 LeCun 的重点。 LeCun 并不否认统计学习很强。深度学习本身就是统计学习。LLM 的成功也确实说明,大规模自监督学习能从文本里抽出大量结构。问题在于:这种结构主要落在语言和陈述性知识空间里,而不是落在可行动的世界状态空间里。 换成训练目标,就是这条公式: 1pθ(next token | context) 自回归 LLM 学...
