文章历史示例:节点报告可分配 10 个 CPU。请求 10m、限制 11 CPU 的 Pod 已放置;请求 11 CPU、限制相同的 Pod 保持 Pending。其他放置条件仍适用。

调度器计算资源请求,而不是瞬时使用率

Kubernetes 调度判断的是 Pod 在资源请求和其他放置约束下是否适合某个节点,不是简单查看当前 CPU 曲线,然后把任务塞进看起来最空闲的位置。请求为未来需求提供记账输入,实际使用率则是另一种观测。决定一个表面空闲的集群是否有能力容纳特定 Pod 之前,需要同时理解两者,不能让其中一个指标替代全部容量判断。 读取准入后的请求。API 拒绝、已创建但 Pending,以及成功放置,属于不同阶段。 以准入后的真实配置为依据 对于普通应用容器,调度器在判断节点是否容纳 Pod 时,会计算它们的请求。初始化需求、Pod 额外开销以及受支持的 Pod 级资源配置,也可能影响有效请求。最终经过准入的 Pod 才是实际输入,包括默认值和修改结果,而不只是操作者记得提交的源文件。排查时应读取保存下来的对象,确认控制面实际看到什么。 Node allocatable 也不同于硬件总容量,它表示按照节点配置可以提供给 Pod 的资源量。其他工作负载即使暂时空闲,其资源请求仍然占用调度记账中的空间。不过,请求并不表示应用已经实际分配了同样多的物理内存,也不表示独占相应数量的 CPU 核心。放置记账、实时消耗和独占策略属于不同机制,不能混用“预留”一词解释。 ...

四月 2, 2028 · 3 分钟 · XB Field Notes
CronJob 默认最多保留三个成功 Job 和一个失败 Job;Job TTL 独立控制年龄。任一机制都可能删除已结束 Job。

Kubernetes CronJob 需要历史清理策略

CronJob 按计划创建 Job,再由 Job 管理真正执行工作的 Pod。完成后的对象可以保留有用状态,但保留量受到多种独立机制影响。尤其要注意,CronJob 本来就有默认历史上限;省略显式历史字段,并不意味着普通已完成运行会无限堆积。分析清理问题时,先分清对象类型与状态,再判断是哪项机制没有覆盖。 当另一机制允许更早删除时,数量与 TTL 都不保证最低保留时长。清理是异步的,活动任务限制也不证明业务可安全重试。本轮未重跑保留诊断。 历史记录不等于日志归档 CronJob 默认最多保留三个成功 Job 和一个失败 Job,控制器分别协调两类记录。某类上限设为零,表示不保留该类历史,但清理是异步过程,不是任务结束那个瞬间必然消失。仍在运行的 Job 不属于完成历史,需要单独观察,不能期待这两个数量上限替它们设置运行期限。 三十天每小时一次意味着七百二十个计划机会,不一定保留七百二十个 Job,更不一定恰好产生相同数量的 Pod。错过调度、并发策略、重试与并行度都会改变关系,一个 Job 也可能拥有多个 Pod。用运行次数估算存储或控制面容量之前,应把这些假设说清楚,不能把理想时间表直接当成当前对象数量。 Pod 对象仍在,也不保证容器日志仍然可读。节点故障、日志轮转、容器清理和驱逐都会影响访问。真正需要按时长保留的证据,应交付到合适的日志系统。Kubernetes 对象便于调查状态,但不能替代归档保证;只延长 Job 历史,不会自动解决节点日志的生命周期问题。 ...

二月 25, 2028 · 1 分钟 · XB Field Notes
用户任务表的五个日历字段之后直接是命令;系统任务表还要先写账号字段。

Cron 系统任务表与用户任务表有不同契约

