@@ -19,10 +19,10 @@ package resourcemonitor
19
19
import (
20
20
"context"
21
21
"fmt"
22
+ "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos"
22
23
"strconv"
23
24
24
25
corev1 "k8s.io/api/core/v1"
25
- "k8s.io/apimachinery/pkg/api/resource"
26
26
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27
27
client "k8s.io/client-go/kubernetes"
28
28
"k8s.io/klog/v2"
@@ -57,58 +57,49 @@ func NewPodResourcesScanner(namespace string, podResourceClient podresourcesapi.
57
57
}
58
58
59
59
// isWatchable tells if the the given namespace should be watched.
60
- func (resMon * PodResourcesScanner ) isWatchable (podNamespace string , podName string , hasDevice bool ) (bool , bool , error ) {
61
- pod , err := resMon .k8sClient .CoreV1 ().Pods (podNamespace ).Get (context .TODO (), podName , metav1.GetOptions {})
60
+ // In Scan(), if watchable is false, this pods scan will skip
61
+ // so we can return directly if pod's namespace is not watchable
62
+ func (resMon * PodResourcesScanner ) isWatchable (podResource * podresourcesapi.PodResources ) (bool , bool , error ) {
63
+ if resMon .namespace != "*" && resMon .namespace != podResource .Namespace {
64
+ return false , false , nil
65
+ }
66
+
67
+ pod , err := resMon .k8sClient .CoreV1 ().Pods (podResource .Namespace ).Get (context .TODO (), podResource .Name , metav1.GetOptions {})
62
68
if err != nil {
63
69
return false , false , err
64
70
}
65
71
66
- isIntegralGuaranteed := pod .Status .QOSClass == corev1 .PodQOSGuaranteed && hasExclusiveCPUs (pod )
72
+ podHasExclusiveCPUs := hasExclusiveCPUs (pod )
73
+ isPodGuaranteed := qos .GetPodQOS (pod ) == corev1 .PodQOSGuaranteed
67
74
68
- if resMon .namespace == "*" && (isIntegralGuaranteed || hasDevice ) {
69
- return true , isIntegralGuaranteed , nil
70
- }
71
- // TODO: add an explicit check for guaranteed pods and pods with devices
72
- return resMon .namespace == podNamespace && (isIntegralGuaranteed || hasDevice ), isIntegralGuaranteed , nil
75
+ return isPodGuaranteed || hasDevice (podResource ), podHasExclusiveCPUs , nil
73
76
}
74
77
75
78
// hasExclusiveCPUs returns true if a guaranteed pod is allocated exclusive CPUs else returns false.
76
79
// In isWatchable() function we check for the pod QoS and proceed if it is guaranteed (i.e. request == limit)
77
80
// and hence we only check for request in the function below.
78
81
func hasExclusiveCPUs (pod * corev1.Pod ) bool {
79
- var totalCPU int64
80
- var cpuQuantity resource.Quantity
81
82
for _ , container := range pod .Spec .InitContainers {
82
-
83
- var ok bool
84
- if cpuQuantity , ok = container .Resources .Requests [corev1 .ResourceCPU ]; ! ok {
85
- continue
86
- }
87
- totalCPU += cpuQuantity .Value ()
88
- isInitContainerGuaranteed := hasIntegralCPUs (& container )
89
- if isInitContainerGuaranteed {
83
+ if hasIntegralCPUs (& container ) {
90
84
return true
91
85
}
92
86
}
93
87
for _ , container := range pod .Spec .Containers {
94
- var ok bool
95
- if cpuQuantity , ok = container .Resources .Requests [corev1 .ResourceCPU ]; ! ok {
96
- continue
97
- }
98
- totalCPU += cpuQuantity .Value ()
99
- isAppContainerGuaranteed := hasIntegralCPUs (& container )
100
- if isAppContainerGuaranteed {
88
+ if hasIntegralCPUs (& container ) {
101
89
return true
102
90
}
103
91
}
104
92
105
- //No CPUs requested in all the containers in the pod
93
+ //No integralCPUs requested in all the containers of the pod
106
94
return false
107
95
}
108
96
109
97
// hasIntegralCPUs returns true if a container in pod is requesting integral CPUs else returns false
110
98
func hasIntegralCPUs (container * corev1.Container ) bool {
111
- cpuQuantity := container .Resources .Requests [corev1 .ResourceCPU ]
99
+ cpuQuantity , ok := container .Resources .Requests [corev1 .ResourceCPU ]
100
+ if ! ok {
101
+ return false
102
+ }
112
103
return cpuQuantity .Value ()* 1000 == cpuQuantity .MilliValue ()
113
104
}
114
105
@@ -146,8 +137,7 @@ func (resMon *PodResourcesScanner) Scan() (ScanResponse, error) {
146
137
147
138
for _ , podResource := range respPodResources {
148
139
klog .InfoS ("scanning pod" , "podName" , podResource .GetName ())
149
- hasDevice := hasDevice (podResource )
150
- isWatchable , isIntegralGuaranteed , err := resMon .isWatchable (podResource .GetNamespace (), podResource .GetName (), hasDevice )
140
+ isWatchable , isExclusiveCPUs , err := resMon .isWatchable (podResource )
151
141
if err != nil {
152
142
return ScanResponse {}, fmt .Errorf ("checking if pod in a namespace is watchable, namespace:%v, pod name %v: %w" , podResource .GetNamespace (), podResource .GetName (), err )
153
143
}
@@ -166,7 +156,7 @@ func (resMon *PodResourcesScanner) Scan() (ScanResponse, error) {
166
156
}
167
157
168
158
cpuIDs := container .GetCpuIds ()
169
- if len (cpuIDs ) > 0 && isIntegralGuaranteed {
159
+ if len (cpuIDs ) > 0 && isExclusiveCPUs {
170
160
var resCPUs []string
171
161
for _ , cpuID := range container .GetCpuIds () {
172
162
resCPUs = append (resCPUs , strconv .FormatInt (cpuID , 10 ))
0 commit comments