/
node.go
97 lines (91 loc) · 2.29 KB
/
node.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package monitor
import (
"context"
"fmt"
"time"
corev1 "k8s.io/api/core/v1"
informercorev1 "k8s.io/client-go/informers/core/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/cache"
)
func startNodeMonitoring(ctx context.Context, m Recorder, client kubernetes.Interface) {
nodeChangeFns := []func(node, oldNode *corev1.Node) []Condition{
func(node, oldNode *corev1.Node) []Condition {
var conditions []Condition
for i := range node.Status.Conditions {
c := &node.Status.Conditions[i]
previous := findNodeCondition(oldNode.Status.Conditions, c.Type, i)
if previous == nil {
continue
}
if c.Status != previous.Status {
conditions = append(conditions, Condition{
Level: Warning,
Locator: locateNode(node),
Message: fmt.Sprintf("condition %s changed", c.Type),
})
}
}
if node.UID != oldNode.UID {
conditions = append(conditions, Condition{
Level: Error,
Locator: locateNode(node),
Message: fmt.Sprintf("node was deleted and recreated"),
})
}
return conditions
},
}
nodeInformer := informercorev1.NewNodeInformer(client, time.Hour, nil)
nodeInformer.AddEventHandler(
cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {},
DeleteFunc: func(obj interface{}) {
pod, ok := obj.(*corev1.Node)
if !ok {
return
}
m.Record(Condition{
Level: Warning,
Locator: locateNode(pod),
Message: "deleted",
})
},
UpdateFunc: func(old, obj interface{}) {
node, ok := obj.(*corev1.Node)
if !ok {
return
}
oldNode, ok := old.(*corev1.Node)
if !ok {
return
}
for _, fn := range nodeChangeFns {
m.Record(fn(node, oldNode)...)
}
},
},
)
m.AddSampler(func(now time.Time) []*Condition {
var conditions []*Condition
for _, obj := range nodeInformer.GetStore().List() {
node, ok := obj.(*corev1.Node)
if !ok {
continue
}
isReady := false
if c := findNodeCondition(node.Status.Conditions, corev1.NodeReady, 0); c != nil {
isReady = c.Status == corev1.ConditionTrue
}
if !isReady {
conditions = append(conditions, &Condition{
Level: Warning,
Locator: locateNode(node),
Message: "node is not ready",
})
}
}
return conditions
})
go nodeInformer.Run(ctx.Done())
}