,我们经常能看到PLEG的异常日志。...通过对PLEG的源码分析,希望能让大家了解PLEG是干什么的,以及它是如何工作的、它与什么模块有交互等问题。...容量,不可配,写死为1000; PLEG relist进行循环检查的间隔,不可配,写死为1s; 下面是GenericPLEG的结构体定义: pkg/kubelet/pleg/generic.go:49...Q: 在kubelet初始化时完成了PLEG的创建,那么合适启动的PLEG呢?...kl.pleg.Start() kl.syncLoop(updates, kl) } 在kubelet开始syncLoop前启动PLEG; PLEG Start PLEG Start就是启动一个协程,
现象:某个Node频繁出现“PLEG is not healthy: pleg was last seen active 3m46.752815514s ago; threshold is 3m0s”错误...kubelet也看到这个Pod的状态异常: I0218 01:21:17.383650 10311 kubelet.go:1775] skipping pod synchronization - [PLEG...is not healthy: pleg was last seen active 3m46.752815514s ago; threshold is 3m0s] ......E0218 01:21:30.654433 10311 generic.go:271] PLEG: pod istio-ingressgateway-6bbdd58f8c-nlgnd/istio-system
现象:某个Node频繁NotReady,kubectl describe该Node,出现“PLEG is not healthy: pleg was last seen active 3m46.752815514s...我们首先要明白PLEG是什么? PLEG 全称叫 Pod Lifecycle Event Generator,即 Pod 生命周期事件生成器。...整体的工作流程如下图所示,虚线部分是 PLEG 的工作内容。...以默认情况为准,PLEG检查会间隔一秒,换句话说,每一次检查过程执行之后,PLEG会等待一秒钟,然后进行下一次检查;而每一次检查的超时时间是三分钟,如果一次PLEG检查操作不能在三分钟内完成,那么这个状况...而这里的 PLEG,指的是 pod lifecycle event generator。PLEG 是 kubelet 用来检查 runtime 的健康检查机制。
01 PLEG 是个啥? PLEG 全称叫 Pod Lifecycle Event Generator,即 Pod 生命周期事件生成器。...整体的工作流程如下图所示,虚线部分是 PLEG 的工作内容。 ? 02 PLEG is not healthy 是如何发生的?...# HELP kubelet_pleg_relist_interval_microseconds Interval in microseconds between relisting in PLEG....Latency in microseconds for relisting pods in PLEG. # TYPE kubelet_pleg_relist_latency_microseconds.../pkg/kubelet/pleg/generic.go[10] Past bug about CNI — PLEG is not healthy error, node marked NotReady
(types.Result, error) DelNetwork(net *NetworkConfig, rt *RuntimeConf) error } CNI Plugin在kubelet管理的PLEG...plegCh: a channel to read PLEG updates from // // Events are also read from the kubelet liveness...kl.sourcesReady.AddSource(u.Source) case e := <-plegCh: if isSyncPodWorthy(e) { // PLEG event for...if pod, ok := kl.podManager.GetPodByUID(e.ID); ok { glog.V(2).Infof("SyncLoop (PLEG): %q, event:...glog.V(4).Infof("SyncLoop (PLEG): ignore irrelevant event: %#v", e) } } if e.Type == pleg.ContainerDied
Pod 创建/删除 K8s 中 Pod 的调谐采用 channel 生产者-消费者模型实现,具体通过 PLEG(Pod Lifecycle Event Generator) 进行 Pod 生命周期事件管理...// kubernetes/pkg/kubelet/pleg/pleg.go // 通过 PLEG 进行 Pod 生命周期事件管理 type PodLifecycleEventGenerator interface... // 监听 eventChannel,传递给下游消费者 Healthy() (bool, error) } Pod 事件生产者 - 相关代码: // kubernetes/pkg/kubelet/pleg...) bool { select { ... // 消费者:监听 plegCh 的事件 case e := <-plegCh: if e.Type == pleg.ContainerStarted...klog.V(4).InfoS("SyncLoop (PLEG): pod does not exist, ignore irrelevant event", "event", e) } }
Pod 创建/删除 K8s 中 Pod 的调谐采用 channel 生产者-消费者模型实现,具体通过 PLEG(Pod Lifecycle Event Generator) 进行 Pod 生命周期事件管理...// kubernetes/pkg/kubelet/pleg/pleg.go // 通过 PLEG 进行 Pod 生命周期事件管理 type PodLifecycleEventGenerator interface...eventChannel,传递给下游消费者 Healthy() (bool, error) } Pod 事件生产者(producer) - 相关代码: // kubernetes/pkg/kubelet/pleg...klog.V(4).InfoS("SyncLoop (PLEG): pod does not exist, ignore irrelevant event", "event", e)...} } // 容器销毁事件处理:清除 Pod 内相关 Container if e.Type == pleg.ContainerDied {
- nodestatus/ 定义了很多节点状态更新用的 setter - pleg/ pod lifecycle event generator - pod/...iptables 规则 (暂未明白这个同步的意义) 运行 kl.podKiller 运行 pod 状态管理模块 kl.statusManager 运行 pod 探针模块 kl.probeManager 运行 pleg...(pod lifecycle event generator) 模块 kl.pleg 运行主循环 kl.syncLoop kl.syncLoop 接受两个参数,第一个是 <-chan kubetypes.PodUpdate...chan time.Time,定时触发的 resync 操作 - housekeepingCh <-chan time.Time,定时触发的清理操作 - plegCh <-chan *pleg.PodLifecycleEvent...和上述四个操作什么关系(凭什么你叫 sync) HandlePodCleanups 和 HandlePodRemoves 的区别 为什么需要定时触发 syncCh 为什么需要 housekeeping pleg
= nil {kl.runtimeClassManager.Start(wait.NeverStop)}// 通过 PLEG 进行 Pod 生命周期事件管理 kl.pleg.Start()kl.syncLoop...(Pod Lifecycle Event Generator)Pod生命周期管理相关接口如下:// kubernetes/pkg/kubelet/pleg/pleg.go type PodLifecycleEventGenerator...Pods 并计算事件类型 Watch() chan *PodLifecycleEvent // 监听 eventChannel,传递给下游消费者 Healthy() (bool, error) }PLEG...的入口函数为GenericPLEG的成员函数Start// kubernetes/pkg/kubelet/pleg/generic.go // 启动一个 goroutine 周期性的重新生成 Pods...g.relistPeriod, wait.NeverStop)}relist函数在重新生成新的 Pods 列表的过程中,不管生产新的 Pod 事件:// kubernetes/pkg/kubelet/pleg
5 Pod 创建/删除 K8s 中 Pod 的调谐采用 channel 生产者-消费者模型实现,具体通过 PLEG(Pod Lifecycle Event Generator)进行 Pod 生命周期事件管理...// kubernetes/pkg/kubelet/pleg/pleg.go// 通过 PLEG 进行 Pod 生命周期事件管理type PodLifecycleEventGenerator interface...eventChannel,传递给下游消费者 Healthy() (bool, error)} Pod 事件生产者(producer)- 相关代码: // kubernetes/pkg/kubelet/pleg...klog.V(4).InfoS("SyncLoop (PLEG): pod does not exist, ignore irrelevant event", "event", e)...} } // 容器销毁事件处理:清除 Pod 内相关 Container if e.Type == pleg.ContainerDied {
//启动 pleg 该模块主要用于周期性地向 container runtime 刷新当前所有容器的状态 //https://github.com/kubernetes/community/blob/...master/contributors/design-proposals/node/pod-lifecycle-event-generator.md kl.pleg.Start() kl.syncLoop...模块,该模块主要用于周期性地向 container runtime 上报当前所有容器的状态,具体可以看:Pod Lifecycle Event Generator (PLEG); 调用kl.syncLoop...): ignore irrelevant event: %#v", e) } } if e.Type == pleg.ContainerDied { if containerID,...(string); ok { kl.cleanUpContainersInPod(e.ID, containerID) } } ... } PLEG.Start的时候会每秒钟启动调用一次
直接看源码: image.png 我们可以看到syncLoop有个for循环,主要运行syncLoopIteration,并且和pleg组件有交互。...这其实是kubelet中PLEG这个组件去干的事。 image.png 我们再看一下这张图,pleg watch到数据传入了syncLoopIteration。...pleg是用来在pod生命周期中生成事件的,它周期性地去监听容器状态。...If an // error occurs during the inspection, we want PLEG to retry again // in the next relist....这下就明白了:syncLoopIteration中回去watch pleg的eventchannel,而pleg周期性地发现pod(或container)的变化,生成事件,写入eventchannel中
...) } else { klet.StatsProvider = stats.NewCRIStatsProvider(......) } // 9、初始化 pleg...klet.pleg = pleg.NewGenericPLEG(klet.containerRuntime, plegChannelCapacity, plegRelistPeriod, klet.podCache...", klet.pleg.Healthy) if _, err := klet.updatePodCIDR(kubeCfg.PodCIDR); err !...= nil { kl.runtimeClassManager.Start(wait.NeverStop) } // 12、启动 pleg kl.pleg.Start...): ignore irrelevant event: %#v", e) } } if e.Type == pleg.ContainerDied
我们主要来看下 syncLoop 层的几个重要组件: PLEG:调用容器运行时的接口来获取本节点 containers/sandboxes 的信息,与本地维护的 pod cache 进行对比,生成对应的...plegCh:该 channel 的生产者为 pleg 子模块,该模块会周期性地向容器运行时查询当前所有容器的状态,如果状态发生变化,则向这个 channel 生产事件。...kl.lastContainerStartedTime.Add(e.ID, time.Now()) } if isSyncPodWorthy(e) { // PLEG event...if pod, ok := kl.podManager.GetPodByUID(e.ID); ok { klog.V(2).Infof("SyncLoop (PLEG): %q, event...klog.V(4).Infof("SyncLoop (PLEG): ignore irrelevant event: %#v", e) } } if e.Type == pleg.ContainerDied
1、PLEG(Pod Lifecycle Event Generator) PLEG 是 kubelet 的核心模块,PLEG 会一直调用 container runtime 获取本节点 containers
什么是PLEG? 这个报错清楚地告诉我们,容器 runtime 是不工作的,且 PLEG 是不健康的。这里容器 runtime 指的就是 docker daemon 。...而这里的 PLEG,指的是 pod lifecycle event generator。PLEG 是 kubelet 用来检查 runtime 的健康检查机制。...但是 polling 有其高成本的缺陷,所以 PLEG 应用而生。...PLEG 尝试以一种“中断”的形式,来实现对容器 runtime 的健康检查,虽然实际上,它同时用了 polling 和”中断”这样折中的方案。 ?...在这个问题中,既然 PLEG 认为容器 runtime 出了问题,我们需要从 docker daemon 进程看起。
什么是PLEG 这个报错很清楚的告诉我们,容器runtime是不工作的,且PLEG是不健康的。这里容器runtime指的就是docker daemon。...而这里的PLEG,指的是pod lifecycle event generator。PLEG是kubelet用来检查容器runtime的健康检查机制。...但是polling有其成本上的缺陷,所以PLEG应用而生。PLEG尝试以一种“中断”的形式,来实现对容器runtime的健康检查,虽然实际上,它同时用了polling和”中断”两种机制。 ?...在这个问题中,既然PLEG认为容器运行是出了问题,我们需要先从docker daemon进程看起。
.) // pleg klet.pleg = pleg.NewGenericPLEG(klet.containerRuntime, plegChannelCapacity, plegRelistPeriod...kl.pleg.Start() kl.syncLoop(updates, kl) } syncLoop 是 kubelet 的主循环方法,它从不同的管道(FILE,URL, API-SERVER)监听...housekeepingTicker := time.NewTicker(housekeepingPeriod) defer housekeepingTicker.Stop() plegCh := kl.pleg.Watch
核心功能模块 PLEG ?...PLEG全称为PodLifecycleEvent,PLEG会一直调用container runtime获取本节点的pods,之后比较本模块中之前缓存的pods信息,比较最新的pods中的容器的状态是否发生改变...housekeepingTicker := time.NewTicker(housekeepingPeriod) defer housekeepingTicker.Stop() plegCh := kl.pleg.Watch...同时kl.pleg.Watch()是pleg模块定义的事件channel, SyncHandler定义 type SyncHandler interface { HandlePodAdditions...触发同步的事件channel主要包括 1.configCh pod的配置改变 2.PLEG模块中状态更新事件 3.1s为周期的同步时钟 syncPod 4.2s为周期的执行全局清理任务的始终
housekeepingTicker := time.NewTicker(housekeepingPeriod) defer housekeepingTicker.Stop() plegCh := kl.pleg.Watch...plegCh: a channel to read PLEG updates from // // Events are also read from the kubelet liveness...kl.sourcesReady.AddSource(u.Source) } case e := <-plegCh: if isSyncPodWorthy(e) { // PLEG event...if pod, ok := kl.podManager.GetPodByUID(e.ID); ok { glog.V(2).Infof("SyncLoop (PLEG): %q, event:...glog.V(4).Infof("SyncLoop (PLEG): ignore irrelevant event: %#v", e) } } if e.Type == pleg.ContainerDied
领取专属 10元无门槛券
手把手带您无忧上云