@@ -131,6 +131,18 @@ func (k *KubeCmd) UpgradeKubernetesVersion(ctx context.Context, kubernetesVersio
131
131
)
132
132
}
133
133
134
+ // TODO(burgerdev): remove after releasing v2.19
135
+ // Workaround for https://github.com/kubernetes/kubernetes/issues/127316: force kubelet to
136
+ // connect to the local API server.
137
+ if err := k .patchKubeadmConfig (ctx , func (cc * kubeadm.ClusterConfiguration ) {
138
+ if cc .FeatureGates == nil {
139
+ cc .FeatureGates = map [string ]bool {}
140
+ }
141
+ cc .FeatureGates ["ControlPlaneKubeletLocalMode" ] = true
142
+ }); err != nil {
143
+ return fmt .Errorf ("setting FeatureGate ControlPlaneKubeletLocalMode: %w" , err )
144
+ }
145
+
134
146
versionConfig , ok := versions .VersionConfigs [kubernetesVersion ]
135
147
if ! ok {
136
148
return fmt .Errorf ("skipping Kubernetes upgrade: %w" , compatibility .NewInvalidUpgradeError (
@@ -236,65 +248,32 @@ func (k *KubeCmd) ApplyJoinConfig(ctx context.Context, newAttestConfig config.At
236
248
// ExtendClusterConfigCertSANs extends the ClusterConfig stored under "kube-system/kubeadm-config" with the given SANs.
237
249
// Empty strings are ignored, existing SANs are preserved.
238
250
func (k * KubeCmd ) ExtendClusterConfigCertSANs (ctx context.Context , alternativeNames []string ) error {
239
- var kubeadmConfig * corev1.ConfigMap
240
- if err := k .retryAction (ctx , func (ctx context.Context ) error {
241
- var err error
242
- kubeadmConfig , err = k .kubectl .GetConfigMap (ctx , constants .ConstellationNamespace , constants .KubeadmConfigMap )
243
- return err
244
- }); err != nil {
245
- return fmt .Errorf ("retrieving current kubeadm-config: %w" , err )
246
- }
247
-
248
- clusterConfigData , ok := kubeadmConfig .Data [constants .ClusterConfigurationKey ]
249
- if ! ok {
250
- return errors .New ("ClusterConfiguration missing from kubeadm-config" )
251
- }
252
-
253
- var clusterConfiguration kubeadm.ClusterConfiguration
254
- if err := runtime .DecodeInto (kubeadmscheme .Codecs .UniversalDecoder (), []byte (clusterConfigData ), & clusterConfiguration ); err != nil {
255
- return fmt .Errorf ("decoding cluster configuration data: %w" , err )
256
- }
257
-
258
- existingSANs := make (map [string ]struct {})
259
- for _ , existingSAN := range clusterConfiguration .APIServer .CertSANs {
260
- existingSANs [existingSAN ] = struct {}{}
261
- }
262
-
263
- var missingSANs []string
264
- for _ , san := range alternativeNames {
265
- if san == "" {
266
- continue // skip empty SANs
251
+ if err := k .patchKubeadmConfig (ctx , func (clusterConfiguration * kubeadm.ClusterConfiguration ) {
252
+ existingSANs := make (map [string ]struct {})
253
+ for _ , existingSAN := range clusterConfiguration .APIServer .CertSANs {
254
+ existingSANs [existingSAN ] = struct {}{}
267
255
}
268
- if _ , ok := existingSANs [san ]; ! ok {
269
- missingSANs = append (missingSANs , san )
270
- existingSANs [san ] = struct {}{} // make sure we don't add the same SAN twice
271
- }
272
- }
273
256
274
- if len (missingSANs ) == 0 {
275
- k .log .Debug ("No new SANs to add to the cluster's apiserver SAN field" )
276
- return nil
277
- }
278
- k .log .Debug ("Extending the cluster's apiserver SAN field" , "certSANs" , strings .Join (missingSANs , ", " ))
279
-
280
- clusterConfiguration .APIServer .CertSANs = append (clusterConfiguration .APIServer .CertSANs , missingSANs ... )
281
- sort .Strings (clusterConfiguration .APIServer .CertSANs )
257
+ var missingSANs []string
258
+ for _ , san := range alternativeNames {
259
+ if san == "" {
260
+ continue // skip empty SANs
261
+ }
262
+ if _ , ok := existingSANs [san ]; ! ok {
263
+ missingSANs = append (missingSANs , san )
264
+ existingSANs [san ] = struct {}{} // make sure we don't add the same SAN twice
265
+ }
266
+ }
282
267
283
- opt := k8sjson.SerializerOptions {Yaml : true }
284
- serializer := k8sjson .NewSerializerWithOptions (k8sjson .DefaultMetaFactory , kubeadmscheme .Scheme , kubeadmscheme .Scheme , opt )
285
- encoder := kubeadmscheme .Codecs .EncoderForVersion (serializer , kubeadmv1beta4 .SchemeGroupVersion )
286
- newConfigYAML , err := runtime .Encode (encoder , & clusterConfiguration )
287
- if err != nil {
288
- return fmt .Errorf ("marshaling ClusterConfiguration: %w" , err )
289
- }
268
+ if len (missingSANs ) == 0 {
269
+ k .log .Debug ("No new SANs to add to the cluster's apiserver SAN field" )
270
+ }
271
+ k .log .Debug ("Extending the cluster's apiserver SAN field" , "certSANs" , strings .Join (missingSANs , ", " ))
290
272
291
- kubeadmConfig .Data [constants .ClusterConfigurationKey ] = string (newConfigYAML )
292
- k .log .Debug ("Triggering kubeadm config update now" )
293
- if err = k .retryAction (ctx , func (ctx context.Context ) error {
294
- _ , err := k .kubectl .UpdateConfigMap (ctx , kubeadmConfig )
295
- return err
273
+ clusterConfiguration .APIServer .CertSANs = append (clusterConfiguration .APIServer .CertSANs , missingSANs ... )
274
+ sort .Strings (clusterConfiguration .APIServer .CertSANs )
296
275
}); err != nil {
297
- return fmt .Errorf ("setting new kubeadm config : %w" , err )
276
+ return fmt .Errorf ("extending ClusterConfig.CertSANs : %w" , err )
298
277
}
299
278
300
279
k .log .Debug ("Successfully extended the cluster's apiserver SAN field" )
@@ -462,6 +441,51 @@ func (k *KubeCmd) retryAction(ctx context.Context, action func(ctx context.Conte
462
441
return retrier .Do (ctx )
463
442
}
464
443
444
+ // patchKubeadmConfig fetches and unpacks the kube-system/kubeadm-config ClusterConfiguration entry,
445
+ // runs doPatch on it and uploads the result.
446
+ func (k * KubeCmd ) patchKubeadmConfig (ctx context.Context , doPatch func (* kubeadm.ClusterConfiguration )) error {
447
+ var kubeadmConfig * corev1.ConfigMap
448
+ if err := k .retryAction (ctx , func (ctx context.Context ) error {
449
+ var err error
450
+ kubeadmConfig , err = k .kubectl .GetConfigMap (ctx , constants .ConstellationNamespace , constants .KubeadmConfigMap )
451
+ return err
452
+ }); err != nil {
453
+ return fmt .Errorf ("retrieving current kubeadm-config: %w" , err )
454
+ }
455
+
456
+ clusterConfigData , ok := kubeadmConfig .Data [constants .ClusterConfigurationKey ]
457
+ if ! ok {
458
+ return errors .New ("ClusterConfiguration missing from kubeadm-config" )
459
+ }
460
+
461
+ var clusterConfiguration kubeadm.ClusterConfiguration
462
+ if err := runtime .DecodeInto (kubeadmscheme .Codecs .UniversalDecoder (), []byte (clusterConfigData ), & clusterConfiguration ); err != nil {
463
+ return fmt .Errorf ("decoding cluster configuration data: %w" , err )
464
+ }
465
+
466
+ doPatch (& clusterConfiguration )
467
+
468
+ opt := k8sjson.SerializerOptions {Yaml : true }
469
+ serializer := k8sjson .NewSerializerWithOptions (k8sjson .DefaultMetaFactory , kubeadmscheme .Scheme , kubeadmscheme .Scheme , opt )
470
+ encoder := kubeadmscheme .Codecs .EncoderForVersion (serializer , kubeadmv1beta4 .SchemeGroupVersion )
471
+ newConfigYAML , err := runtime .Encode (encoder , & clusterConfiguration )
472
+ if err != nil {
473
+ return fmt .Errorf ("marshaling ClusterConfiguration: %w" , err )
474
+ }
475
+
476
+ kubeadmConfig .Data [constants .ClusterConfigurationKey ] = string (newConfigYAML )
477
+ k .log .Debug ("Triggering kubeadm config update now" )
478
+ if err = k .retryAction (ctx , func (ctx context.Context ) error {
479
+ _ , err := k .kubectl .UpdateConfigMap (ctx , kubeadmConfig )
480
+ return err
481
+ }); err != nil {
482
+ return fmt .Errorf ("setting new kubeadm config: %w" , err )
483
+ }
484
+
485
+ k .log .Debug ("Successfully patched the cluster's kubeadm-config" )
486
+ return nil
487
+ }
488
+
465
489
func checkForApplyError (expected , actual updatev1alpha1.NodeVersion ) error {
466
490
var err error
467
491
switch {
0 commit comments