/
liveness-handler.go
85 lines (74 loc) · 2.34 KB
/
liveness-handler.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
package handlers
import (
"context"
"fmt"
"hitachienergy.com/cr-operator/util"
"k8s.io/apimachinery/pkg/types"
"net/http"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
"strings"
"time"
)
var livenessHandler = make(map[types.UID]struct{})
var kClient client.Client
func NotifyLivenessHandler(client client.Client, newId types.UID) {
kClient = client
if _, ok := livenessHandler[newId]; !ok {
// we only need to start a new goroutine if the config is new
livenessHandler[newId] = struct{}{}
log.Log.Info("starting liveness handler")
go handleLivenessProbe(util.ConfigMap[newId])
}
}
func handleLivenessProbe(config *util.ConfigMapEntry) {
probeFailures := make(map[string]int)
startTime := time.Now().Unix()
for {
currentTime := time.Now().Unix()
if int(currentTime-startTime) < config.LivenessProbe.Interval {
duration := time.Duration(((int64)(config.LivenessProbe.Interval) - (currentTime - startTime)) * 1_000_000_000)
time.Sleep(duration)
continue
}
// reset start time for next loop
startTime = currentTime
for _, pod := range config.Pods {
if pod.Deleted {
delete(probeFailures, pod.Uid)
continue
}
if pod.Ip == "" {
continue
}
address := fmt.Sprintf("http://%s:%d/%s", pod.Ip, config.LivenessProbe.Port, strings.TrimPrefix(config.LivenessProbe.Path, "/"))
resp, err := livenessRequest(address)
if err == nil && resp.StatusCode >= 200 && resp.StatusCode < 400 {
probeFailures[pod.Uid] = 0
continue
}
if err != nil {
log.Log.Info("error while checking liveness", "error", err)
} else {
log.Log.Info("error while checking liveness", "code", resp.StatusCode, "status", resp.Status)
}
probeFailures[pod.Uid]++
if probeFailures[pod.Uid] != 3 {
continue
}
log.Log.Info("deleting Pod", "pod", pod.Name, "host", pod.HostIp, "pod.kref", pod.KRef.Name)
podName := util.CreatePod(kClient, context.Background(), config.LabelSelector, pod)
util.RestorePods[podName].OldPod = pod.KRef
}
}
}
func livenessRequest(address string) (*http.Response, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, "GET", address, nil)
if err != nil {
log.Log.Error(err, "error creating request")
return nil, err
}
return http.DefaultClient.Do(req)
}