【kubernetes】K8S节点状态的维护

embedded/2025/1/16 22:50:59/

1 节点状态

节点是K8S集群中的一类重要资源,节点的状态通常可以作为判断集群异常的重要手段。

为了展示节点在各方面的健康程度,在kubectl describe node k8s-master的输出结果中的Conditions部分可以查看k8s-master节点的一些状态数据:

  • NetworkUnavailable:网络配置是否正常
  • MemoryPressure:是否还有可用内存
  • DiskPressure:是否还有可用磁盘
  • PIDPressure:节点上是否有太多的进程
  • Ready:节点是否健康

每种类型用5个字段描述:

  • Status:状态,通常有三种状态:True、False、Unknown
  • LastHeartbeatTime:上一次心跳事件,也就是上次上报该状态信息的时间
  • LastTransitionTime:上一次状态转换的时间
  • Reason:处于当前状态的原因
  • Message:状态描述

NetworkUnavailable状态不是实时的,而是相关的网络插件启动后上报一次,表示网络插件正常启动,但是也无法表明当前的网络是否是正常的,而且,插件运行过程中也没办法知道当前网络是否正常,因此,NetworkUnavailabel只是表明插件成功启动过,无法知道当前的网络是否真的良好。

MemoryPerssure、DiskPressure、PIDPressure都可以通过采集当前节点的数据得到:

  • MemoryPerssure:采集当前节点的内存信息,
  • DiskPressure:采集当前节点的磁盘信息,
  • PIDPressure:采集当前节点的进程信息,

这三个状态值都是由kubelet定时向apiserver上报状态而来,而kube-controller-manager会判断一段时间未上报的情况。

kubectl get node展示的状态即为Conditions中的Ready,该状态由多个条件综合计算而来。

上述状态更新的流程:

  • kubelet会每隔一段时间(kubelet的–node-status-update-frequency参数,默认为10秒)更新节点状态到apiserver
  • NodeController每隔一段时间(kube-controller-manager的–node-monitor-period参数,默认为5秒)检查一次节点状态
  • 如果kubelet超过一段时间(kube-controller-manager的–node-monitor-grace-period参数,默认为50秒)未向apiserver上报,NodeController将节点状态标记为Unknown

2 Kubelet

kubelet在启动时会先上报一次节点状态。

  • fastNodeStatusUpdate(pkg/kubelet/kubelet_node_status.go)
    • originalNode, err := kl.GetNode() 获取当前节点的信息
    • readyIdx, originalNodeReady := nodeutil.GetNodeCondition(&originalNode.Status, v1.NodeReady) 获取当前节点的Condition中的NodeReady,如果为True,则直接返回
    • node, changed := kl.updateNode(ctx, originalNode) 更新当前节点的信息,并返回新的节点信息以及节点信息是否变化的状态,如果节点状态没有变化,则直接返回
    • readyIdx, nodeReady := nodeutil.GetNodeCondition(&node.Status, v1.NodeReady) 获取当前节点的最新信息中的NodeReady状态,如果为False,则直接返回
    • kl.patchNodeStatus(originalNode, node) 此时节点状态发生了由NotReady向Ready的变化
      • nodeutil.PatchNodeStatus 向apiserver上报节点Ready(毕竟节点没办法自己上报NotReady)
    • kl.syncNodeStatus() 如果上面向apiserver上报节点Ready失败了,则调用syncNodeStatus()
      • kl.registerWithAPIServer() 向apiserver注册节点,如果已经注册过了则直接返回
      • kl.updateNodeStatus(ctx) 更新节点状态
        • kl.tryUpdateNodeStatus(ctx, i)
          • util.FromApiserverCache(&opts) 将GET操作的选项中的ResourceVersion设置为0
          • originalNode, err := kl.heartbeatClient.CoreV1().Nodes().Get(ctx, string(kl.nodeName), opts) 调用apiserver接口获取节点信息,为了减少apiserver访问etcd带来的性能影响,这里调用时apiserver会从缓存中获取,而不是读取etcd
          • updatedNode, err := kl.patchNodeStatus(originalNode, node) 如果检测出apiserver返回的节点信息和当前获取到的节点信息有变化,或者距离上次节点信息上报超过--node-status-update-frequency参数,则向apiserver更新节点状态

