头图

简介

Node Problem Detector(NPD)是 Kubernetes 集群中一个重要的监控插件,它的作用是监控节点的健康状况并检测可能出现的问题。NPD 通过在每个节点上运行的检测器来工作,能够发现基础设施、容器运行时、硬件和内核等问题,并将这些问题报告给集群中的上层控制面。

NPD 只是作为一个问题检测和报告程序运行,需要配合自愈程序才能完成节点问题的自动处理,默认的集群控制面组件并不会响应 NPD 报告的问题。NPD 可以检测的问题如下:

  • 基础设施问题: NTP 服务关闭;
  • 硬件问题:损坏的处理器 、内存或者磁盘;
  • 内核问题:内核死锁或者文件系统损坏;
  • 容器运行时问题:CRI 守护进程无响应;
  • ...

NPD 以 DaemoSet 或独立进程的方式运行,支持多个 exporter 作为通知渠道,其中 Kubernetes exporter 向 APIServer 报告以下两类节点问题:

  • Event ,对 Pod 影响有限但值得关注的问题;
  • NodeCondition , 可以导致 Pod 无法在节点运行的持久性问题;

实际上,两类问题都会产生 K8s Event ,只不过 NodeCondition 会作为一个不可自动恢复的状态持久存在于 Node 的描述信息中,除非主动重置或者重启 NPD Pod。考虑到 NodeCondition 需要作为自愈系统的输入,这是一种合理的设计,让自愈行为能够实现串行操作,有利于在自愈过程中保持一致性。

架构方面,目前, NPD 作为守护进程以 goroutine 方式运行各类问题检测器,支持用户以各种语言扩展,例如编写 check_xxx.sh 脚本并配置为 NPD 插件, temporarypermanent 类型的规则分别为 APIServer 上报 EventNodeCondition ,未来, NPD 和 问题检测器的架构可能发生变更,部分问题检测器以主机进程的方式运行,以避免检测行为受到被检测对象干扰,导致事件丢失。

NPD 支持的检测器类型有:

问题检测器类型NodeCondition描述
SystemLogMonitor<li>KernelDeadlock (内核死锁)
<li>ReadonlyFilesystem (文件系统只读)
<li>FrequentKubeletRestart ( Kubelet 频繁重启)
<li>FrequentDockerRestart ( Docker 频繁重启)
<li>FrequentContainerdRestart ( Containerd 频繁重启)
根据预定义规则监控系统日志,报告问题和指标,可禁用。
SystemStatMonitor根据预定义规则监控系统健康相关的状态,报告问题和指标,可禁用。
CustomPluginMonitorNTPProblem ( NTP 问题)调用用户自定义的问题检测器,仅包含 NTP 检测器作为示例,可禁用。
HealthChecker<li>KubeletUnhealthy ( Kubelet 非健康状态)
<li>ContainerRuntimeUnhealthy (容器运行时非健康状态)
检查 Kubelet 和容器运行时( Docker 和 Containerd )健康状态,不支持禁用。

NPD 支持多种类型的导出器,可将节点事件导出为 Kubernetes 事件或者 Prometheus 指标等,通过采集以上渠道的数据可实现对节点事件的观测。相对来说,通过 Kubernetes Events 获取节点事件是一个更加优雅的方案,观测方能够通过事件流获得更丰富的上下文。

观测云采集器 Datakit 支持自动采集 Kubernetes 事件,配置日志检测监控器可向用户主动报告节点问题。使用云服务时,建议启用云厂商提供的 NPD 插件,将提供更强大的节点问题检测能力。

操作步骤

部署 DataKit

登录观测云控制台,点击「集成」 -「DataKit」 - 「Kubernetes」,下载 datakit.yaml,拷贝第 3 步中 ENV_DATAWAY 键的值:

图片

编辑 datakit.yaml,修改 DaemonSet 环境变量:

  • 修改 ENV_DATAWAY 的值为上一步中拷贝的值;
  • 修改 ENV_CLUSTER_NAME_K8S 的值为集群名称;
  • 新增 ENV_NAMESPACE,值为集群名称;

执行以下命令部署 Datakit 并验证:

kubectl apply -f datakit.yaml
kubectl get pods -n datakit

部署成功后 Datakit 将自动采集集群事件并上报至数据来源为 kubernetes_events 的日志,无需额外配置,点击日志条目可查看阔扩展信息:

图片

开启 NPD 插件

对于云 Kubernetes 服务,推荐启用官方 NPD 插件,对于自建 Kubernetes 服务,可前往 NPD 官方仓库下载相关资源文件并部署:

注意:

  • 官方默认配置仅启用从操作系统、进程管理器日志检查节点问题的插件,启用其他插件可能需要为官方镜像集成命令行工具,例如 systemctl、crictl 等;
  • 官方镜像无法拉取时,可为镜像增加前缀 k8s.m.daocloud.io/

日志(事件)

观测云中,Kubernetes 事件描述如下:

