86
86
// NOTE: The following assumes that kubeadm version equals to Kubernetes version.
87
87
minVerUnversionedKubeletConfig = semver .MustParse ("1.24.0" )
88
88
89
+ // minKubernetesVersionControlPlaneKubeletLocalMode is the min version from which
90
+ // we will enable the ControlPlaneKubeletLocalMode kubeadm feature gate.
91
+ // Note: We have to do this with Kubernetes 1.31. Because with that version we encountered
92
+ // a case where it's not okay anymore to ignore the Kubernetes version skew (kubelet 1.31 uses
93
+ // the spec.clusterIP field selector that is only implemented in kube-apiserver >= 1.31.0).
94
+ minKubernetesVersionControlPlaneKubeletLocalMode = semver .MustParse ("1.31.0" )
95
+
89
96
// ErrControlPlaneMinNodes signals that a cluster doesn't meet the minimum required nodes
90
97
// to remove an etcd member.
91
98
ErrControlPlaneMinNodes = errors .New ("cluster has fewer than 2 control plane nodes; removing an etcd member is not supported" )
@@ -107,7 +114,7 @@ type WorkloadCluster interface {
107
114
ReconcileKubeletRBACRole (ctx context.Context , version semver.Version ) error
108
115
UpdateKubernetesVersionInKubeadmConfigMap (version semver.Version ) func (* bootstrapv1.ClusterConfiguration )
109
116
UpdateImageRepositoryInKubeadmConfigMap (imageRepository string ) func (* bootstrapv1.ClusterConfiguration )
110
- UpdateFeatureGatesInKubeadmConfigMap (featureGates map [ string ] bool ) func (* bootstrapv1.ClusterConfiguration )
117
+ UpdateFeatureGatesInKubeadmConfigMap (kubeadmConfigSpec bootstrapv1. KubeadmConfigSpec , kubernetesVersion semver. Version ) func (* bootstrapv1.ClusterConfiguration )
111
118
UpdateEtcdLocalInKubeadmConfigMap (localEtcd * bootstrapv1.LocalEtcd ) func (* bootstrapv1.ClusterConfiguration )
112
119
UpdateEtcdExternalInKubeadmConfigMap (externalEtcd * bootstrapv1.ExternalEtcd ) func (* bootstrapv1.ClusterConfiguration )
113
120
UpdateAPIServerInKubeadmConfigMap (apiServer bootstrapv1.APIServer ) func (* bootstrapv1.ClusterConfiguration )
@@ -186,11 +193,40 @@ func (w *Workload) UpdateImageRepositoryInKubeadmConfigMap(imageRepository strin
186
193
}
187
194
188
195
// UpdateFeatureGatesInKubeadmConfigMap updates the feature gates in the kubeadm config map.
189
- func (w * Workload ) UpdateFeatureGatesInKubeadmConfigMap (featureGates map [ string ] bool ) func (* bootstrapv1.ClusterConfiguration ) {
196
+ func (w * Workload ) UpdateFeatureGatesInKubeadmConfigMap (kubeadmConfigSpec bootstrapv1. KubeadmConfigSpec , kubernetesVersion semver. Version ) func (* bootstrapv1.ClusterConfiguration ) {
190
197
return func (c * bootstrapv1.ClusterConfiguration ) {
198
+ // We use DeepCopy here to avoid modifying the KCP object in the apiserver.
199
+ kubeadmConfigSpec := kubeadmConfigSpec .DeepCopy ()
200
+ DefaultFeatureGates (kubeadmConfigSpec , kubernetesVersion )
201
+
191
202
// Even if featureGates is nil, reset it to ClusterConfiguration
192
203
// to override any previously set feature gates.
193
- c .FeatureGates = featureGates
204
+ c .FeatureGates = kubeadmConfigSpec .ClusterConfiguration .FeatureGates
205
+ }
206
+ }
207
+
208
+ const (
209
+ // ControlPlaneKubeletLocalMode is a feature gate of kubeadm that ensures
210
+ // kubelets only communicate with the local apiserver.
211
+ ControlPlaneKubeletLocalMode = "ControlPlaneKubeletLocalMode"
212
+ )
213
+
214
+ // DefaultFeatureGates defaults the feature gates field.
215
+ func DefaultFeatureGates (kubeadmConfigSpec * bootstrapv1.KubeadmConfigSpec , kubernetesVersion semver.Version ) {
216
+ if kubernetesVersion .LT (minKubernetesVersionControlPlaneKubeletLocalMode ) {
217
+ return
218
+ }
219
+
220
+ if kubeadmConfigSpec .ClusterConfiguration == nil {
221
+ kubeadmConfigSpec .ClusterConfiguration = & bootstrapv1.ClusterConfiguration {}
222
+ }
223
+
224
+ if kubeadmConfigSpec .ClusterConfiguration .FeatureGates == nil {
225
+ kubeadmConfigSpec .ClusterConfiguration .FeatureGates = map [string ]bool {}
226
+ }
227
+
228
+ if _ , ok := kubeadmConfigSpec .ClusterConfiguration .FeatureGates [ControlPlaneKubeletLocalMode ]; ! ok {
229
+ kubeadmConfigSpec .ClusterConfiguration .FeatureGates [ControlPlaneKubeletLocalMode ] = true
194
230
}
195
231
}
196
232
0 commit comments