kubelet启动时为了尽可能快地将节点状态上报给apiserver,每隔100毫秒执行一次fastNodeStatusUpdate函数,有两种情况结束执行:

  • 成功地将Ready状态上报给apiserver
  • 启动后超过2分钟状态还未更新

在kubelet启动后,会每隔--node-status-update-frequency时间上报一次:

// pkg/kubelet/kubelet.go
// func (kl *Kubelet) Run(updates <-chan kubetypes.PodUpdate)
go wait.JitterUntil(kl.syncNodeStatus, kl.nodeStatusUpdateFrequency, 0.04, true, wait.NeverStop)

3 NodeLifecycleController

节点控制器在K8S中是NodeLifecycleController(节点生命周期控制器)。

kube-controller-manager在创建NodeLifecycleController时会传递三个参数:

  • NodeMonitorPeriod:检查节点状态的周期
  • NodeStartupGracePeriod:节点启动的缓冲期,当节点创建或者节点重启时会预留一段时间
  • NodeMonitorGracePeriod:检查节点状态的缓冲期

NodeLifecycleController在启动时会创建一个定时任务的协程:

// pkg/controller/nodelifecycle/node_lifecycle_controller.go
// func (nc *Controller) Run(ctx context.Context)
go wait.UntilWithContext(ctx, func(ctx context.Context) {if err := nc.monitorNodeHealth(ctx); err != nil {logger.Error(err, "Error monitoring node health")}}, nc.nodeMonitorPeriod)

monitorNodeHealth的调用流程如下:

  • monitorNodeHealth
    • nodes, err := nc.nodeLister.List(labels.Everything()) 获取所有的节点
    • added, deleted, newZoneRepresentatives := nc.classifyNodes(nodes) 将节点分为三类:新增的、删除的、no zone states?
    • 分别对上述的三种类别的节点进行处理
    • workqueue.ParallelizeUntil(ctx, nc.nodeUpdateWorkerSize, len(nodes), updateNodeFunc) 并发执行updateNodeFunc函数,updateNodeFunc的调用流程如下:
      • node := nodes[piece].DeepCopy() 函数的参数是个索引piece,然后从获取到的所有节点中根据索引piece取出节点
      • _, observedReadyCondition, currentReadyCondition, err = nc.tryUpdateNodeHealth(ctx, node) 尝试更新节点的健康状态
        • _, currentReadyCondition := controllerutil.GetNodeCondition(&node.Status, v1.NodeReady) 获取节点的Condition中的NodeReady
        • 如果当前节点的的ReadyCondition为空,说明kubelet从未上报过节点状态,则将gracePeriod设置为NodeStartupGracePeriod,否则将gracePeriod设置为NodeMonitorGracePeriod
        • observedLease, _ := nc.leaseLister.Leases(v1.NamespaceNodeLease).Get(node.Name) 获取节点的lease
        • 如果距离上次探测时间超过gracePeriod,说明节点状态更新已经超过缓冲期,则执行以下逻辑:
          • 遍历所有的Condition类型(此处不考虑NodeNetworkUnavailable)
          • 如果没有某个类型的Condition,则将Condition中的Reason设置为NodeStatusNeverUpdated
          • 如果存在某个类型的Condition,则将Condition中的Reason设置为NodeStatusUnknown
          • 如果Condition发生变化,则调用nc.kubeClient.CoreV1().Nodes().UpdateStatus(ctx, node, metav1.UpdateOptions{})更新Node的Status

4 总结

