@@ -23,11 +23,13 @@ import (
23
23
24
24
"k8s.io/api/core/v1"
25
25
"k8s.io/apimachinery/pkg/api/resource"
26
+ utilfeature "k8s.io/apiserver/pkg/util/feature"
27
+ "k8s.io/kubernetes/pkg/features"
26
28
)
27
29
28
30
// addResourceList adds the resources in newList to list
29
- func addResourceList (list , new v1.ResourceList ) {
30
- for name , quantity := range new {
31
+ func addResourceList (list , newList v1.ResourceList ) {
32
+ for name , quantity := range newList {
31
33
if value , ok := list [name ]; ! ok {
32
34
list [name ] = * quantity .Copy ()
33
35
} else {
@@ -53,7 +55,9 @@ func maxResourceList(list, new v1.ResourceList) {
53
55
}
54
56
55
57
// PodRequestsAndLimits returns a dictionary of all defined resources summed up for all
56
- // containers of the pod.
58
+ // containers of the pod. If PodOverhead feature is enabled, pod overhead is added to the
59
+ // total container resource requests and to the total container limits which have a
60
+ // non-zero quantity.
57
61
func PodRequestsAndLimits (pod * v1.Pod ) (reqs , limits v1.ResourceList ) {
58
62
reqs , limits = v1.ResourceList {}, v1.ResourceList {}
59
63
for _ , container := range pod .Spec .Containers {
@@ -65,37 +69,79 @@ func PodRequestsAndLimits(pod *v1.Pod) (reqs, limits v1.ResourceList) {
65
69
maxResourceList (reqs , container .Resources .Requests )
66
70
maxResourceList (limits , container .Resources .Limits )
67
71
}
72
+
73
+ // if PodOverhead feature is supported, add overhead for running a pod
74
+ // to the sum of reqeuests and to non-zero limits:
75
+ if pod .Spec .Overhead != nil && utilfeature .DefaultFeatureGate .Enabled (features .PodOverhead ) {
76
+ addResourceList (reqs , pod .Spec .Overhead )
77
+
78
+ for name , quantity := range pod .Spec .Overhead {
79
+ if value , ok := limits [name ]; ok && ! value .IsZero () {
80
+ value .Add (quantity )
81
+ limits [name ] = value
82
+ }
83
+ }
84
+ }
85
+
68
86
return
69
87
}
70
88
71
- // GetResourceRequest finds and returns the request for a specific resource.
72
- func GetResourceRequest (pod * v1.Pod , resource v1.ResourceName ) int64 {
73
- if resource == v1 .ResourcePods {
74
- return 1
89
+ // GetResourceRequestQuantity finds and returns the request quantity for a specific resource.
90
+ func GetResourceRequestQuantity (pod * v1.Pod , resourceName v1.ResourceName ) resource.Quantity {
91
+ requestQuantity := resource.Quantity {}
92
+
93
+ switch resourceName {
94
+ case v1 .ResourceCPU :
95
+ requestQuantity = resource.Quantity {Format : resource .DecimalSI }
96
+ case v1 .ResourceMemory , v1 .ResourceStorage , v1 .ResourceEphemeralStorage :
97
+ requestQuantity = resource.Quantity {Format : resource .BinarySI }
98
+ default :
99
+ requestQuantity = resource.Quantity {Format : resource .DecimalSI }
100
+ }
101
+
102
+ if resourceName == v1 .ResourceEphemeralStorage && ! utilfeature .DefaultFeatureGate .Enabled (features .LocalStorageCapacityIsolation ) {
103
+ // if the local storage capacity isolation feature gate is disabled, pods request 0 disk
104
+ return requestQuantity
75
105
}
76
- totalResources := int64 ( 0 )
106
+
77
107
for _ , container := range pod .Spec .Containers {
78
- if rQuantity , ok := container .Resources .Requests [resource ]; ok {
79
- if resource == v1 .ResourceCPU {
80
- totalResources += rQuantity .MilliValue ()
81
- } else {
82
- totalResources += rQuantity .Value ()
83
- }
108
+ if rQuantity , ok := container .Resources .Requests [resourceName ]; ok {
109
+ requestQuantity .Add (rQuantity )
84
110
}
85
111
}
86
- // take max_resource(sum_pod, any_init_container)
112
+
87
113
for _ , container := range pod .Spec .InitContainers {
88
- if rQuantity , ok := container .Resources .Requests [resource ]; ok {
89
- if resource == v1 .ResourceCPU {
90
- if rQuantity .MilliValue () > totalResources {
91
- totalResources = rQuantity .MilliValue ()
92
- }
93
- } else if rQuantity .Value () > totalResources {
94
- totalResources = rQuantity .Value ()
114
+ if rQuantity , ok := container .Resources .Requests [resourceName ]; ok {
115
+ if requestQuantity .Cmp (rQuantity ) < 0 {
116
+ requestQuantity = rQuantity .DeepCopy ()
95
117
}
96
118
}
97
119
}
98
- return totalResources
120
+
121
+ // if PodOverhead feature is supported, add overhead for running a pod
122
+ // to the total requests if the resource total is non-zero
123
+ if pod .Spec .Overhead != nil && utilfeature .DefaultFeatureGate .Enabled (features .PodOverhead ) {
124
+ if podOverhead , ok := pod .Spec .Overhead [resourceName ]; ok && ! requestQuantity .IsZero () {
125
+ requestQuantity .Add (podOverhead )
126
+ }
127
+ }
128
+
129
+ return requestQuantity
130
+ }
131
+
132
+ // GetResourceRequest finds and returns the request value for a specific resource.
133
+ func GetResourceRequest (pod * v1.Pod , resource v1.ResourceName ) int64 {
134
+ if resource == v1 .ResourcePods {
135
+ return 1
136
+ }
137
+
138
+ requestQuantity := GetResourceRequestQuantity (pod , resource )
139
+
140
+ if resource == v1 .ResourceCPU {
141
+ return requestQuantity .MilliValue ()
142
+ }
143
+
144
+ return requestQuantity .Value ()
99
145
}
100
146
101
147
// ExtractResourceValueByContainerName extracts the value of a resource
0 commit comments