{
  "time": 1723622964327,
  "time_us": 1723622964327008,
  "__docid": "L_1723622964327_cqu6cdhmc0rcje80ft90",
  "__source": "kubernetes_events",
  "message": "kernel: BUG: unable to handle kernel NULL pointer dereference at TESTING",
  "__isCutMessage": false,
  "__namespace": "logging",
  "source": "kubernetes_events",
  "status": "warn",
  "df_metering_size": 1,
  "message_length": 72,
  "cluster_name_k8s": "default",
  "date_ns": 1723622964327008500,
  "from_node": "lc-ubuntu-k8s-70",
  "index": "default",
  "involved_kind": "Node",
  "involved_name": "lc-ubuntu-k8s-70",
  "involved_namespace": "",
  "involved_uid": "lc-ubuntu-k8s-70",
  "reason": "KernelOops",
  "resource_version": "228175",
  "time_ns": 1723622964327008500,
  "type": "Warning",
  "uid": "32e220e4-e3f1-4e38-a079-4982c4824ca8",
  "__search": 0,
  "__searches": [],
  "__unit": {
    "time": null,
    "time_us": null,
    "__docid": null,
    "__source": null,
    "__namespace": null,
    "source": null,
    "status": null,
    "df_metering_size": null,
    "message_length": null,
    "cluster_name_k8s": null,
    "date_ns": null,
    "from_node": null,
    "index": null,
    "involved_kind": null,
    "involved_name": null,
    "involved_namespace": null,
    "involved_uid": null,
    "reason": null,
    "resource_version": null,
    "time_ns": null,
    "type": null,
    "uid": null
  },
  "__uuid": "a41db1f0-5a14-11ef-bb6b-61e8f09c54b4",
  "__hightlight": false,
  "__is_all_columns_data": true
}

NPD 生成的事件中并不包含标识持久性与临时性问题的字段,需要根据 reason 字段的值配置不同类型的监控器,例如持久性问题监控器和临时性问题监控器,分别匹配对应的 reason,另外,临时性事件频繁发生时可视为持久性事件。

可以通过云厂商官方文档或启用 NPD 后的 ConfigMap 了解能够检测的节点事件:

kubectl get configmap/ack-node-problem-detector-config -n kube-system -o yaml

监控视图

登录观测云控制台,点击「场景」 -「新建仪表板」,输入 “kubernetes”, 选择 “Node Problem Detector 监控视图”,点击 “确定” 即可添加视图:

图片

关键指标

任何持久性问题、频繁出现的非持久性问题均可作为关键指标,例如 Kubetlet 处于非健康状态、CNI 插件问题、Pod 频繁被 OOMKill 等,这些指标其实会作为日志的 tag 存在。

以下列表包含但不限于默认配置下 NPD 能够检测的事件:

原因持久性描述
DockerHungDocker 挂起或无响应
ReadonlyFilesystem文件系统被挂载为只读模式,通常是一种保护机制,在某些情况下防止文件系统损坏
CorruptDockerOverlay2Overlay2 存储驱动存在问题
ContainerdUnhealthyContainerd 处于非健康状态
KubeletUnhealthyKubelet 处于非健康状态
DockerUnhealthyDocker 处于非健康状态
OOMKillingKubernetes 因 OOM 结束 Pod
TaskHung任务挂起
UnregisterNetDevice网络接口异常
KernelOops内核检测到的异常行为,例如:空指针、设备错误
Ext4ErrorExt4 文件系统问题
Ext4WarningExt4 文件系统问题
IOError缓冲区问题
MemoryReadError可被修复的内存错误,频繁发生意味着内存硬件可能出现问题
KubeletStartKubelet 启动,频繁出现意味 Kubelet 频繁重启
DockerStartDocker 启动,频繁出现意味 Kubelet 频繁重启
ContainerdStartContainerd 启动,频繁出现意味 Kubelet 频繁重启
CorruptDockerImageDocker registry 使用的目录不为空
DockerContainerStartupFailureDocker 无法启动
ConntrackFull网络连接跟踪数满,将影响 NAT、防火墙等网络功能
NTPIsDownNTP时间同步异常

监控器(告警)

持久性问题监控器

配置持久性问题监控器,关注任意节点的指定事件:

图片

图片

频繁出现的非持久性问题监控器

配置频繁出现的非持久性问题监控器,关注某一节点的指定事件出现的次数:

图片

事件模拟

可通过以下命令模拟问题,该操作向 APIServer 同时写入了临时和持久性事件:

sudo sh -c "echo 'kernel: INFO: task docker:20744 blocked for more than 120 seconds.' >> /dev/kmsg"

可看到告警产生:

图片

点击告警可快速查看事件趋势、自定义链接、事件历史、关联仪表盘等信息:

图片

启用观测云监控器时,需要根据所选 NPD 插件报告的事件类型和 reason 调整仪表盘、监控器。

总结

总的来说,NPD 是 Kubernetes 集群可观测性的重要组成部分,它通过检测和报告节点问题,帮助提高集群的稳定性和可靠性,同时结合观测云的平台,可以为用户提供一个全面、自动化的 Kubernetes 节点监控解决方案,帮助用户更好地管理和维护他们的集群。


观测云
21 声望85 粉丝

云时代的系统可观测平台