@@ -17,51 +17,211 @@ limitations under the License.
17
17
package v1alpha1
18
18
19
19
import (
20
+ v1 "k8s.io/api/core/v1"
20
21
"k8s.io/apimachinery/pkg/api/resource"
21
22
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
22
23
capi "sigs.k8s.io/cluster-api/api/v1beta1"
23
24
)
24
25
25
26
// NodePoolSpec defines the configuration for a Karpenter NodePool
26
27
type NodePoolSpec struct {
27
- // Disruption specifies the disruption behavior for the node pool
28
- // +optional
29
- Disruption * DisruptionSpec `json:"disruption,omitempty"`
28
+ // Template contains the template of possibilities for the provisioning logic to launch a NodeClaim with.
29
+ // NodeClaims launched from this NodePool will often be further constrained than the template specifies.
30
+ // +required
31
+ Template NodeClaimTemplate `json:"template"`
30
32
31
- // Limits specifies the limits for the node pool
33
+ // Disruption contains the parameters that relate to Karpenter's disruption logic
34
+ // +kubebuilder:default:={consolidateAfter: "0s"}
32
35
// +optional
33
- Limits * LimitsSpec `json:"limits,omitempty "`
36
+ Disruption Disruption `json:"disruption "`
34
37
35
- // Requirements specifies the requirements for the node pool
38
+ // Limits define a set of bounds for provisioning capacity.
36
39
// +optional
37
- Requirements []RequirementSpec `json:"requirements,omitempty"`
38
-
39
- // Taints specifies the taints to apply to nodes in this pool
40
+ Limits Limits `json:"limits,omitempty"`
41
+
42
+ // Weight is the priority given to the nodepool during scheduling. A higher
43
+ // numerical weight indicates that this nodepool will be ordered
44
+ // ahead of other nodepools with lower weights. A nodepool with no weight
45
+ // will be treated as if it is a nodepool with a weight of 0.
46
+ // +kubebuilder:validation:Minimum:=1
47
+ // +kubebuilder:validation:Maximum:=100
40
48
// +optional
41
- Taints []TaintSpec `json:"taints,omitempty"`
49
+ Weight * int32 `json:"weight,omitempty"`
50
+ }
42
51
43
- // Labels specifies the labels to apply to nodes in this pool
52
+ type NodeClaimTemplate struct {
53
+ ObjectMeta `json:"metadata,omitempty"`
54
+ // +required
55
+ Spec NodeClaimTemplateSpec `json:"spec"`
56
+ }
57
+
58
+ type ObjectMeta struct {
59
+ // Map of string keys and values that can be used to organize and categorize
60
+ // (scope and select) objects. May match selectors of replication controllers
61
+ // and services.
62
+ // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels
44
63
// +optional
45
64
Labels map [string ]string `json:"labels,omitempty"`
46
65
47
- // Weight specifies the weight of this node pool
66
+ // Annotations is an unstructured key value map stored with a resource that may be
67
+ // set by external tools to store and retrieve arbitrary metadata. They are not
68
+ // queryable and should be preserved when modifying objects.
69
+ // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations
48
70
// +optional
49
- Weight * int32 `json:"weight ,omitempty"`
71
+ Annotations map [ string ] string `json:"annotations ,omitempty"`
50
72
}
51
73
52
- // DisruptionSpec defines the disruption behavior for a NodePool
53
- type DisruptionSpec struct {
54
- // ConsolidateAfter specifies when to consolidate nodes
74
+ // NodeClaimTemplateSpec describes the desired state of the NodeClaim in the Nodepool
75
+ // NodeClaimTemplateSpec is used in the NodePool's NodeClaimTemplate, with the resource requests omitted since
76
+ // users are not able to set resource requests in the NodePool.
77
+ type NodeClaimTemplateSpec struct {
78
+ // Taints will be applied to the NodeClaim's node.
55
79
// +optional
56
- ConsolidateAfter * metav1.Duration `json:"consolidateAfter,omitempty"`
80
+ Taints []v1.Taint `json:"taints,omitempty"`
81
+ // StartupTaints are taints that are applied to nodes upon startup which are expected to be removed automatically
82
+ // within a short period of time, typically by a DaemonSet that tolerates the taint. These are commonly used by
83
+ // daemonsets to allow initialization and enforce startup ordering. StartupTaints are ignored for provisioning
84
+ // purposes in that pods are not required to tolerate a StartupTaint in order to have nodes provisioned for them.
85
+ // +optional
86
+ StartupTaints []v1.Taint `json:"startupTaints,omitempty"`
87
+ // Requirements are layered with GetLabels and applied to every node.
88
+ // +kubebuilder:validation:XValidation:message="requirements with operator 'In' must have a value defined",rule="self.all(x, x.operator == 'In' ? x.values.size() != 0 : true)"
89
+ // +kubebuilder:validation:XValidation:message="requirements operator 'Gt' or 'Lt' must have a single positive integer value",rule="self.all(x, (x.operator == 'Gt' || x.operator == 'Lt') ? (x.values.size() == 1 && int(x.values[0]) >= 0) : true)"
90
+ // +kubebuilder:validation:XValidation:message="requirements with 'minValues' must have at least that many values specified in the 'values' field",rule="self.all(x, (x.operator == 'In' && has(x.minValues)) ? x.values.size() >= x.minValues : true)"
91
+ // +kubebuilder:validation:MaxItems:=100
92
+ // +required
93
+ Requirements []NodeSelectorRequirementWithMinValues `json:"requirements" hash:"ignore"`
94
+ // TerminationGracePeriod is the maximum duration the controller will wait before forcefully deleting the pods on a node, measured from when deletion is first initiated.
95
+ //
96
+ // Warning: this feature takes precedence over a Pod's terminationGracePeriodSeconds value, and bypasses any blocked PDBs or the karpenter.sh/do-not-disrupt annotation.
97
+ //
98
+ // This field is intended to be used by cluster administrators to enforce that nodes can be cycled within a given time period.
99
+ // When set, drifted nodes will begin draining even if there are pods blocking eviction. Draining will respect PDBs and the do-not-disrupt annotation until the TGP is reached.
100
+ //
101
+ // Karpenter will preemptively delete pods so their terminationGracePeriodSeconds align with the node's terminationGracePeriod.
102
+ // If a pod would be terminated without being granted its full terminationGracePeriodSeconds prior to the node timeout,
103
+ // that pod will be deleted at T = node timeout - pod terminationGracePeriodSeconds.
104
+ //
105
+ // The feature can also be used to allow maximum time limits for long-running jobs which can delay node termination with preStop hooks.
106
+ // If left undefined, the controller will wait indefinitely for pods to be drained.
107
+ // +kubebuilder:validation:Pattern=`^([0-9]+(s|m|h))+$`
108
+ // +kubebuilder:validation:Type="string"
109
+ // +optional
110
+ TerminationGracePeriod * metav1.Duration `json:"terminationGracePeriod,omitempty"`
111
+ // ExpireAfter is the duration the controller will wait
112
+ // before terminating a node, measured from when the node is created. This
113
+ // is useful to implement features like eventually consistent node upgrade,
114
+ // memory leak protection, and disruption testing.
115
+ // +kubebuilder:default:="720h"
116
+ // +kubebuilder:validation:Pattern=`^(([0-9]+(s|m|h))+|Never)$`
117
+ // +kubebuilder:validation:Type="string"
118
+ // +kubebuilder:validation:Schemaless
119
+ // +optional
120
+ ExpireAfter NillableDuration `json:"expireAfter,omitempty"`
121
+ }
57
122
58
- // ConsolidationPolicy specifies the consolidation policy
123
+ // A node selector requirement with min values is a selector that contains values, a key, an operator that relates the key and values
124
+ // and minValues that represent the requirement to have at least that many values.
125
+ type NodeSelectorRequirementWithMinValues struct {
126
+ v1.NodeSelectorRequirement `json:",inline"`
127
+ // This field is ALPHA and can be dropped or replaced at any time
128
+ // MinValues is the minimum number of unique values required to define the flexibility of the specific requirement.
129
+ // +kubebuilder:validation:Minimum:=1
130
+ // +kubebuilder:validation:Maximum:=50
59
131
// +optional
60
- ConsolidationPolicy * string `json:"consolidationPolicy,omitempty"`
132
+ MinValues * int `json:"minValues,omitempty"`
133
+ }
134
+
135
+ type NodeClassReference struct {
136
+ // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"
137
+ // +kubebuilder:validation:XValidation:rule="self != ''",message="kind may not be empty"
138
+ // +required
139
+ Kind string `json:"kind"`
140
+ // Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names
141
+ // +kubebuilder:validation:XValidation:rule="self != ''",message="name may not be empty"
142
+ // +required
143
+ Name string `json:"name"`
144
+ // API version of the referent
145
+ // +kubebuilder:validation:XValidation:rule="self != ''",message="group may not be empty"
146
+ // +kubebuilder:validation:Pattern=`^[^/]*$`
147
+ // +required
148
+ Group string `json:"group"`
149
+ }
61
150
62
- // ConsolidateUnder specifies when to consolidate under
151
+ type Limits v1.ResourceList
152
+
153
+ type ConsolidationPolicy string
154
+
155
+ const (
156
+ ConsolidationPolicyWhenEmpty ConsolidationPolicy = "WhenEmpty"
157
+ ConsolidationPolicyWhenEmptyOrUnderutilized ConsolidationPolicy = "WhenEmptyOrUnderutilized"
158
+ )
159
+
160
+ // DisruptionReason defines valid reasons for disruption budgets.
161
+ // +kubebuilder:validation:Enum={Underutilized,Empty,Drifted}
162
+ type DisruptionReason string
163
+
164
+ // Budget defines when Karpenter will restrict the
165
+ // number of Node Claims that can be terminating simultaneously.
166
+ type Budget struct {
167
+ // Reasons is a list of disruption methods that this budget applies to. If Reasons is not set, this budget applies to all methods.
168
+ // Otherwise, this will apply to each reason defined.
169
+ // allowed reasons are Underutilized, Empty, and Drifted.
170
+ // +optional
171
+ Reasons []DisruptionReason `json:"reasons,omitempty"`
172
+ // Nodes dictates the maximum number of NodeClaims owned by this NodePool
173
+ // that can be terminating at once. This is calculated by counting nodes that
174
+ // have a deletion timestamp set, or are actively being deleted by Karpenter.
175
+ // This field is required when specifying a budget.
176
+ // This cannot be of type intstr.IntOrString since kubebuilder doesn't support pattern
177
+ // checking for int nodes for IntOrString nodes.
178
+ // Ref: https://github.com/kubernetes-sigs/controller-tools/blob/55efe4be40394a288216dab63156b0a64fb82929/pkg/crd/markers/validation.go#L379-L388
179
+ // +kubebuilder:validation:Pattern:="^((100|[0-9]{1,2})%|[0-9]+)$"
180
+ // +kubebuilder:default:="10%"
181
+ Nodes string `json:"nodes" hash:"ignore"`
182
+ // Schedule specifies when a budget begins being active, following
183
+ // the upstream cronjob syntax. If omitted, the budget is always active.
184
+ // Timezones are not supported.
185
+ // This field is required if Duration is set.
186
+ // +kubebuilder:validation:Pattern:=`^(@(annually|yearly|monthly|weekly|daily|midnight|hourly))|((.+)\s(.+)\s(.+)\s(.+)\s(.+))$`
187
+ // +optional
188
+ Schedule * string `json:"schedule,omitempty" hash:"ignore"`
189
+ // Duration determines how long a Budget is active since each Schedule hit.
190
+ // Only minutes and hours are accepted, as cron does not work in seconds.
191
+ // If omitted, the budget is always active.
192
+ // This is required if Schedule is set.
193
+ // This regex has an optional 0s at the end since the duration.String() always adds
194
+ // a 0s at the end.
195
+ // +kubebuilder:validation:Pattern=`^((([0-9]+(h|m))|([0-9]+h[0-9]+m))(0s)?)$`
196
+ // +kubebuilder:validation:Type="string"
63
197
// +optional
64
- ConsolidateUnder * ConsolidateUnderSpec `json:"consolidateUnder,omitempty"`
198
+ Duration * metav1.Duration `json:"duration,omitempty" hash:"ignore"`
199
+ }
200
+
201
+ type Disruption struct {
202
+ // ConsolidateAfter is the duration the controller will wait
203
+ // before attempting to terminate nodes that are underutilized.
204
+ // Refer to ConsolidationPolicy for how underutilization is considered.
205
+ // +kubebuilder:validation:Pattern=`^(([0-9]+(s|m|h))+|Never)$`
206
+ // +kubebuilder:validation:Type="string"
207
+ // +kubebuilder:validation:Schemaless
208
+ // +required
209
+ ConsolidateAfter NillableDuration `json:"consolidateAfter"`
210
+ // ConsolidationPolicy describes which nodes Karpenter can disrupt through its consolidation
211
+ // algorithm. This policy defaults to "WhenEmptyOrUnderutilized" if not specified
212
+ // +kubebuilder:default:="WhenEmptyOrUnderutilized"
213
+ // +kubebuilder:validation:Enum:={WhenEmpty,WhenEmptyOrUnderutilized}
214
+ // +optional
215
+ ConsolidationPolicy ConsolidationPolicy `json:"consolidationPolicy,omitempty"`
216
+ // Budgets is a list of Budgets.
217
+ // If there are multiple active budgets, Karpenter uses
218
+ // the most restrictive value. If left undefined,
219
+ // this will default to one budget with a value to 10%.
220
+ // +kubebuilder:validation:XValidation:message="'schedule' must be set with 'duration'",rule="self.all(x, has(x.schedule) == has(x.duration))"
221
+ // +kubebuilder:default:={{nodes: "10%"}}
222
+ // +kubebuilder:validation:MaxItems=50
223
+ // +optional
224
+ Budgets []Budget `json:"budgets,omitempty" hash:"ignore"`
65
225
}
66
226
67
227
// ConsolidateUnderSpec defines when to consolidate under
@@ -128,10 +288,6 @@ type EC2NodeClassSpec struct {
128
288
// Subnets specifies the subnets to use
129
289
// +optional
130
290
Subnets map [string ]string `json:"subnets,omitempty"`
131
-
132
- // Tags specifies the tags to apply to EC2 instances
133
- // +optional
134
- Tags map [string ]string `json:"tags,omitempty"`
135
291
}
136
292
137
293
// KarpenterMachinePoolSpec defines the desired state of KarpenterMachinePool.
0 commit comments