背景
当 Kubernetes 中节点发生如下问题时,在整个集群中,K8S 服务组件并不会感知这些问题,就会导致 Pod 仍会调度至问题节点。所以就需要一个检测机制来检测上述问题。
- 基础服务问题:NTP 服务挂了;
- 硬件问题:CPU,内存或磁盘损坏;
- 内核问题:内核死锁,文件系统损坏;
- 容器运行时问题:运行时守护程序无响应。
node-problem-detector
https://github.com/kubernetes/node-problem-detector
node-problem-detector是集群节点的健康监测组件。以 DaemonSet 方式运行,帮助用户实时检测节点上的各种异常情况,并将检测结果报告给上游的 Kube-apiserver。
故障种类
故障上报
node-problem-detector 通过设置 NodeCondition 或者创建 Event 对象来汇报问题。
- Nodecondition:针对永久性故障,会通过设置NodeCondition 来改变节点状态。
- Event:临时故障通过 Event 来提醒相关对象,比如通知当前节点运行的所有 Pod。
自定义npd插件
创建 node-strick-detector.yaml,并在控制平面节点上保存配置到插件 Pod 的目录 /etc/kubernetes/addons/node-problem-detector。这样在集群引导时pod就会自动加载出来了。
npd的异常处理行为
- NPD 只负责获取异常事件,并修改 node condition,不会对节点状态和调度产生影响。
lastHeartbeatTime: "2022-04-02T15:44:46Z" lastTransitionTime: "2022-04-02T15:29:43Z" message: 'kernel: INFO: task docker:20744 blocked for more than 120 seconds." reason: DockerHung status: "True" type: KernelDeadlock
- 需要自定义控制器,监听 NPD 汇报的 condition, taint node,阻止 Pod 调度到故障节点。
- 问题修复后,重启 NPD pod 来清理错误事件。
安装
使用helm进行安装。
# 添加repo源
helm repo add deliveryhero https://charts.deliveryhero.io/
# 搜索repo
helm search repo node-problem-detector
# 安装
helm install npd deliveryhero/node-problem-detector
# 查看npd
helm list
# 查看pod
k get po
# 发现pod都是ImagePullBackOff或者ErrImagePull状态,由于使用了k8s.gcr.io/node-problem-detector/node-problem-detector:v0.8.10镜像,国内是无法访问k8s.gcr.io的。
# 编辑ds
k edit ds npd-node-problem-detector -o yaml
# 替换镜像
修改为lank8s.cn/node-problem-detector/node-problem-detector:v0.8.10
# 再次查看pod,运行正常
k get po
部署在集群内的 Kubernetes 对象
k get ds | grep npd-node-problem-detector
k get clusterrole | grep npd-node-problem-detector
k get clusterrolebinding | grep npd-node-problem-detector
k get sa | grep npd-node-problem-detector
k get secret | grep npd-node-problem-detector
查看ClusterRoleBinding具体内容
测试
# 查看当前node情况,event为空。
k describe node node1
# 添加kernel bug到/dev/kmsg
sudo sh -c "echo 'kernel: BUG: unable to handle kernel NULL pointer dereference at TESTING' >> /dev/kmsg"
cat /dev/kmsg
# 查看当前node情况,event中显示了添加的kernel bug。
k describe node node1
# 通过KernelOops的event上报给了apiserver。
# 再次添加
sudo sh -c "echo 'kernel: BUG: unable to handle kernel NULL pointer dereference at TESTING2' >> /dev/kmsg"
# 查看当前node情况,event中显示了添加的kernel bug2。
k describe node node1