sigs.k8s.io/kueue@v0.6.2/apis/kueue/v1beta1/workload_types.go (about) 1 /* 2 Copyright 2023 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package v1beta1 18 19 import ( 20 corev1 "k8s.io/api/core/v1" 21 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 22 ) 23 24 // WorkloadSpec defines the desired state of Workload 25 type WorkloadSpec struct { 26 // podSets is a list of sets of homogeneous pods, each described by a Pod spec 27 // and a count. 28 // There must be at least one element and at most 8. 29 // podSets cannot be changed. 30 // 31 // +listType=map 32 // +listMapKey=name 33 // +kubebuilder:validation:MaxItems=8 34 // +kubebuilder:validation:MinItems=1 35 PodSets []PodSet `json:"podSets"` 36 37 // queueName is the name of the LocalQueue the Workload is associated with. 38 // queueName cannot be changed while .status.admission is not null. 39 QueueName string `json:"queueName,omitempty"` 40 41 // If specified, indicates the workload's priority. 42 // "system-node-critical" and "system-cluster-critical" are two special 43 // keywords which indicate the highest priorities with the former being 44 // the highest priority. Any other name must be defined by creating a 45 // PriorityClass object with that name. If not specified, the workload 46 // priority will be default or zero if there is no default. 47 PriorityClassName string `json:"priorityClassName,omitempty"` 48 49 // Priority determines the order of access to the resources managed by the 50 // ClusterQueue where the workload is queued. 51 // The priority value is populated from PriorityClassName. 52 // The higher the value, the higher the priority. 53 // If priorityClassName is specified, priority must not be null. 54 Priority *int32 `json:"priority,omitempty"` 55 56 // priorityClassSource determines whether the priorityClass field refers to a pod PriorityClass or kueue.x-k8s.io/workloadpriorityclass. 57 // Workload's PriorityClass can accept the name of a pod priorityClass or a workloadPriorityClass. 58 // When using pod PriorityClass, a priorityClassSource field has the scheduling.k8s.io/priorityclass value. 59 // +kubebuilder:default="" 60 // +kubebuilder:validation:Enum=kueue.x-k8s.io/workloadpriorityclass;scheduling.k8s.io/priorityclass;"" 61 PriorityClassSource string `json:"priorityClassSource,omitempty"` 62 63 // Active determines if a workload can be admitted into a queue. 64 // Changing active from true to false will evict any running workloads. 65 // Possible values are: 66 // 67 // - false: indicates that a workload should never be admitted and evicts running workloads 68 // - true: indicates that a workload can be evaluated for admission into it's respective queue. 69 // 70 // Defaults to true 71 // +kubebuilder:default=true 72 Active *bool `json:"active,omitempty"` 73 } 74 75 type Admission struct { 76 // clusterQueue is the name of the ClusterQueue that admitted this workload. 77 ClusterQueue ClusterQueueReference `json:"clusterQueue"` 78 79 // PodSetAssignments hold the admission results for each of the .spec.podSets entries. 80 // +listType=map 81 // +listMapKey=name 82 PodSetAssignments []PodSetAssignment `json:"podSetAssignments"` 83 } 84 85 type PodSetAssignment struct { 86 // Name is the name of the podSet. It should match one of the names in .spec.podSets. 87 // +kubebuilder:default=main 88 Name string `json:"name"` 89 90 // Flavors are the flavors assigned to the workload for each resource. 91 Flavors map[corev1.ResourceName]ResourceFlavorReference `json:"flavors,omitempty"` 92 93 // resourceUsage keeps track of the total resources all the pods in the podset need to run. 94 // 95 // Beside what is provided in podSet's specs, this calculation takes into account 96 // the LimitRange defaults and RuntimeClass overheads at the moment of admission. 97 // This field will not change in case of quota reclaim. 98 ResourceUsage corev1.ResourceList `json:"resourceUsage,omitempty"` 99 100 // count is the number of pods taken into account at admission time. 101 // This field will not change in case of quota reclaim. 102 // Value could be missing for Workloads created before this field was added, 103 // in that case spec.podSets[*].count value will be used. 104 // 105 // +optional 106 // +kubebuilder:validation:Minimum=0 107 Count *int32 `json:"count,omitempty"` 108 } 109 110 type PodSet struct { 111 // name is the PodSet name. 112 Name string `json:"name"` 113 114 // template is the Pod template. 115 // 116 // The only allowed fields in template.metadata are labels and annotations. 117 // 118 // If requests are omitted for a container or initContainer, 119 // they default to the limits if they are explicitly specified for the 120 // container or initContainer. 121 // 122 // During admission, the rules in nodeSelector and 123 // nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution that match 124 // the keys in the nodeLabels from the ResourceFlavors considered for this 125 // Workload are used to filter the ResourceFlavors that can be assigned to 126 // this podSet. 127 Template corev1.PodTemplateSpec `json:"template"` 128 129 // count is the number of pods for the spec. 130 // +kubebuilder:validation:Minimum=1 131 Count int32 `json:"count"` 132 133 // minCount is the minimum number of pods for the spec acceptable 134 // if the workload supports partial admission. 135 // 136 // If not provided, partial admission for the current PodSet is not 137 // enabled. 138 // 139 // Only one podSet within the workload can use this. 140 // 141 // This is an alpha field and requires enabling PartialAdmission feature gate. 142 // 143 // +optional 144 MinCount *int32 `json:"minCount,omitempty"` 145 } 146 147 // WorkloadStatus defines the observed state of Workload 148 type WorkloadStatus struct { 149 // admission holds the parameters of the admission of the workload by a 150 // ClusterQueue. admission can be set back to null, but its fields cannot be 151 // changed once set. 152 Admission *Admission `json:"admission,omitempty"` 153 154 // requeueState holds the re-queue state 155 // when a workload meets Eviction with PodsReadyTimeout reason. 156 // 157 // +optional 158 RequeueState *RequeueState `json:"requeueState,omitempty"` 159 160 // conditions hold the latest available observations of the Workload 161 // current state. 162 // 163 // The type of the condition could be: 164 // 165 // - Admitted: the Workload was admitted through a ClusterQueue. 166 // - Finished: the associated workload finished running (failed or succeeded). 167 // - PodsReady: at least `.spec.podSets[*].count` Pods are ready or have 168 // succeeded. 169 // 170 // +optional 171 // +listType=map 172 // +listMapKey=type 173 // +patchStrategy=merge 174 // +patchMergeKey=type 175 Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` 176 177 // reclaimablePods keeps track of the number pods within a podset for which 178 // the resource reservation is no longer needed. 179 // +optional 180 // +listType=map 181 // +listMapKey=name 182 ReclaimablePods []ReclaimablePod `json:"reclaimablePods,omitempty"` 183 184 // admissionChecks list all the admission checks required by the workload and the current status 185 // +optional 186 // +listType=map 187 // +listMapKey=name 188 // +patchStrategy=merge 189 // +patchMergeKey=name 190 AdmissionChecks []AdmissionCheckState `json:"admissionChecks,omitempty" patchStrategy:"merge" patchMergeKey:"name"` 191 } 192 193 type RequeueState struct { 194 // count records the number of times a workload has been re-queued 195 // When a deactivated (`.spec.activate`=`false`) workload is reactivated (`.spec.activate`=`true`), 196 // this count would be reset to null. 197 // 198 // +optional 199 // +kubebuilder:validation:Minimum=0 200 Count *int32 `json:"count,omitempty"` 201 202 // requeueAt records the time when a workload will be re-queued. 203 // When a deactivated (`.spec.activate`=`false`) workload is reactivated (`.spec.activate`=`true`), 204 // this time would be reset to null. 205 // 206 // +optional 207 RequeueAt *metav1.Time `json:"requeueAt,omitempty"` 208 } 209 210 type AdmissionCheckState struct { 211 // name identifies the admission check. 212 // +required 213 // +kubebuilder:validation:Required 214 // +kubebuilder:validation:MaxLength=316 215 Name string `json:"name"` 216 // state of the admissionCheck, one of Pending, Ready, Retry, Rejected 217 // +required 218 // +kubebuilder:validation:Required 219 // +kubebuilder:validation:Enum=Pending;Ready;Retry;Rejected 220 State CheckState `json:"state"` 221 // lastTransitionTime is the last time the condition transitioned from one status to another. 222 // This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. 223 // +required 224 // +kubebuilder:validation:Required 225 // +kubebuilder:validation:Type=string 226 // +kubebuilder:validation:Format=date-time 227 LastTransitionTime metav1.Time `json:"lastTransitionTime"` 228 // message is a human readable message indicating details about the transition. 229 // This may be an empty string. 230 // +required 231 // +kubebuilder:validation:Required 232 // +kubebuilder:validation:MaxLength=32768 233 Message string `json:"message" protobuf:"bytes,6,opt,name=message"` 234 235 // +optional 236 // +listType=atomic 237 PodSetUpdates []PodSetUpdate `json:"podSetUpdates,omitempty"` 238 } 239 240 // PodSetUpdate contains a list of pod set modifications suggested by AdmissionChecks. 241 // The modifications should be additive only - modifications of already existing keys 242 // or having the same key provided by multiple AdmissionChecks is not allowed and will 243 // result in failure during workload admission. 244 type PodSetUpdate struct { 245 // Name of the PodSet to modify. Should match to one of the Workload's PodSets. 246 // +required 247 // +kubebuilder:validation:Required 248 Name string `json:"name"` 249 250 // +optional 251 Labels map[string]string `json:"labels,omitempty"` 252 253 // +optional 254 Annotations map[string]string `json:"annotations,omitempty"` 255 256 // +optional 257 NodeSelector map[string]string `json:"nodeSelector,omitempty"` 258 259 // +optional 260 Tolerations []corev1.Toleration `json:"tolerations,omitempty"` 261 } 262 263 type ReclaimablePod struct { 264 // name is the PodSet name. 265 Name string `json:"name"` 266 267 // count is the number of pods for which the requested resources are no longer needed. 268 // +kubebuilder:validation:Minimum=0 269 Count int32 `json:"count"` 270 } 271 272 const ( 273 // WorkloadAdmitted means that the Workload has reserved quota and all the admissionChecks 274 // defined in the ClusterQueue are satisfied. 275 WorkloadAdmitted = "Admitted" 276 277 // WorkloadQuotaReserved means that the Workload has reserved quota a ClusterQueue. 278 WorkloadQuotaReserved = "QuotaReserved" 279 280 // WorkloadFinished means that the workload associated to the 281 // ResourceClaim finished running (failed or succeeded). 282 WorkloadFinished = "Finished" 283 284 // WorkloadPodsReady means that at least `.spec.podSets[*].count` Pods are 285 // ready or have succeeded. 286 WorkloadPodsReady = "PodsReady" 287 288 // WorkloadEvicted means that the Workload was evicted by a ClusterQueue 289 WorkloadEvicted = "Evicted" 290 ) 291 292 const ( 293 // WorkloadEvictedByPreemption indicates that the workload was evicted 294 // in order to free resources for a workload with a higher priority. 295 WorkloadEvictedByPreemption = "Preempted" 296 297 // WorkloadEvictedByPodsReadyTimeout indicates that the eviction took 298 // place due to a PodsReady timeout. 299 WorkloadEvictedByPodsReadyTimeout = "PodsReadyTimeout" 300 301 // WorkloadEvictedByAdmissionCheck indicates that the workload was evicted 302 // because at least one admission check transitioned to False. 303 WorkloadEvictedByAdmissionCheck = "AdmissionCheck" 304 305 // WorkloadEvictedByClusterQueueStopped indicates that the workload was evicted 306 // because the ClusterQueue is Stopped. 307 WorkloadEvictedByClusterQueueStopped = "ClusterQueueStopped" 308 309 // WorkloadEvictedByDeactivation indicates that the workload was evicted 310 // because spec.active is set to false. 311 WorkloadEvictedByDeactivation = "InactiveWorkload" 312 ) 313 314 // +genclient 315 // +kubebuilder:object:root=true 316 // +kubebuilder:storageversion 317 // +kubebuilder:subresource:status 318 // +kubebuilder:printcolumn:name="Queue",JSONPath=".spec.queueName",type=string,description="Name of the queue this workload was submitted to" 319 // +kubebuilder:printcolumn:name="Admitted by",JSONPath=".status.admission.clusterQueue",type=string,description="Name of the ClusterQueue that admitted this workload" 320 // +kubebuilder:printcolumn:name="Age",JSONPath=".metadata.creationTimestamp",type=date,description="Time this workload was created" 321 // +kubebuilder:resource:shortName={wl} 322 323 // Workload is the Schema for the workloads API 324 type Workload struct { 325 metav1.TypeMeta `json:",inline"` 326 metav1.ObjectMeta `json:"metadata,omitempty"` 327 328 Spec WorkloadSpec `json:"spec,omitempty"` 329 Status WorkloadStatus `json:"status,omitempty"` 330 } 331 332 // +kubebuilder:object:root=true 333 334 // WorkloadList contains a list of ResourceClaim 335 type WorkloadList struct { 336 metav1.TypeMeta `json:",inline"` 337 metav1.ListMeta `json:"metadata,omitempty"` 338 Items []Workload `json:"items"` 339 } 340 341 func init() { 342 SchemeBuilder.Register(&Workload{}, &WorkloadList{}) 343 }