Skip to content

Commit f9cd33f

Browse files
authored
✨ Implement MachineDrainRules (#11353)
* Implement MachineDrainRules * Fix review findings * fix scale e2e test * fixes * fixes * fixes * regen openapi * Fix review findings * Fix review findings
1 parent f810589 commit f9cd33f

22 files changed

+2924
-245
lines changed

api/v1beta1/clusterclass_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ type ValidationRule struct {
699699
// Transition rules by default are applied only on UPDATE requests and are
700700
// skipped if an old value could not be found.
701701
//
702-
// +kubebuilder:validation:Required
702+
// +required
703703
Rule string `json:"rule"`
704704
// message represents the message displayed when validation fails. The message is required if the Rule contains
705705
// line breaks. The message must not contain line breaks.
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
/*
2+
Copyright 2024 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+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21+
)
22+
23+
const (
24+
// PodDrainLabel is the label that can be set on Pods in workload clusters to ensure a Pod is not drained.
25+
// The only valid value is "skip".
26+
// This label takes precedence over MachineDrainRules defined in the management cluster.
27+
PodDrainLabel = "cluster.x-k8s.io/drain"
28+
)
29+
30+
// MachineDrainRuleDrainBehavior defines the drain behavior. Can be either "Drain" or "Skip".
31+
// +kubebuilder:validation:Enum=Drain;Skip
32+
type MachineDrainRuleDrainBehavior string
33+
34+
const (
35+
// MachineDrainRuleDrainBehaviorDrain means a Pod should be drained.
36+
MachineDrainRuleDrainBehaviorDrain MachineDrainRuleDrainBehavior = "Drain"
37+
38+
// MachineDrainRuleDrainBehaviorSkip means the drain for a Pod should be skipped.
39+
MachineDrainRuleDrainBehaviorSkip MachineDrainRuleDrainBehavior = "Skip"
40+
)
41+
42+
// MachineDrainRuleSpec defines the spec of a MachineDrainRule.
43+
type MachineDrainRuleSpec struct {
44+
// drain configures if and how Pods are drained.
45+
// +required
46+
Drain MachineDrainRuleDrainConfig `json:"drain"`
47+
48+
// machines defines to which Machines this MachineDrainRule should be applied.
49+
//
50+
// If machines is not set, the MachineDrainRule applies to all Machines in the Namespace.
51+
// If machines contains multiple selectors, the results are ORed.
52+
// Within a single Machine selector the results of selector and clusterSelector are ANDed.
53+
// Machines will be selected from all Clusters in the Namespace unless otherwise
54+
// restricted with the clusterSelector.
55+
//
56+
// Example: Selects control plane Machines in all Clusters or
57+
// Machines with label "os" == "linux" in Clusters with label
58+
// "stage" == "production".
59+
//
60+
// - selector:
61+
// matchExpressions:
62+
// - key: cluster.x-k8s.io/control-plane
63+
// operator: Exists
64+
// - selector:
65+
// matchLabels:
66+
// os: linux
67+
// clusterSelector:
68+
// matchExpressions:
69+
// - key: stage
70+
// operator: In
71+
// values:
72+
// - production
73+
//
74+
// +optional
75+
// +listType=atomic
76+
// +kubebuilder:validation:MinItems=1
77+
// +kubebuilder:validation:MaxItems=32
78+
Machines []MachineDrainRuleMachineSelector `json:"machines,omitempty"`
79+
80+
// pods defines to which Pods this MachineDrainRule should be applied.
81+
//
82+
// If pods is not set, the MachineDrainRule applies to all Pods in all Namespaces.
83+
// If pods contains multiple selectors, the results are ORed.
84+
// Within a single Pod selector the results of selector and namespaceSelector are ANDed.
85+
// Pods will be selected from all Namespaces unless otherwise
86+
// restricted with the namespaceSelector.
87+
//
88+
// Example: Selects Pods with label "app" == "logging" in all Namespaces or
89+
// Pods with label "app" == "prometheus" in the "monitoring"
90+
// Namespace.
91+
//
92+
// - selector:
93+
// matchExpressions:
94+
// - key: app
95+
// operator: In
96+
// values:
97+
// - logging
98+
// - selector:
99+
// matchLabels:
100+
// app: prometheus
101+
// namespaceSelector:
102+
// matchLabels:
103+
// kubernetes.io/metadata.name: monitoring
104+
//
105+
// +optional
106+
// +listType=atomic
107+
// +kubebuilder:validation:MinItems=1
108+
// +kubebuilder:validation:MaxItems=32
109+
Pods []MachineDrainRulePodSelector `json:"pods,omitempty"`
110+
}
111+
112+
// MachineDrainRuleDrainConfig configures if and how Pods are drained.
113+
type MachineDrainRuleDrainConfig struct {
114+
// behavior defines the drain behavior.
115+
// Can be either "Drain" or "Skip".
116+
// "Drain" means that the Pods to which this MachineDrainRule applies will be drained.
117+
// If behavior is set to "Drain" the order in which Pods are drained can be configured
118+
// with the order field. When draining Pods of a Node the Pods will be grouped by order
119+
// and one group after another will be drained (by increasing order). Cluster API will
120+
// wait until all Pods of a group are terminated / removed from the Node before starting
121+
// with the next group.
122+
// "Skip" means that the Pods to which this MachineDrainRule applies will be skipped during drain.
123+
// +required
124+
Behavior MachineDrainRuleDrainBehavior `json:"behavior"`
125+
126+
// order defines the order in which Pods are drained.
127+
// Pods with higher order are drained after Pods with lower order.
128+
// order can only be set if behavior is set to "Drain".
129+
// If order is not set, 0 will be used.
130+
// Valid values for order are from -2147483648 to 2147483647 (inclusive).
131+
// +optional
132+
Order *int32 `json:"order,omitempty"`
133+
}
134+
135+
// MachineDrainRuleMachineSelector defines to which Machines this MachineDrainRule should be applied.
136+
// +kubebuilder:validation:MinProperties=1
137+
type MachineDrainRuleMachineSelector struct {
138+
// selector is a label selector which selects Machines by their labels.
139+
// This field follows standard label selector semantics; if not present or
140+
// empty, it selects all Machines.
141+
//
142+
// If clusterSelector is also set, then the selector as a whole selects
143+
// Machines matching selector belonging to Clusters selected by clusterSelector.
144+
// If clusterSelector is not set, it selects all Machines matching selector in
145+
// all Clusters.
146+
// +optional
147+
Selector *metav1.LabelSelector `json:"selector,omitempty"`
148+
149+
// clusterSelector is a label selector which selects Machines by the labels of
150+
// their Clusters.
151+
// This field follows standard label selector semantics; if not present or
152+
// empty, it selects Machines of all Clusters.
153+
//
154+
// If selector is also set, then the selector as a whole selects
155+
// Machines matching selector belonging to Clusters selected by clusterSelector.
156+
// If selector is not set, it selects all Machines belonging to Clusters
157+
// selected by clusterSelector.
158+
// +optional
159+
ClusterSelector *metav1.LabelSelector `json:"clusterSelector,omitempty"`
160+
}
161+
162+
// MachineDrainRulePodSelector defines to which Pods this MachineDrainRule should be applied.
163+
// +kubebuilder:validation:MinProperties=1
164+
type MachineDrainRulePodSelector struct {
165+
// selector is a label selector which selects Pods by their labels.
166+
// This field follows standard label selector semantics; if not present or
167+
// empty, it selects all Pods.
168+
//
169+
// If namespaceSelector is also set, then the selector as a whole selects
170+
// Pods matching selector in Namespaces selected by namespaceSelector.
171+
// If namespaceSelector is not set, it selects all Pods matching selector in
172+
// all Namespaces.
173+
// +optional
174+
Selector *metav1.LabelSelector `json:"selector,omitempty"`
175+
176+
// namespaceSelector is a label selector which selects Pods by the labels of
177+
// their Namespaces.
178+
// This field follows standard label selector semantics; if not present or
179+
// empty, it selects Pods of all Namespaces.
180+
//
181+
// If selector is also set, then the selector as a whole selects
182+
// Pods matching selector in Namespaces selected by namespaceSelector.
183+
// If selector is not set, it selects all Pods in Namespaces selected by
184+
// namespaceSelector.
185+
// +optional
186+
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty"`
187+
}
188+
189+
// +kubebuilder:object:root=true
190+
// +kubebuilder:resource:path=machinedrainrules,scope=Namespaced,categories=cluster-api
191+
// +kubebuilder:storageversion
192+
// +kubebuilder:printcolumn:name="Behavior",type="string",JSONPath=".spec.drain.behavior",description="Drain behavior"
193+
// +kubebuilder:printcolumn:name="Order",type="string",JSONPath=".spec.drain.order",description="Drain order"
194+
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Time duration since creation of the MachineDrainRule"
195+
196+
// MachineDrainRule is the Schema for the MachineDrainRule API.
197+
type MachineDrainRule struct {
198+
metav1.TypeMeta `json:",inline"`
199+
200+
// +required
201+
metav1.ObjectMeta `json:"metadata"`
202+
203+
// spec defines the spec of a MachineDrainRule.
204+
// +required
205+
Spec MachineDrainRuleSpec `json:"spec"`
206+
}
207+
208+
// +kubebuilder:object:root=true
209+
210+
// MachineDrainRuleList contains a list of MachineDrainRules.
211+
type MachineDrainRuleList struct {
212+
metav1.TypeMeta `json:",inline"`
213+
214+
// +required
215+
metav1.ListMeta `json:"metadata"`
216+
217+
// items contains the items of the MachineDrainRuleList.
218+
// +required
219+
Items []MachineDrainRule `json:"items"`
220+
}
221+
222+
func init() {
223+
objectTypes = append(objectTypes, &MachineDrainRule{}, &MachineDrainRuleList{})
224+
}

api/v1beta1/zz_generated.deepcopy.go

Lines changed: 158 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)