Cron 可以从不止一种任务表读取计划。用户任务表属于某个账号,而系统任务表能够为每一条记录指定运行账号。把一行原样复制到另一种表中,如果没有调整字段,cron 对命令起点的理解就会变化。排查看似正确的五字段日历表达式之前,应先确认正在编辑的到底是哪种任务表,而不是只检查分钟和小时。 Debian 用户表在五个字段后开始命令,系统表则先增加用户名。未转义百分号先于 shell 引号处理,并分离标准输入。本图为示意图;没有执行需要特权的示例。 账号列改变了解析边界 传统用户记录依次填写分钟、小时、月内日期、月份、星期,再接命令正文,由 crontab 命令安装给选定用户。Debian 的 /etc/crontab 和 /etc/cron.d 下文件,则在五个日历字段之后额外增加用户名。这个用户名属于系统表格式,并不是可以随意放进用户任务表的说明性字段;多写或少写都会改变后续解释。 月份限制仍然必须满足。当月内日期与星期都受到限制时,Debian/Vixie 的日期规则允许满足其中之一,但月份与星期并不是二选一。把表达式迁移到带秒字段或采用其他日期组合方式的调度产品前,应核对具体方言。表面上相似的空格布局,不能证明两个调度器提供相同语义。 系统任务文件还受所有权、权限、名称及末尾换行要求约束。Debian 中应采用 root 所有、组和其他用户不可写且名称被接受的文件,不要把任意备份后缀当成有效任务名。/etc/cron.daily 等周期目录通常通过发行版安排和 run-parts 被调用,不是每份脚本都独立当作 crontab 解析。实际运行时间需要查看本机已安装的调度安排。 坏掉的样子 在 root 用户自己的任务表中,五字段后再写 root,意味着让 shell 执行一个名为 root 的命令。任务表安装成功,不证明这个命令存在。反过来,系统表漏掉账号列,就会把命令文字当成用户名。审阅时需要同时检查解析边界与最终身份,尤其是任务会写文件或读取受保护数据时,不能仅凭“都是 root 配置的”推断执行账号。 任务环境同样是一份契约。不要默认交互别名、shell 启动文件或启动 cron 的父进程环境都会传给任务。需要的值应明确配置,同时选择合适的 PATH 和解释器。cron.d 文件中的环境也不应被认为自动继承 /etc/crontab 中的设置。验证时要采用真正的运行账号检查权限与输出,避免管理员手工执行成功掩盖低权限任务失败。 ...

一月 12, 2028 · 5 分钟 · XB Field Notes
对于 storage=nvme 标签规则,必要亲和排除不匹配节点;偏好亲和为匹配节点加分,不匹配节点仍可能是候选。其他约束仍须通过。

节点亲和把工作负载放到合适的节点

节点亲和把工作负载的要求与节点标签匹配起来。它可以要求 NVMe 存储,也可以偏好较新的机型,但不会代替调度器的其他检查。即使没有亲和规则,调度器也会先按资源请求、污点、存储卷约束等条件筛选,再给可行节点评分,并非只比较此刻的空闲容量。 GPU 放置说明了这一区别:通过设备插件声明 GPU 扩展资源请求,才能把设备数量纳入资源适配;加速器标签可以进一步选择型号。标签本身不会分配 GPU,容忍污点也既不请求设备,又不要求一定进入专用池。必须分别表达资源需求、放置要求和允许进入哪些节点。 必要亲和按标签过滤。偏好亲和参与可行节点评分,两者单独都不保证成功放置。 按标签匹配节点 accelerator=nvidia-a100、storage=nvme 等标签描述的属性,需要节点供给流程建立并持续维护。替换节点不会自动继承旧节点的任意标签。应先确认新硬件确有这些属性,再附上旧标签;否则规则在形式上匹配,实际选到的机器却不适合业务。 把标签词表当作 API 管理。重命名一个键会影响所有引用它的清单,过时的值则可能错误描述硬件。校验配置时要对照预期节点清单,包括计划扩容但还未上线的容量。某个标签暂时不存在,可能是供给过程未完成或整个节点池暂时缺席,不一定只是拼写错误。不要让静态校验把这些不同原因混成同一个结论。 隔离还依赖标签完整性。Kubernetes 1.34 文档建议结合 Node authorizer、NodeRestriction 准入插件和受保护的 node-restriction.kubernetes.io/ 标签键。普通的节点自报合规标签并不是独立安全边界。需要明确谁能修改标签,以及谁能修改工作负载的放置要求;字符串匹配不能代替这些权限检查。 偏好还是强制 requiredDuringSchedulingIgnoredDuringExecution 排除不满足规则的节点;preferredDuringSchedulingIgnoredDuringExecution 为可行节点增加带权偏好,其他评分仍可能胜出。两种形式都不保证剩余容量、应用健康或故障韧性。必要条件可能让 Pod 保持 Pending;偏好允许落到不匹配的节点,但所有硬约束仍须通过。 ...

十二月 9, 2027 · 1 分钟 · XB Field Notes
请求指向节点容量匹配。CPU 上限指向节流和等待;内存上限指向回收和可能的 OOM。

Requests 参与放置,limits 约束资源消耗

