深入分析Kubernetes Critical Pod(二)
深入分析Kubernetes Critical Pod(一)介绍了Scheduler对Critical Pod的处理逻辑,下面我们再看下Kubelet Eviction Manager对Critical Pod的处理逻辑是怎样的,以便我们了解Kubelet Evict Pod时对Critical Pod是否有保护措施,如果有,又是如何保护的。
Kubelet Eviction Manager Admit
kubelet在syncLoop中每个1s会循环调用syncLoopIteration,从config change channel | pleg channel | sync channel | houseKeeping channel | liveness manager's update channel
中获取event,然后分别调用对应的event handler进行处理。
- configCh: dispatch the pods for the config change to the appropriate handler callback for the event type
- plegCh: update the runtime cache; sync pod
- syncCh: sync all pods waiting for sync
- houseKeepingCh: trigger cleanup of pods
- liveness manager's update channel: sync pods that have failed or in which one or more containers have failed liveness checks
特别提一下,houseKeeping channel是每隔houseKeeping(10s)时间就会有event,然后执行HandlePodCleanups,执行以下清理操作:
- Stop the workers for no-longer existing pods.(每个pod对应会有一个worker,也就是goruntine)
- killing unwanted pods
- removes the volumes of pods that should not be running and that have no containers running.
- Remove any orphaned mirror pods.
- Remove any cgroups in the hierarchy for pods that are no longer running.
pkg/kubelet/kubelet.go:1753func (kl *Kubelet) syncLoopIteration(configCh <-chan kubetypes.PodUpdate, handler SyncHandler,syncCh <-chan time.Time, housekeepingCh <-chan time.Time, plegCh <-chan *pleg.PodLifecycleEvent) bool {select {case u, open := <-configCh:if !open {glog.Errorf("Update channel is closed. Exiting the sync loop.")return false}switch u.Op {case kubetypes.ADD:handler.HandlePodAdditions(u.Pods)...case kubetypes.RESTORE:glog.V(2).Infof("SyncLoop (RESTORE, %q): %q", u.Source, format.Pods(u.Pods))// These are pods restored from the checkpoint. Treat them as new// pods.handler.HandlePodAdditions(u.Pods)...}if u.Op != kubetypes.RESTORE {...}case e := <-plegCh:...case <-syncCh:...case update := <-kl.livenessManager.Updates():...case <-housekeepingCh:...}return true
}
syncLoopIteration中定义了当kubelet配置变更重启后的逻辑:kubelet会对正在running的Pods进行Admission处理,Admission的结果有可能会让该Pod被本节点拒绝。
HandlePodAdditions就是用来处理Kubelet ConficCh中的event的Handler。
// HandlePodAdditions is the callback in SyncHandler for pods being added from a config source.
func (kl *Kubelet) HandlePodAdditions(pods []*v1.Pod) {start := kl.clock.Now()sort.Sort(sliceutils.PodsByCreationTime(pods))for _, pod := range pods {...if !kl.podIsTerminated(pod) {...// Check if we can admit the pod; if not, reject it.if ok, reason, message := kl.canAdmitPod(activePods, pod); !ok {kl.rejectPod(pod, reason, message)continue}}...}
}
如果该Pod Status不是属于Terminated,就调用canAdmitPod对该Pod进行准入检查。如果准入检查结果表示该Pod被拒绝,那么就会将该Pod Phase设置为Failed。
pkg/kubelet/kubelet.go:1643func (kl *Kubelet) canAdmitPod(pods []*v1.Pod, pod *v1.Pod) (bool, string, string) {// the kubelet will invoke each pod admit handler in sequence// if any handler rejects, the pod is rejected.// TODO: move out of disk check into a pod admitter// TODO: out of resource eviction should have a pod admitter call-outattrs := &lifecycle.PodAdmitAttributes{Pod: pod, OtherPods: pods}for _, podAdmitHandler := range kl.admitHandlers {if result := podAdmitHandler.Admit(attrs); !result.Admit {return false, result.Reason, result.Message}}return true, "", ""
}
canAdmitPod就会调用kubelet启动时注册的一系列admitHandlers对该Pod进行准入检查,其中就包括kubelet eviction manager对应的admitHandle。
pkg/kubelet/eviction/eviction_manager.go:123// Admit rejects a pod if its not safe to admit for node stability.
func (m *managerImpl) Admit(attrs *lifecycle.PodAdmitAttributes) lifecycle.PodAdmitResult {m.RLock()defer m.RUnlock()if len(m.nodeConditions) == 0 {return lifecycle.PodAdmitResult{Admit: true}}if utilfeature.DefaultFeatureGate.Enabled(features.ExperimentalCriticalPodAnnotation) && kubelettypes.IsCriticalPod(attrs.Pod) {return lifecycle.PodAdmitResult{Admit: true}}if hasNodeCondition(m.nodeConditions, v1.NodeMemoryPressure) {notBestEffort := v1.PodQOSBestEffort != v1qos.GetPodQOS(attrs.Pod)if notBestEffort {return lifecycle.PodAdmitResult{Admit: true}}}return lifecycle.PodAdmitResult{Admit: false,Reason: reason,Message: fmt.Sprintf(message, m.nodeConditions),}
}
eviction manager的Admit的逻辑如下:
- 如果该node的Conditions为空,则Admit成功;
如果enable了ExperimentalCriticalPodAnnotation Feature Gate,并且该Pod是Critical Pod(Pod有Critical的Annotation,或者Pod的优先级不小于SystemCriticalPriority),则Admit成功;
- SystemCriticalPriority的值为2 billion。
- 如果该node的Condition为Memory Pressure,并且Pod QoS为非best-effort,则Admit成功;
- 其他情况都表示Admit失败,即不允许该Pod在该node上Running。
Kubelet Eviction Manager SyncLoop
另外,在kubelet eviction manager的syncLoop中,也会对Critical Pod有特殊处理,代码如下。
pkg/kubelet/eviction/eviction_manager.go:226// synchronize is the main control loop that enforces eviction thresholds.
// Returns the pod that was killed, or nil if no pod was killed.
func (m *managerImpl) synchronize(diskInfoProvider DiskInfoProvider, podFunc ActivePodsFunc) []*v1.Pod {...// we kill at most a single pod during each eviction intervalfor i := range activePods {pod := activePods[i]if utilfeature.DefaultFeatureGate.Enabled(features.ExperimentalCriticalPodAnnotation) &&kubelettypes.IsCriticalPod(pod) && kubepod.IsStaticPod(pod) {continue}...return []*v1.Pod{pod}}glog.Infof("eviction manager: unable to evict any pods from the node")return nil
}
当触发了kubelet evict pod时,如果该pod满足以下所有条件时,将不会被kubelet eviction manager kill掉。
- 该Pod Status不是Terminated;
- Enable ExperimentalCriticalPodAnnotation Feature Gate;
- 该Pod是Critical Pod;
- 该Pod时Static Pod;
总结
经过上面的分析,我们得到以下Kubelet Eviction Manager对Critical Pod处理的关键点:
- kubelet重启后,eviction manager的Admit流程中对Critical Pod做如下特殊处理:如果enable了ExperimentalCriticalPodAnnotation Feature Gate,则允许该Critical Pod准入该node,无视该node的Condition。
当触发了kubelet evict pod时,如果该Critical Pod满足以下所有条件时,将不会被kubelet eviction manager kill掉。
- 该Pod Status不是Terminated;
- Enable ExperimentalCriticalPodAnnotation Feature Gate;
- 该Pod是Static Pod;
深入分析Kubernetes Critical Pod(二)相关推荐
- 二十、Kubernetes中Pod调度第二篇NodeAffinity详解、实例
1.概述 在默认情况下,一个Pod在哪个Node节点上运行,是由Scheduler组件采用相应的算法计算出来的,这个过程是不受人工控制的.但是在实际使用中,这并不满足的需求,因为很多情况下,我们想控制 ...
- Kubernetes 固定 Pod IP 地址方法
第七章 Kubernetes 固定 Pod IP 地址方法 文章目录 第七章 Kubernetes 固定 Pod IP 地址方法 一.自定义 IP 地址池 1.下载 calico 管理工具 calic ...
- Kubernetes之(二十)Helm程序包管理器
目录 Kubernetes之(二十)Helm程序包管理器 概念 部署Helm 下载helm 部署Tiller helm的使用 chart 目录结构 chart模板 定制安装 MySQL chart c ...
- kubernetes 之 pod 调度策略(一)
前言: 在 kubernetes 集群当中,我们很少直接创建一个 pod 来启动应用服务,而是通过控制器来创建 pod 从而运行应用实例,比如: Deployment.DaemonSet.Job 等控 ...
- 【K8S】[掘金] kubernetes 网络分析之二 K8S的网络模型
kubernetes 网络分析之二 K8S的网络模型 K8S 的网络特征 每个POD 一个IP (IP peer POD) 所有POD 通过IP 直接访问其他POD 而不管POD 是否在同一台物理机上 ...
- Kubernetes之Pod镜像拉取策略配置
一.默认的镜像拉取策略 1.1 当镜像指定的标签是latest时,默认策略是每次都下载更新 编辑pod-imagepullpolicy.yaml 文件,内容如下: apiVersion: v1 kin ...
- Kubernetes中Pod生命周期
在 Kubernetes中Pod是容器管理的最小单位, 有着各种各样的Pod管理器. 那么一个Pod从启动到释放, 在这期间经历了哪些过程呢? Pod自开始创建, 到正常运行, 再到释放, 其时间跨度 ...
- 容器编排技术 -- Kubernetes DNS Pod 与 Service 介绍
容器编排技术 -- Kubernetes DNS Pod 与 Service 介绍 1 介绍 2 怎样获取 DNS 名字? 3 支持的 DNS 模式 3.1 Service 3.1.1 A 记录 3. ...
- 容器编排技术 -- Kubernetes 给 Pod 配置服务质量等级
容器编排技术 -- Kubernetes 给 Pod 配置服务质量等级 1 Before you begin 2 QoS 等级 3 创建一个命名空间 4 创建一个 Pod 并分配 QoS 等级为 Gu ...
最新文章
- html模板是干嘛的,html模板有什么用
- 数据库中字段类型对应的C#中的数据类型
- Django入门(二) 理解Django生命流程周期
- .Net 实用技术收藏!!!
- 分布式文件系统之Tfs是什么?
- 从零认识单片机(9)
- sqlserver中常用的几个存储过程
- 使用开源的openssl的md5头文件,实现对于文件的md5代码
- mysql中定时任务_mysql中定时任务的用法
- android模拟器太卡,安卓模拟器安装之后太卡怎么解决
- iis7 您无权使用所提供的凭据查看此目录或页面。_使用 Spring Cloud 和 Docker 轻松构建微服务架构!...
- 理解一下ThreadLocal线程存储---springcloud工作笔记160
- MyISAM与InnoDB的区别是什么?
- 用MDT 2012为企业部署windows 7(四)--创建Deploymentshare共享以及介绍一些选项的具体作用...
- div和div之间画横线,如何在两个div之间画一条线?
- Angular 入门教程系列:33:移动端统计图表F2
- html表单站内搜,网站集成百度、Bing必应搜索引擎,在网页中实现站内全文搜索...
- macbook m1 vmware fusion 安装centos8
- 免费UI色彩搭配素材资源|色卡帮你找准搭配技巧
- ubuntu 软件包管理
热门文章
- python怎么筛选excel数据_PythonEXCEL读取-保存-矩阵合并-条件筛选
- ubuntu 查看cpu运行频率_Ubuntu下调整CPU运行频率并对其进行监视
- word2vec模型的理解
- java的圆周率_java学习日记,圆周率的打印
- canvas在舞台上点击后图片旋转_View绘制系列(10)Canvas基础变换
- gradle 指定java版本_Eclipse使用gradle编译时,使用固定的jdk版本进行编译(修改gradle的jdk编译版本)...
- PTA团体程序设计天梯赛篇(一)----模拟专题
- python 连接字符的方法(全)
- 天翼云从业认证(4.2)网站建设实战
- select2 手动输入匹配下拉框内容可多选