简介
官方文档库地址:https://github.com/kubernetes/node-problem-detector
node-problem-detector 旨在使集群管理堆栈中的上游层能够看到各种节点问题。它是一个在每个节点上运行的守护进程,检测节点问题并将其报告给apiserver。
node-problem-detector 可以作为 DaemonSet 运行,也可以独立运行。现在它作为 GKE集群中默认启用的Kubernetes Addon运行。它也作为AKS Linux Extension的一部分在 AKS 中默认启用。
背景
大量节点问题可能会影响节点上运行的 pod,例如:
- 基础设施守护进程问题:ntp 服务关闭;
- 硬件问题:CPU、内存或磁盘损坏;
- 内核问题:内核死锁、文件系统损坏;
- 容器运行时问题:运行时守护进程无响应;
- …
目前,这些问题对于集群管理堆栈中的上游层是不可见的,因此 Kubernetes 将继续将 pod 调度到坏节点。
为了解决这个问题,我们引入了这个新的守护进程node-problem-detector来从各种守护进程收集节点问题,并将它们提供给上游层。一旦上游层能够看到这些问题,我们就可以讨论 remedy systems了。
Problem API
node-problem-detector 使用Event并向NodeConditionapiserver 报告问题。
- NodeCondition:导致节点无法用于 pod 的永久性问题应报告为NodeCondition。
- Event:对 pod 影响有限但具有参考意义的临时问题应报告为Event。
Problem Daemon
问题守护进程是 node-problem-detector 的一个子守护进程。它监视特定类型的节点问题并将其报告给 node-problem-detector。
守护进程可能是:
- 专为 Kubernetes 专用用例设计的微型守护进程。
- 与节点问题检测器集成的现有节点健康监控守护进程。
目前,问题守护进程在 node-problem-detector 二进制文件中以 goroutine 的形式运行。未来,我们会将 node-problem-detector和问题守护进程分离到不同的容器中,并使用 pod 规范将它们组合在一起。
每种类型的问题守护进程都可以通过设置相应的构建标签在编译时禁用。如果在编译时禁用它们,则它们的所有构建依赖项、全局变量和后台goroutine 都将从编译的可执行文件中剔除。
支持的守护进程列表:
问题守护进程类型 | 节点状态 | 解释 | 配置 | 禁用构建标签 |
---|---|---|---|---|
SystemLogMonitor | KernelDeadlock ReadonlyFilesystem FrequentKubeletRestart FrequentDockerRestart FrequentContainerdRestart | 系统日志监视器监视系统日志并根据预定义的规则报告问题和指标。 | filelog, kmsg, kernel, abrt, systemd | disable_system_log_monitor |
SystemStatsMonitor | None(Could be added in the future) | 节点问题检测器的系统统计监视器,用于收集各种与健康相关的系统统计信息作为指标。请参阅此处的提案。 | system-stats-monitor | disable_system_stats_monitor |
CustomPluginMonitor | On-demand(According to users configuration), existing example: NTPProblem | 一个自定义的 node-problem-detector 插件监控器,用于调用和检查各种节点问题,并使用用户定义的检查脚本。请参阅此处的提案。 | example | disable_custom_plugin_monitor |
HealthChecker | KubeletUnhealthy ContainerRuntimeUnhealthy | 节点问题检测器的健康检查器用于检查 kubelet 和容器运行时的健康状况。 | kubelet docker containerd | Helm |
Exporter
exporter 是 node-problem-detector 的一个组件。它向某些后端报告节点问题 和/或 指标。其中一些可以在编译时使用构建标记禁用。支持的导出器列表:
Exporter | 解释 | 禁用构建标签 |
---|---|---|
Kubernetes exporter | Kubernetes 导出器向 Kubernetes API 服务器报告节点问题:临时问题报告为事件,永久问题报告为节点状况。 | |
Prometheus exporter | Prometheus 导出器将节点问题和指标本地报告为 Prometheus 指标 | |
Stackdriver exporter | Stackdriver 导出器向 Stackdriver Monitoring API 报告节点问题和指标。 | disable_stackdriver_exporter |
用法
标志
- –version:打印节点问题检测器的当前版本。
- –hostname-override:node-problem-detector 用于更新状态和发出事件的自定义节点名称。node-problem-detector 首先从hostname-override获取节点名称,然后从NODE_NAME环境变量 获取,最后返回到os.Hostname。
对于系统日志监控
–config.system-log-monitor:系统日志监视器配置文件路径列表,以逗号分隔,例如 config/kernel-monitor.json。节点问题检测器将为每个配置启动单独的日志监视器。您可以使用不同的日志监视器来监视不同的系统日志。
对于系统统计监控
–config.system-stats-monitor:系统统计监控配置文件的路径列表,以逗号分隔,例如 config/system-stats-monitor.json。节点问题检测器将为每个配置启动一个单独的系统统计监控器。您可以使用不同的系统统计监控器来监控与问题相关的不同系统统计信息。
对于自定义插件监视器
–config.custom-plugin-monitor:自定义插件监控配置文件路径列表,以逗号分隔,例如 config/custom-plugin-monitor.json。节点问题检测器将为每个配置启动一个单独的自定义插件监控。您可以使用不同的自定义插件监控来监控不同的节点问题。
对于健康检查者
- –enable-k8s-exporter:启用向 Kubernetes API 服务器报告,默认为true。
- –apiserver-override:用于自定义 node-problem-detector 如何连接 apiserver 的 URI
参数。如果–enable-k8s-exporter是,则忽略此参数。格式与Heapster 的标志false相同。例如,要无需身份验证即可运行,请使用以下配置: source
http://APISERVER_IP:APISERVER_PORT?inClusterConfig=false
请参阅heapster 文档
以获取可用选项的完整列表。
- –address:绑定节点问题检测服务器的地址。
- –port:绑定节点问题检测服务器的端口。使用 0 表示禁用。
对于 Prometheus exporter
- –prometheus-address:绑定Prometheus抓取端点的地址,默认为127.0.0.1。
- –prometheus-port:绑定 Prometheus 抓取端点的端口,默认为 20257。使用 0 表示禁用。
对于 Stackdriver exporter
–exporter.stackdriver:Stackdriver
导出器配置文件的路径,例如config/exporter/stackdriver-exporter.json,默认为空字符串。设置为空字符串即可禁用。
已弃用的标志
-
–system-log-monitors:系统日志监控配置文件的路径列表,以逗号分隔。此选项已弃用,由–config.system-log-monitor替代,并将被删除。如果同时设置–system-log-monitors和 --config.system-log-monitor , NPD 将崩溃。
-
–custom-plugin-monitors:自定义插件监控配置文件的路径列表,以逗号分隔。此选项已弃用,由–config.custom-plugin-monitor替代,并将被删除。如果同时设置–custom-plugin-monitors和 --config.custom-plugin-monitor,NPD 将崩溃。
构建镜像
- 安装libsystemdARM GCC 工具链的开发依赖项
- Debian / Ubuntu:apt install libsystemd-dev gcc-aarch64-linux-gnu
- git clone git@github.com:kubernetes/node-problem-detector.git
- 在顶层目录中运行make。它将:
- 构建二进制文件。
- 构建docker镜像。二进制文件和config/被复制到docker镜像中。
如果您不需要某些类别的问题守护进程,您可以选择在编译时禁用它们。这是保持 node-problem-detector运行时紧凑且没有不必要代码(例如全局变量、goroutines 等)的最佳方法。
您可以通过BUILD_TAGS在运行之前设置环境变量来实现这一点make。例如:
BUILD_TAGS="disable_custom_plugin_monitor disable_system_stats_monitor" make
上述命令将在不使用自定义插件监视器和系统统计监视器的情况下编译node-problem-detector 。查看问题守护进程部分,了解如何在编译时禁用每个问题守护进程。
推送镜像
make push
将 docker 镜像上传到注册表。默认情况下,镜像将上传到 staging-k8s.gcr.io
。可以轻松修改Makefile
以将镜像推送到另一个注册表。
安装
将 node-problem-detector
安装到集群中的最简单方法是使用Helm 图表:
helm repo add deliveryhero https://charts.deliveryhero.io/
helm install --generate-name deliveryhero/node-problem-detector
或者,手动安装 node-problem-detector:
编辑node-problem-detector.yaml以适应您的环境。将log
卷设置为您的系统日志目录(由 SystemLogMonitor 使用)。您可以使用 ConfigMap 覆盖config
pod 内的目录。
编辑node-problem-detector-config.yaml来配置 node-problem-detector。
- 编辑rbac.yaml以适合您的环境。
- 使用 创建 ServiceAccount 和 ClusterRoleBinding
kubectl create -f rbac.yaml
。 - 使用 创建 ConfigMap
kubectl create -f node-problem-detector-config.yaml
。 - 使用 创建 DaemonSet
kubectl create -f node-problem-detector.yaml
。
开始独立运行
要独立运行 node-problem-detector,您应该设置inClusterConfig为false,并且教 node-problem-detector 如何 访问 apiserver,也就是apiserver-override。
要使用不安全的 apiserver 连接独立运行 node-problem-detector:
node-problem-detector --apiserver-override=http://APISERVER_IP:APISERVER_INSECURE_PORT?inClusterConfig=false
更多场景请见此处
试用
您可以在正在运行的集群中尝试使用 node-problem-detector,方法是将消息注入到 node-problem-detector 正在监视的日志中。
例如,假设 node-problem-detector 正在使用KernelMonitor。在您的机器上运行kubectl get events -w
。在节点上运行sudo sh -c "echo 'kernel: BUG: unable to handle kernel NULL pointer dereference at TESTING' >> /dev/kmsg"
。然后您应该会看到该KernelOopss事件。
添加新规则或开发节点问题检测器时,在独立模式下在本地工作站上进行测试可能更容易。对于 API 服务器,一种简单的方法是使用kubectl proxy正在运行的集群的 API 服务器在本地可用。您会收到一些错误,因为 API 服务器无法识别您的本地工作站。但无论如何,您仍然应该能够测试您的新规则。
例如,测试KernelMonitor规则:
make
(本地构建node-problem-detector)kubectl proxy --port=8080
(使正在运行的集群的 API 服务器在本地可用)- 将KernelMonitor更新到您的本地内核日志目录
logPath
。例如,在某些 Linux 系统上,它是/run/log/journal
而不是/var/log/journal
。 ./bin/node-problem-detector --logtostderr --apiserver-override=http://127.0.0.1:8080?inClusterConfig=false --config.system-log-monitor=config/kernel-monitor.json --config.system-stats-monitor=config/system-stats-monitor.json --port=20256 --prometheus-port=2025
(或指向任何 API 服务器地址:端口和 Prometheus 端口)sudo sh -c "echo 'kernel: BUG: unable to handle kernel NULL pointer dereference at TESTING' >> /dev/kmsg"
- 您可以
KernelOops
在节点问题检测器日志中看到事件。 sudo sh -c "echo 'kernel: INFO: task docker:20744 blocked for more than 120 seconds.' >> /dev/kmsg"
- 您可以在node-problem-detector log看
DockerHung
event和状态 - 您可以在http://127.0.0.1:20256/conditions查看
DockerHung
状态 - 您可以在http://127.0.0.1:20257/metrics上查看 Prometheus 格式的磁盘相关系统指标。
注:
您可以在test/kernel_log_generator/problems下查看更多规则示例。
- 对于KernelMonitor
消息注入,所有消息都应该有kernel:
前缀(另请注意,后面有一个空格:);或者使用generator.sh。 - 要将其他日志(如 systemd 日志)注入 journald,请使用
echo 'Some systemd message' | systemd-cat -t systemd
。
Remedy Systems
Remedy Systems是一个或多个旨在尝试解决node-problem-detector检测到的问题的过程。Remedy Systems会观察node-problem-detector发出的事件 和/或
节点状况,并采取措施使 Kubernetes 集群恢复健康状态。补救系统有以下几种:
- Draino 根据标签和节点条件自动排空 Kubernetes节点。与所有提供的标签和任何提供的节点条件匹配的节点将被阻止立即接受新 pod(也称为“封锁”),并在可配置的时间后排空。Draino可以与 Cluster Autoscaler结合使用,以自动终止排空的节点。请参阅 此问题 ,了解 Draino的示例生产用例。
- Descheduler
取消调度策略RemovePodsViolatingNodeTaints会驱逐节点上违反NoSchedule污染的Pod。必须启用k8s调度程序的TaintNodesByCondition功能。Cluster Autoscaler
可用于自动终止耗尽的节点。 - mediK8S
是一个基于Node Health Check Operator (NHC)构建的自动修复系统的总体项目,该系统监控节点状况并使用修复 API将修复委托给外部修复程序。Poison-Pill是一个修复程序,它将重新启动节点并确保所有有状态的工作负载都得到重新安排。如果集群具有足够的健康容量,NHC支持有条件地进行修复,或者手动暂停任何操作以最大限度地减少集群中断。 - Cluster API 的MachineHealthCheck负责修复不健康的机器。