@@ -27,7 +27,6 @@ import (
2727
2828 certificatesv1 "k8s.io/api/certificates/v1"
2929 v1 "k8s.io/api/core/v1"
30- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3130 "k8s.io/apimachinery/pkg/util/wait"
3231 "k8s.io/client-go/kubernetes"
3332 "k8s.io/client-go/kubernetes/scheme"
@@ -56,25 +55,29 @@ var (
5655
5756// getPerNodeKubeconfig creates new kubeConfig, based on bootstrap, with new certDir
5857func getPerNodeKubeconfig (bootstrap * rest.Config , certDir string ) * rest.Config {
59- return & rest.Config {
60- Host : bootstrap .Host ,
61- APIPath : bootstrap .APIPath ,
62- ContentConfig : rest.ContentConfig {
63- AcceptContentTypes : "application/vnd.kubernetes.protobuf,application/json" ,
64- ContentType : "application/vnd.kubernetes.protobuf" ,
65- },
66- TLSClientConfig : rest.TLSClientConfig {
67- KeyFile : path .Join (certDir , certNamePrefix + "-current.pem" ),
68- CertFile : path .Join (certDir , certNamePrefix + "-current.pem" ),
69- CAData : bootstrap .TLSClientConfig .CAData ,
70- },
71- // Allow multus (especially in server mode) to make more concurrent requests
72- // to reduce client-side throttling
73- QPS : 50 ,
74- Burst : 50 ,
75- // Set the config timeout to one minute.
76- Timeout : time .Minute ,
77- }
58+ config := rest .CopyConfig (bootstrap )
59+ config .TLSClientConfig .CertFile = path .Join (certDir , certNamePrefix + "-current.pem" )
60+ config .TLSClientConfig .KeyFile = path .Join (certDir , certNamePrefix + "-current.pem" )
61+ config .TLSClientConfig .CertData = nil
62+ config .TLSClientConfig .KeyData = nil
63+
64+ // Switch to the per-node client certificate instead of reusing bootstrap auth.
65+ config .BearerToken = ""
66+ config .BearerTokenFile = ""
67+ config .Username = ""
68+ config .Password = ""
69+ config .ExecProvider = nil
70+ config .AuthProvider = nil
71+
72+ config .AcceptContentTypes = "application/vnd.kubernetes.protobuf,application/json"
73+ config .ContentType = "application/vnd.kubernetes.protobuf"
74+ // Allow multus (especially in server mode) to make more concurrent requests
75+ // to reduce client-side throttling
76+ config .QPS = 50
77+ config .Burst = 50
78+ // Set the config timeout to one minute.
79+ config .Timeout = time .Minute
80+ return config
7881}
7982
8083// PerNodeK8sClient creates/reload new multus kubeconfig per-node.
@@ -85,33 +88,35 @@ func PerNodeK8sClient(nodeName, bootstrapKubeconfigFile string, certDuration tim
8588 }
8689 config := getPerNodeKubeconfig (bootstrapKubeconfig , certDir )
8790
88- // If we have a valid certificate, user that to fetch CSRs.
91+ // If we have a valid certificate, use that to fetch CSRs.
8992 // Otherwise, use the bootstrap credentials from bootstrapKubeconfig
9093 // https://github.com/kubernetes/kubernetes/blob/068ee321bc7bfe1c2cefb87fb4d9e5deea84fbc8/cmd/kubelet/app/server.go#L953-L963
9194 newClientsetFn := func (current * tls.Certificate ) (kubernetes.Interface , error ) {
9295 cfg := bootstrapKubeconfig
9396
94- // validate the kubeconfig
95- tempClient , err := kubernetes .NewForConfig (cfg )
96- if err != nil {
97- logging .Errorf ("failed to read kubeconfig from cert manager: %v" , err )
98- } else {
99- _ , err := tempClient .CoreV1 ().Pods ("" ).List (context .TODO (), metav1.ListOptions {})
100- // tls unknown authority error is unrecoverable error with retry
97+ // When a current certificate exists, prefer it for CSR operations but fall back
98+ // to bootstrap credentials if the stored per-node config is no longer trusted.
99+ if current != nil {
100+ cfg = config
101+ tempClient , err := kubernetes .NewForConfig (cfg )
102+ if err != nil {
103+ return nil , logging .Errorf ("failed to create client from per-node kubeconfig: %v" , err )
104+ }
105+ _ , err = tempClient .Discovery ().ServerVersion ()
101106 if err != nil {
102107 if strings .Contains (err .Error (), "x509: certificate signed by unknown authority" ) {
103- logging .Verbosef ("cert mgr gets invalid config. rebuild from bootstrap kubeconfig" )
104- // reload and use bootstrapKubeconfig again
105- newBootstrapKubeconfig , _ := clientcmd .BuildConfigFromFlags ("" , bootstrapKubeconfigFile )
106- cfg = newBootstrapKubeconfig
108+ logging .Verbosef ("cert mgr gets invalid per-node config. rebuild from bootstrap kubeconfig" )
109+ newBootstrapKubeconfig , reloadErr := clientcmd .BuildConfigFromFlags ("" , bootstrapKubeconfigFile )
110+ if reloadErr != nil {
111+ return nil , logging .Errorf ("failed to reload bootstrap kubeconfig: %v" , reloadErr )
112+ }
113+ bootstrapKubeconfig = newBootstrapKubeconfig
114+ config = getPerNodeKubeconfig (bootstrapKubeconfig , certDir )
115+ cfg = bootstrapKubeconfig
107116 } else {
108- logging .Errorf ("failed to list pods with new certs : %v" , err )
117+ logging .Errorf ("failed to validate per-node kubeconfig : %v" , err )
109118 }
110119 }
111-
112- if current != nil {
113- cfg = config
114- }
115120 }
116121 return kubernetes .NewForConfig (cfg )
117122 }
0 commit comments