云原生运维【免费下载链接】deschedulerDescheduler for Kubernetes项目地址https://gitcode.com/gh_mirrors/de/descheduler点击查看免费下载导读PodLifeTime 是 Kubernetes descheduler 框架中一个高度灵活的 Deschedule 插件它不依赖节点资源利用率而是完全以 Pod 自身的年龄 状态 状态迁移时间为判断依据决定哪些 Pod 该被驱逐。本文以插件官方文档pkg/framework/plugins/podlifetime/README.md为主体结合仓库源码、示例配置与单元/E2E 测试完整讲解其过滤链组合逻辑、全部参数语义、经典使用场景与可直接复用的 DeschedulerPolicy 配置帮助你在集群中实现到期轮换、残留清理、故障回收三类最常见的 Pod 生命周期治理。插件定位在 Descheduler 框架中的角色PodLifeTime 被注册为Deschedule 扩展点插件。在 pkg/descheduler/setupplugins.go 中插件以podlifetime.PluginName即PodLifeTime注册进默认插件注册表并绑定了参数类型PodLifeTimeArgs、校验函数ValidatePodLifeTimeArgs与默认值函数SetDefaults_PodLifeTimeArgspluginregistry.Register(podlifetime.PluginName, podlifetime.New, podlifetime.PodLifeTime{}, podlifetime.PodLifeTimeArgs{}, podlifetime.ValidatePodLifeTimeArgs, podlifetime.SetDefaults_PodLifeTimeArgs, registry)因此在使用时PodLifeTime 必须出现在策略文件的plugins.deschedule.enabled列表中而不是balance或filter等其他扩展点。其核心实现位于 pkg/framework/plugins/podlifetime/pod_lifetime.go参数类型定义在 pkg/framework/plugins/podlifetime/types.go。工作原理过滤链的 AND/OR 组合语义PodLifeTime 的判定逻辑可以概括为一句话所有非空的过滤类别之间是 AND 关系Pod 必须满足每一个已配置的过滤条件才会被驱逐每个过滤类别内部是 OR 关系命中其中任意一项即可满足该类别。源码中 New() 通过podutil.WrapFilterFuncs把各个条件逐一串成一条过滤链命名空间过滤include/exclude与labelSelector是插件级的通用前置过滤与驱逐器的Filter/PreEvictionFilter一并组合maxPodLifeTimeSecondsPod 年龄大于该秒数才通过states任一匹配即通过ORownerKinds按 OwnerReference 的 Kind 做 include/excludeconditions任一条件过滤器命中即通过ORexitCodes任一容器终止退出码匹配即通过OR。最终所有过滤器叠加后Pod 必须全部通过才能进入驱逐候选列表。该语义与项目根文档 README.md 中All non-empty filter categories are ANDed…Within each category, items are ORed的描述完全一致。排序与驱逐最老优先、限额即止候选 Pod 确定后插件调用 SortPodsBasedOnAgepkg/descheduler/pod/pods.go按CreationTimestamp升序原地排序保证最老的 Pod 先被驱逐随后在 Deschedule() 中逐个调用handle.Evictor().Evict()执行驱逐。驱逐循环对两种限额错误做了专门处理pkg/framework/plugins/podlifetime/pod_lifetime.go#L179-L193EvictionNodeLimitError单节点驱逐上限已满continue跳过当前节点继续尝试其他节点上的 PodEvictionTotalLimitError全局总驱逐上限已满直接停止整个插件执行。这些限额maxPodsToEvictPerNode、maxPodsToEvictPerNamespace、maxPodsToEvictTotal由驱逐器在 pkg/descheduler/evictions/evictions.go 中统一强制total 与 per-node 上限在EvictPod内检查并返回对应错误类型PodLifeTime 只需消费它们即可无需自己实现限额逻辑。注Pod 的 PDBPod Disruption Budget约束同样由驱逐器层负责PodLifeTime 不绕过 PDB驱逐请求会正常受 PDB 保护。参数总览下表完整列出了插件支持的配置参数字段名、语义与 types.go 一致参数说明类型必填默认maxPodLifeTimeSeconds年龄超过该秒数的 Pod 才会被驱逐uint否*nilstates按 Pod phase、Pod status reason、容器 waiting/terminated reason 过滤命中任一即匹配[]string否nilconditions仅驱逐满足状态条件见 PodConditionFilter的 Pod[]PodConditionFilter否nilexitCodes仅驱逐存在匹配容器终止退出码的 Pod[]int32否nilownerKinds按 OwnerReference 的 Kind 做 include/excludeOwnerKinds否nilnamespaces限定驱逐的命名空间include 或 excludeNamespaces否nillabelSelector仅驱逐匹配这些标签的 Podmetav1.LabelSelector否nilincludingInitContainers将 state/exitCode 过滤扩展到 init 容器bool否falseincludingEphemeralContainers将 state 过滤扩展到 ephemeral 容器bool否false* 至少需要指定一个过滤条件maxPodLifeTimeSeconds、states、conditions或exitCodes之一否则参数校验失败。这条至少一个过滤条件的硬性校验在 validation.go 中实现同时校验还包括namespaces 与 ownerKinds 的 include/exclude 互斥、labelSelector 合法性、states 取值白名单、conditions 每条至少设置一个字段。defaults.gopkg/framework/plugins/podlifetime/defaults.go目前保持各字段默认 nil/false 不变即所有过滤维度默认关闭未配置即不参与判定。states 字段详解四类状态的 OR 匹配states是 PodLifeTime 最核心的过滤维度。它按OR语义同时匹配四类状态任一命中即通过见 pod_lifetime.go类别取值示例Pod phaseRunning、Pending、Succeeded、Failed、UnknownPod status reasonNodeAffinity、NodeLost、Shutdown、UnexpectedAdmissionError容器 waiting reasonCrashLoopBackOff、ImagePullBackOff、ErrImagePull、CreateContainerConfigError、CreateContainerError、InvalidImageName、PodInitializing、ContainerCreating容器 terminated reasonOOMKilled、Error、Completed、DeadlineExceeded、Evicted、ContainerCannotRun、StartError上述全部取值由 validation.go 中的podLifeTimeAllowedStates白名单强制约束states 中不允许出现白名单之外的值否则校验直接报错。底层匹配由 pkg/descheduler/pod/pods.go 中的HasMatchingContainerWaitingState/HasMatchingContainerTerminatedState辅助函数完成逐条检查容器的State.Waiting.Reason与State.Terminated.Reason是否命中集合。当includingInitContainers为true时InitContainerStatuses的 waiting/terminated reason 也会参与匹配当includingEphemeralContainers为true时EphemeralContainerStatuses同样参与。单元测试 pod_lifetime_test.go 验证了未开启这两个开关时init/ephemeral 容器的CreateContainerError不会被匹配预期驱逐数为 0开启后则能被驱逐预期驱逐数为 1。conditions按状态条件与迁移时间精细过滤conditions允许你针对pod.status.conditions[]做精确匹配非常适合清理已 Succeeded 但残留过久的场景。PodConditionFilter 字段单个条件过滤器内的字段级匹配是AND所有已设置字段必须同时命中未设置的字段不参与检查多个条件过滤器之间是OR——Pod 的任一 condition 满足任意一个过滤器即被驱逐实现见 pod_lifetime.go 的matchesAnyPodConditionFilter与matchesConditionFields字段说明type条件类型如Ready、Initialized、ContainersReadystatus条件状态True、False、Unknownreason条件原因如PodCompletedminTimeSinceLastTransitionSeconds要求匹配条件的lastTransitionTime距今至少该秒数校验规则validation.go每条过滤器至少设置type/status/reason/minTimeSinceLastTransitionSeconds之一否则校验失败。迁移时间语义重点当设置了minTimeSinceLastTransitionSeconds时Pod 的条件必须同时满足 type/status/reason 字段匹配且其lastTransitionTime必须足够久远若该 condition 没有lastTransitionTime零值则视为不匹配。源码逻辑pod_lifetime.goif f.MinTimeSinceLastTransitionSeconds ! nil { if cond.LastTransitionTime.IsZero() { continue } idle : metav1.Now().Sub(cond.LastTransitionTime.Time) if idle 0 || uint(idle.Seconds()) *f.MinTimeSinceLastTransitionSeconds { continue } } return true测试 TestTransitionTimeFiltering 覆盖了三个关键行为2 小时前的旧迁移时间可驱逐、1 分钟前的新迁移时间不可驱逐、迁移时间检查只作用于匹配字段命中的那条 condition另一条 reason 不匹配的 condition 即便迁移时间很新也不影响判定。ownerKinds按控制器类型定向驱逐ownerKinds通过 Pod 的 OwnerReference 的Kind字段做 include/exclude见 pod_lifetime.go字段说明include仅驱逐由这些 Kind 拥有的 Podexclude不驱逐由这些 Kind 拥有的 Podinclude与exclude最多只能设置一个validation.go 强制。测试 TestOwnerKindsFiltering 验证exclude: [Job]时 Job 拥有的 Failed Pod 不被驱逐、非 Job Pod 正常驱逐include: [Job]时只有 Job Pod 被驱逐。典型价值Job 控制器自身会清理已结束的 Pod因此驱逐器通常应该排除 Job 拥有的 Pod避免与 Job 的清理逻辑重复而 ReplicaSet/DaemonSet 等长期运行的控制器则希望被驱逐后由控制器重建。典型使用场景可直接复用以下场景配置全部来自官方 README字段语义与前述参数一一对应。场景一清理闲置过久的 Succeeded Podargs: states: [Succeeded] conditions: - reason: PodCompleted status: True minTimeSinceLastTransitionSeconds: 14400 # 4 hours仅当 Pod 处于Succeeded阶段且存在reasonPodCompleted、statusTrue的 condition且该 condition 的迁移时间距今超过 4 小时才会被驱逐。场景二驱逐 Failed Pod 但排除 Job 拥有的args: states: [Failed] exitCodes: [1] ownerKinds: exclude: [Job] maxPodLifeTimeSeconds: 3600 includingInitContainers: trueFailed Pod 同时满足存在退出码为 1 的已终止容器含 init 容器且年龄超过 1 小时且不属于 Job才被驱逐。exitCodes匹配实现在 pod_lifetime.go测试 TestExitCodesFiltering 验证了命中与未命中两种情形。场景三资源泄漏缓解——定期重启长驻 Podargs: maxPodLifeTimeSeconds: 604800 # 7 days states: [Running]长期运行的 Pod 可能积累内存泄漏本配置让运行超过 7 天的 Running Pod 被驱逐并由控制器重建实现到期轮换。场景四清理 CrashLoopBackOff / ImagePullBackOff 卡死 Podargs: states: [CrashLoopBackOff, ImagePullBackOff]states列表内部是 OR 语义命中任一 waiting reason 即可被驱逐用于快速回收陷入镜像拉取/启动循环的故障 Pod。场景五仅驱逐特定控制器拥有的 Podargs: states: [Succeeded, Failed] ownerKinds: include: [Job] maxPodLifeTimeSeconds: 600只对 Job 拥有的 Succeeded/Failed Pod 生效且要求其存活超过 600 秒适合对已完成但未及时清理的 Job Pod 做兜底回收。完整 DeschedulerPolicy 配置示例示例 A按年龄 状态过滤驱逐1 天轮换apiVersion: descheduler/v1alpha2 kind: DeschedulerPolicy profiles: - name: default plugins: deschedule: enabled: - name: PodLifeTime pluginConfig: - name: PodLifeTime args: maxPodLifeTimeSeconds: 86400 # 1 day states: - Running namespaces: include: - default示例 B基于状态迁移时间的精细驱逐Succeeded 残留 4 小时apiVersion: descheduler/v1alpha2 kind: DeschedulerPolicy profiles: - name: default plugins: deschedule: enabled: - name: PodLifeTime pluginConfig: - name: PodLifeTime args: states: - Succeeded conditions: - reason: PodCompleted status: True minTimeSinceLastTransitionSeconds: 14400 namespaces: include: - default该配置的效果default命名空间中处于Succeeded阶段、带有PodCompletedTrue条件、且该条件最后迁移时间距今超过 4 小时的 Pod 会被驱逐。仓库还提供了两个可直接套用的独立示例文件examples/pod-life-time.yml7 天年龄 Pending/PodInitializing 状态与 examples/pod-life-time-transition.ymlSucceeded PodCompleted 4 小时迁移阈值均以descheduler/v1alpha2API 版本编写可作为--policy-config-file的输入。命令行运行与验证按 docs/user-guide.md 的Balance Cluster By Pod Age用例可通过 CLI 直接加载策略文件运行descheduler -v3 --evict-local-storage-pods --policy-config-filepod-life-time.yml该命令以-v3开启详细日志--evict-local-storage-pods允许驱逐挂载本地存储的 Pod并加载包含maxPodLifeTimeSeconds: 604800的PodLifeTime策略文件即上述7 天轮换配置。文档同时建议为每个业务应用配置 Pod Disruption BudgetPDB以保证驱逐不会导致应用可用性受损。测试与可靠性依据单元测试pkg/framework/plugins/podlifetime/pod_lifetime_test.go约 1367 行覆盖年龄阈值边界605 秒驱逐 / 595 秒不驱逐见TestPodLifeTime_AgeThreshold、各 phase 状态、全部 waiting reason、Pod status reason、init/ephemeral 容器开关、条件过滤、迁移时间过滤、ownerKinds、exitCodes、组合过滤以及驱逐限额per-node / per-namespace / total下的最老优先行为。参数校验测试validation_test.go 验证了无任何过滤条件时报错非法 state 报错并列出完整白名单include/exclude 互斥空 condition 过滤器报错等规则。默认值测试defaults_test.go 确认空参数时各字段保持 nil。E2E 测试test/e2e/e2e_podlifetime_test.go 在真实集群中用 Job 制造 Failed/Succeeded Pod验证States: [Failed]可驱逐、OwnerKinds.Exclude: [Job]不驱逐 Job Pod、Conditions命中与不命中两种结果。这些测试共同锁定了本文所述的所有参数语义与边界行为可作为你自行验证配置时的参照。小结PodLifeTime 的价值在于把时间这一维度引入了驱逐决策从简单的按年龄驱逐到精确到某个状态条件已迁移超过 N 秒的细粒度回收再到按控制器类型、命名空间、标签、退出码的组合筛选它都能在不触碰运行良好 Pod 的前提下完成集群的新陈代谢。配置时请牢记三条准则至少指定一个过滤条件、类别间 AND / 类别内 OR、为关键应用配置 PDB。赞分享云原生运维【免费下载链接】deschedulerDescheduler for Kubernetes项目地址https://gitcode.com/gh_mirrors/de/descheduler点击查看免费下载相关推荐iTerm2-Color-Schemes 完整指南605 款终端配色一键导入与切换教程iTerm2 Color Schemes 完整指南605 款终端配色一键导入与切换教程 刚拿到一台 Mac、装好 iTerm2 的开发者最常见的动作就是去搜开发工具Android Activity 生命周期全解析基于 android-training-course-in-chinese 的回调机制、状态迁移与实例状态保存实战Android Activity 生命周期全解析基于 android training course in chinese 的回调机制、状态迁移与实例状态保存文档教程移动开发Kubernetes Pod 状态与生命周期管理从构成、相位到探针与重启策略的完整实战指南Kubernetes Pod 状态与生命周期管理从构成、相位到探针与重启策略的完整实战指南 Pod 是 Kubernetes 中最小的调度与部署单元理解它的教程云原生容器编排上一篇Thornvigil 战斗动画实战参考运动文件布局、回归测试套件与实机测量工具链下一篇原神数据本地化管理胡桃工具箱 Snap.Hutao 完整使用指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考