kubernetes 1.8 源码分析之kubelet资源上报

本文详细解析了Kubernetes 1.8版本中kubelet的资源上报机制,包括节点状态的定时收集及上报流程,并重点介绍了如何判断节点是否存在磁盘压力的状态更新逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文地址为: kubernetes 1.8 源码分析之kubelet资源上报

最近在给k8s 1.8添加磁盘调度的时候,又撸了一遍k8s的相关的源码,之前看过我源码分析的那个是k8s 1.4版本的,1.8版本还是有点变化的。
先看看kubelet上报机制,这个是kubelet的心跳机制,定时上报节点状态,默认是10s,时间可以设定
在kubelet创建的时候就已经创建了节点状态的收集方法
pkg/kubelet/kubelet.go里面NewMainKubelet方法

klet.setNodeStatusFuncs = klet.defaultNodeStatusFuncs()

那默认的方法有哪些呢?

// defaultNodeStatusFuncs is a factory that generates the default set of
// setNodeStatus funcs
func (kl *Kubelet) defaultNodeStatusFuncs() []func(*v1.Node) error {
    // initial set of node status update handlers, can be modified by Option's
    withoutError := func(f func(*v1.Node)) func(*v1.Node) error {
        return func(n *v1.Node) error {
            f(n)
            return nil
        }
    }
    return []func(*v1.Node) error{
        kl.setNodeAddress,
        withoutError(kl.setNodeStatusInfo),
        withoutError(kl.setNodeOODCondition),
        withoutError(kl.setNodeMemoryPressureCondition),
        withoutError(kl.setNodeDiskPressureCondition),
        withoutError(kl.setNodeDiskMountPressureCondition),
        withoutError(kl.setNodeReadyCondition),
        withoutError(kl.setNodeVolumesInUseStatus),
        withoutError(kl.recordNodeSchedulableEvent),
    }
}

注意上面的setNodeDiskMountPressureCondition这个是我自己添加上面的,不是k8s自带。这个里面包括节点信息、节点OOD信息、内存磁盘压力状态、节点监控状态等。
方法太多,那一个举例子吧setNodeDiskPressureCondition

func (kl *Kubelet) setNodeDiskPressureCondition(node *v1.Node) {
    currentTime := metav1.NewTime(kl.clock.Now())
    var condition *v1.NodeCondition

    // Check if NodeDiskPressure condition already exists and if it does, just pick it up for update.
    for i := range node.Status.Conditions {
        if node.Status.Conditions[i].Type == v1.NodeDiskPressure {
            condition = &node.Status.Conditions[i]
        }
    }

    newCondition := false
    // If the NodeDiskPressure condition doesn't exist, create one
    if condition == nil {
        condition = &v1.NodeCondition{
            Type:   v1.NodeDiskPressure,
            Status: v1.ConditionUnknown,
        }
        // cannot be appended to node.Status.Conditions here because it gets
        // copied to the slice. So if we append to the slice here none of the
        // updates we make below are reflected in the slice.
        newCondition = true
    }

    // Update the heartbeat time
    condition.LastHeartbeatTime = currentTime

    // Note: The conditions below take care of the case when a new NodeDiskPressure condition is
    // created and as well as the case when the condition already exists. When a new condition
    // is created its status is set to v1.ConditionUnknown which matches either
    // condition.Status != v1.ConditionTrue or
    // condition.Status != v1.ConditionFalse in the conditions below depending on whether
    // the kubelet is under disk pressure or not.
    if kl.evictionManager.IsUnderDiskPressure() {
        if condition.Status != v1.ConditionTrue {
            condition.Status = v1.ConditionTrue
            condition.Reason = "KubeletHasDiskPressure"
            condition.Message = "kubelet has disk pressure"
            condition.LastTransitionTime = currentTime
            kl.recordNodeStatusEvent(v1.EventTypeNormal, "NodeHasDiskPressure")
        }
    } else {
        if condition.Status != v1.ConditionFalse {
            condition.Status = v1.ConditionFalse
            condition.Reason = "KubeletHasNoDiskPressure"
            condition.Message = "kubelet has no disk pressure"
            condition.LastTransitionTime = currentTime
            kl.recordNodeStatusEvent(v1.EventTypeNormal, "NodeHasNoDiskPressure")
        }
    }

    if newCondition {
        node.Status.Conditions = append(node.Status.Conditions, *condition)
    }
}

方法很简单,核心就是IsUnderDiskPressure,如果是存在压力就把状态改成true,否则改为false。
看完上报的方法,那这个方法是什么是被调用的呢?本能就可以想到,一个是初始一个是定时的更新,下面看看具体是不是这样的,先看初始pkg/kubelet/kubelet_node_status.go里面的initialNode方法

kl.setNodeStatus(node)

这个方法就是调用刚才上面一系列收集状态的函数

func (kl *Kubelet) setNodeStatus(node *v1.Node) {
    for _, f := range kl.setNodeStatusFuncs {
        if err := f(node); err != nil {
            glog.Warningf("Failed to set some node status fields: %s", err)
        }
    }
}

然后就是定时上报,pkg/kubelet/kubelet_node_status.go里面tryUpdateNodeStatus方法,它是定时上报master的方法。

kl.setNodeStatus(node)

它同样调用setNodeStatus这个方法。顺便在多说一句,这个定时上报的方法什么时候被定时执行呢,答案在pkg/kubelet/kubelet.go的Run里面

if kl.kubeClient != nil {
        // Start syncing node status immediately, this may set up things the runtime needs to run.
        go wait.Until(kl.syncNodeStatus, kl.nodeStatusUpdateFrequency, wait.NeverStop)
    }

通过nodeStatusUpdateFrequency指定上报周期,好了关于资源上报的代码很简单,就不赘述了。


转载请注明本文地址: kubernetes 1.8 源码分析之kubelet资源上报
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值