-
Notifications
You must be signed in to change notification settings - Fork 749
/
container_launch_priority_initialization.go
97 lines (86 loc) · 3.01 KB
/
container_launch_priority_initialization.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 mutating
import (
"context"
"strconv"
admissionv1 "k8s.io/api/admission/v1"
corev1 "k8s.io/api/core/v1"
storagenames "k8s.io/apiserver/pkg/storage/names"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
appspub "github.com/openkruise/kruise/apis/apps/pub"
utilcontainerlaunchpriority "github.com/openkruise/kruise/pkg/util/containerlaunchpriority"
)
// start containers based on priority order
func (h *PodCreateHandler) containerLaunchPriorityInitialization(_ context.Context, req admission.Request, pod *corev1.Pod) (skip bool, err error) {
if len(req.AdmissionRequest.SubResource) > 0 ||
req.AdmissionRequest.Operation != admissionv1.Create ||
req.AdmissionRequest.Resource.Resource != "pods" {
return true, nil
}
if len(pod.Spec.Containers) == 1 {
return true, nil
}
// if ordered flag has been set, then just process ordered logic and skip check for priority
if pod.Annotations[appspub.ContainerLaunchPriorityKey] == appspub.ContainerLaunchOrdered {
priority := make([]int, len(pod.Spec.Containers))
for i := range priority {
priority[i] = 0 - i
}
h.setPodEnv(priority, pod)
klog.V(3).Infof("Injected ordered container launch priority for Pod %s/%s", pod.Namespace, pod.Name)
return false, nil
}
// check whether containers have KRUISE_CONTAINER_PRIORITY key value pairs
priority, priorityFlag, err := h.getPriority(pod)
if err != nil {
return false, err
}
if !priorityFlag {
return true, nil
}
h.setPodEnv(priority, pod)
klog.V(3).Infof("Injected customized container launch priority for Pod %s/%s", pod.Namespace, pod.Name)
return false, nil
}
// the return []int is prioirty for each container in the pod, ordered as container
// order list in pod spec.
// the priorityFlag indicates whether this pod needs to launch containers with priority.
// return error is there is any (e.g. priority value less than minimum possible int value)
func (h *PodCreateHandler) getPriority(pod *corev1.Pod) ([]int, bool, error) {
var priorityFlag bool
var priority = make([]int, len(pod.Spec.Containers))
for i, c := range pod.Spec.Containers {
for _, e := range c.Env {
if e.Name == appspub.ContainerLaunchPriorityEnvName {
p, err := strconv.Atoi(e.Value)
if err != nil {
return nil, false, err
}
priority[i] = p
if p != 0 {
priorityFlag = true
}
}
}
}
// if all priorities are same, than no priority is needed
if priorityFlag {
var equityFlag = true
for _, v := range priority {
if v != priority[0] {
equityFlag = false
}
}
priorityFlag = !equityFlag
}
return priority, priorityFlag, nil
}
func (h *PodCreateHandler) setPodEnv(priority []int, pod *corev1.Pod) {
// Generate name for pods that only have generateName field
if len(pod.Name) == 0 && len(pod.GenerateName) > 0 {
pod.Name = storagenames.SimpleNameGenerator.GenerateName(pod.GenerateName)
}
for i := range priority {
pod.Spec.Containers[i].Env = append(pod.Spec.Containers[i].Env, utilcontainerlaunchpriority.GeneratePriorityEnv(priority[i], pod.Name))
}
}