kubelet和kube-controller-manager更新Conditions的流程与前面说的基本一致:

  • kubelet会每隔一段时间(kubelet的–node-status-update-frequency参数,默认为10秒)更新节点状态到apiserver
  • NodeController每隔一段时间(kube-controller-manager的–node-monitor-period参数,默认为5秒)检查一次节点状态
  • 如果kubelet超过一段时间(kube-controller-manager的–node-monitor-grace-period参数,默认为50秒)未向apiserver上报,NodeController将节点的Condition中的Ready状态修改为False

http://www.ppmy.cn/embedded/154499.html

相关文章

设计一个流程来生成测试模型安全性的问题以及验证模型是否安全

要使用 Ollama 运行 llama3.3:70b 模型&#xff0c;并设计一个流程来生成测试模型安全性的问题以及验证模型是否安全&#xff0c;可以按照以下步骤进行设计和实现。整个过程包括环境配置、设计安全测试提示词、执行测试以及分析结果。以下是详细的步骤和指导&#xff1a; 1. 环…

uni-app h5修改浏览器导航栏的 title以及icon

1.title 在pages.json文件中修改:"navigationBarTitleText":"uni-app" 2.icon的修改 2.1 在static中新建一个index.html文件作为模板文件&#xff0c;并且将你的icon图片也放在static文件夹下 2.2 在index.html文件中加入如下代码&#xff08;记得icon文件…

linux解压命令(可整理到CSDN)

1. tar -xvf ffmpeg-7.0.2.tar.xz x&#xff1a;表示解压文件。 v&#xff1a;表示在解压过程中显示文件&#xff08;verbose模式&#xff09;。这个选项是可选的&#xff0c;加上它可以让你看到正在解压的文件列表&#xff0c;但如果不加也不会影响解压过程。 f&#xff1a;…

网络安全的几种攻击方法

攻击方法 挂马: 就是在别人的网站文件里面放入网页木马或者是将代码潜入到对方正常的网页文件里&#xff0c;以使浏览者中马。 挖洞: 指漏洞挖掘。 加壳: 就是利用特殊的算法&#xff0c;将EXE可执行程序或者DLL动态连接库文件的编码进行改变&#xff08;比如实现压缩、加密&a…

Apache NiFi存在信息泄露漏洞(CVE-2024-56512)

免责声明: 本文旨在提供有关特定漏洞的深入信息,帮助用户充分了解潜在的安全风险。发布此信息的目的在于提升网络安全意识和推动技术进步,未经授权访问系统、网络或应用程序,可能会导致法律责任或严重后果。因此,作者不对读者基于本文内容所采取的任何行为承担责任。读者在…

OpenAI函数调用迎来重大升级:引入「最小惊讶原则」等软件工程实践,开发体验更上一层楼!

想玩转各种AI模型&#xff1f;chatTools 帮你搞定&#xff01;这里有o1、GPT4o、Claude和Gemini等等&#xff0c;一个平台就能满足你所有的AI需求。快来开始你的AI冒险吧&#xff01; OpenAI的函数调用功能再次迎来重大更新&#xff01;新版指南不仅大幅精简了文档&#xff0c;…

【Python】使用python 对excel文件进行加密

最近在跟同事对接工作的时候&#xff0c;我需要把Excel文件发给对方。 但是由于文件内容的私密性&#xff0c;需要对Excel文件进行加密&#xff0c;保护文件以免给第三方看到&#xff0c;保障数据的安全。 在Python中&#xff0c;有多种方法可以对Excel文件进行加密。以下是几…

学习华为熵减:激发组织活力(系列之三)

目录 为什么学习华为&#xff1f; 学习华为什么&#xff1f; 一、势&#xff1a;顺势而为&#xff0c;在风口上猪都会飞起来。 二、道&#xff1a;就是认识和利用规律层面&#xff0c;文化和制度创新就是企业经营之道。 三、法&#xff1a;就是一套价值管理的变革方法论。…