Requests 参与放置和资源共享,limits 约束运行时消耗。它们是有关联的输入,不是对应用性能的一套通用下限与上限保证。应结合负载行为、争用风险和恢复要求选择,并查看准入后的 Pod,因为默认值与策略可能改变清单里提交的资源值。先区分记账、实际使用和执行约束,才能解释配置为什么影响行为。 解释放置前先读准入后的请求。CPU 节流和内存压力具有不同机制,需要关联证据;资源字段都不保证应用性能。 默认值也是契约的一部分 某资源只有 limit、没有 request 时,如果准入没有提供另一请求,Kubernetes 会把限制复制为请求。因此,只配 limit 通常不是零调度成本。LimitRange 默认值与 ResourceQuota 检查也会影响准入。解释 Pod 为什么 Pending 之前,应读取实际保存的两张资源映射,不能仅凭源文件中某一字段缺失进行判断。 Request 不会预先分配应用的物理内存,也不必然独占 CPU 核心。CPU 请求参与调度及争用时的相对份额。没有 CPU limit 的容器可以利用超过请求的空闲 CPU,但节点容量、祖先约束和竞争负载仍然构成边界。省略限制可能是有意选择,应配套明确容量和争用策略,而不是简单认定只配一边必然错误。 Linux 上 CPU limit 通常通过带宽节流执行,耗尽配额本身不会直接杀死进程。但等待可能增加延迟、触发应用超时或影响探针。整机 CPU 平均值低,也不能排除某个上限很紧的容器正在频繁节流。要比较对应时间窗口的需求、配额和等待,而不是拿整机平均值替代容器约束。 ...

五月 27, 2027 · 1 分钟 · XB Field Notes
在强制 hostname 反亲和且九个副本互相选中的条件下,六个合格主机域各有一个同伴,三个副本仍为 Pending。

Pod 反亲和把选中的同伴分散放置

Pod 反亲和表达一个 Pod 应该避开哪些选中的同伴。主机拓扑可以减少共用节点的风险,可用区拓扑可以覆盖更大的故障域。规则不会创造额外容量,也不能证明应用已经具备高可用性;它负责影响落点,复制机制、就绪、存储与故障恢复仍然有各自职责。三个副本分开只是减少共同故障的一步,并非完整恢复方案。 强制规则过滤候选节点,偏好规则贡献评分。如果硬条件没有留下可行节点,新 Pod 会持续 Pending,直到相关条件改变。对严格隔离要求而言,这可能是正确结果,但必须提前计入容量规划,而不是在故障时才发现“不允许同处”的代价。偏好则允许权衡,不应被描述成几乎等同于硬性分离。 强制反亲和让选中的同伴避开已经占用的拓扑域;拓扑分布则限制候选放置的数量差。两者都依赖选择器、命名空间范围、合格域和其他约束。 选中同伴,再定义拓扑域 labelSelector 识别同伴 Pod,topologyKey 指定用哪个节点标签划分它们所在的位置。kubernetes.io/hostname 通常区分节点,topology.kubernetes.io/zone 按可用区分组。应查看真实标签值,不要假定不同基础设施提供者都自动具备同一套标签;键存在但值错误,同样可能让故障域定义失真。 ...

三月 18, 2027 · 1 分钟 · XB Field Notes
对于未被容忍的污点,NoSchedule 阻止新的普通调度而保留已绑定 Pod;PreferNoSchedule 软性避让而保留已有 Pod;NoExecute 阻止新调度,还可能驱逐已绑定 Pod。

污点会排斥那些不打算容忍它的 Pod

污点排斥没有容忍对应效果的 Pod,容忍度只移除这项障碍,不会强制把负载送到专用硬件。专用节点设计通常还需要标签与必要的节点亲和,再分别检查容量和准入策略。不能把通行资格理解成目的地保证,也不能把容忍度当成工作负载的完整权限边界。 容忍度移除匹配污点这一项障碍。效果决定后果,放置与权限仍是其他机制。 给专用者的标记 NoSchedule 污点在未被容忍时,阻止普通的新调度,但不移动已有 Pod。这可以把 GPU 等专用节点留给特定负载。不能进一步概括为所有污点都不影响运行中程序:NoExecute 具有驱逐行为,PreferNoSchedule 则只是调度偏好。首先看清 effect,才能判断这次变更会影响新放置还是已有实例。 污点不是安全隔离。有权提交合适容忍度的主体可能获得池子资格,直接指定 nodeName 还会绕过普通调度检查。准入限制、授权和设备资源请求是另外的控制;一个 GPU 容忍度既没有请求 GPU,也不保证有空闲 GPU。审阅专用池时,需要同时核对谁能修改模板、谁能添加容忍度以及真正需要哪些硬件资源。 效果决定行为 NoSchedule 对未容忍的 Pod 构成硬性调度排除;PreferNoSchedule 提供软性避让偏好,单靠它不会让节点完全失去资格。NoExecute 还可能移除已经绑定、却没有匹配容忍度的 Pod。匹配 NoExecute 的容忍度可以带 tolerationSeconds,限定污点出现之后还能停留多久;不写时长与设置短时长具有不同后果。 ...

二月 25, 2027 · 2 分钟 · XB Field Notes