图解kubernetes Pod生命周期事件生成器

PLEG(PodLifecycleEventGenerator)主要是用于周期性检测Pod的运行状态,从而对比Pod前后状态生成事件从而触发kubelet进行Pod容器状态的校证,让我们一起来初探下其内部实现机制

  1. 图解设计
    1.1 Pod事件生成
    image.png Pod事件生成主要是根据对应Pod前后的状态对比来实现,首先通过runtime来获取当前节点的所有Pod的列表,并将对应的状态进行保存,这样在下一个轮训周期就可以通过前后状态的对比去发现状态发生改变的Pod的容器,并且产生对应的事件

1.2 事件通知与状态同步
image.png Pod事件生成之后会通过管道将对应的事件同步给状态同步线程,状态同步线程感知到Pod的变更事件后,会与Pod的目标状态进行对比同步,并调用Runtime来进行最终校证操作的执行,同时在下个轮询周期中又会重新从Runtime获取状态,从而不断校证Pod的状态,直至目标状态

  1. Pod记录
    Pod记录其实就是一个map,并通过podRecord来保存前后轮询周期Runtime返回的Pod的信息

type podRecord struct {
old *kubecontainer.Pod
current *kubecontainer.Pod
}

type podRecords map[types.UID]*podRecord
3. Pod事件生成器
3.1 获取Pod状态
首先通过runtime来获取当前节点的所有pod的状态

// Get all the pods.
podList, err := g.runtime.GetPods(true)
if err != nil {
	klog.Errorf("GenericPLEG: Unable to retrieve pods: %v", err)
	return
}

3.2 对比Pod信息生成事件
eventsByPodID := map[types.UID][]*PodLifecycleEvent{}
for pid := range g.podRecords {
// 获取之前的Pod信息
oldPod := g.podRecords.getOld(pid)
pod := g.podRecords.getCurrent(pid)
// 获取当前Pod的所有容器集合
allContainers := getContainersFromPods(oldPod, pod)
for _, container := range allContainers {
//
events := computeEvents(oldPod, pod, &container.ID)
for _, e := range events {
// 更新pod的events事件
updateEvents(eventsByPodID, e)
}
}
}
3.3对比容器状态事件生成
Pod的事件主要是通过底层容器的状态来生成的,会最终对比每个容器的前后状态,从而获取变更事件

func generateEvents(podID types.UID, cid string, oldState, newState plegContainerState) []*PodLifecycleEvent {
if newState == oldState {
return nil
}

klog.V(4).Infof("GenericPLEG: %v/%v: %v -> %v", podID, cid, oldState, newState)
switch newState {
case plegContainerRunning:
	return []*PodLifecycleEvent{{ID: podID, Type: ContainerStarted, Data: cid}}
case plegContainerExited:
	return []*PodLifecycleEvent{{ID: podID, Type: ContainerDied, Data: cid}}
case plegContainerUnknown:
	return []*PodLifecycleEvent{{ID: podID, Type: ContainerChanged, Data: cid}}
case plegContainerNonExistent:
	switch oldState {
	case plegContainerExited:
		// We already reported that the container died before.
		return []*PodLifecycleEvent{{ID: podID, Type: ContainerRemoved, Data: cid}}
	default:
		return []*PodLifecycleEvent{{ID: podID, Type: ContainerDied, Data: cid}, {ID: podID, Type: ContainerRemoved, Data: cid}}
	}
default:
	panic(fmt.Sprintf("unrecognized container state: %v", newState))
}

}
4. 整体事件流程总览
image.png 在k8s中有很多类似PLEG的设计,总的设计目标都是为了通过事件的变更和实际期望状态,不断的进行调整,从而达到最终的期望状态, 以后我尽量只给出组件最核心的一点代码,梳理清除整个流程中核心的数据结构与算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值