@@ -20,6 +20,7 @@ import (
20
20
"fmt"
21
21
"io"
22
22
"io/ioutil"
23
+ "os"
23
24
"path/filepath"
24
25
"strings"
25
26
@@ -28,6 +29,8 @@ import (
28
29
flag "github.com/spf13/pflag"
29
30
30
31
"k8s.io/apimachinery/pkg/runtime"
32
+ "k8s.io/apimachinery/pkg/util/wait"
33
+ clientset "k8s.io/client-go/kubernetes"
31
34
certutil "k8s.io/client-go/util/cert"
32
35
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
33
36
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
@@ -237,9 +240,23 @@ func (j *Join) Run(out io.Writer) error {
237
240
return err
238
241
}
239
242
243
+ kubeconfigFile := filepath .Join (kubeadmconstants .KubernetesDir , kubeadmconstants .KubeletBootstrapKubeConfigFileName )
244
+
245
+ // Write the bootstrap kubelet config file or the TLS-Boostrapped kubelet config file down to disk
246
+ if err := kubeconfigutil .WriteToDisk (kubeconfigFile , cfg ); err != nil {
247
+ return fmt .Errorf ("couldn't save bootstrap-kubelet.conf to disk: %v" , err )
248
+ }
249
+
250
+ // Write the ca certificate to disk so kubelet can use it for authentication
251
+ cluster := cfg .Contexts [cfg .CurrentContext ].Cluster
252
+ err = certutil .WriteCert (j .cfg .CACertPath , cfg .Clusters [cluster ].CertificateAuthorityData )
253
+ if err != nil {
254
+ return fmt .Errorf ("couldn't save the CA certificate to disk: %v" , err )
255
+ }
256
+
240
257
// NOTE: flag "--dynamic-config-dir" should be specified in /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
241
258
if features .Enabled (j .cfg .FeatureGates , features .DynamicKubeletConfig ) {
242
- client , err := kubeconfigutil . ClientSetFromFile ( kubeadmconstants . GetAdminKubeConfigPath () )
259
+ client , err := getTLSBootstrappedClient ( )
243
260
if err != nil {
244
261
return err
245
262
}
@@ -250,20 +267,25 @@ func (j *Join) Run(out io.Writer) error {
250
267
}
251
268
}
252
269
253
- kubeconfigFile := filepath .Join (kubeadmconstants .KubernetesDir , kubeadmconstants .KubeletBootstrapKubeConfigFileName )
270
+ fmt .Fprintf (out , joinDoneMsgf )
271
+ return nil
272
+ }
254
273
255
- // Write the bootstrap kubelet config file or the TLS-Boostrapped kubelet config file down to disk
256
- if err := kubeconfigutil . WriteToDisk ( kubeconfigFile , cfg ); err != nil {
257
- return err
258
- }
274
+ // getTLSBootstrappedClient waits for the kubelet to perform the TLS bootstrap
275
+ // and then creates a client from config file /etc/kubernetes/kubelet.conf
276
+ func getTLSBootstrappedClient () (clientset. Interface , error ) {
277
+ fmt . Println ( "[tlsbootstrap] Waiting for the kubelet to perform the TLS Bootstrap..." )
259
278
260
- // Write the ca certificate to disk so kubelet can use it for authentication
261
- cluster := cfg .Contexts [cfg .CurrentContext ].Cluster
262
- err = certutil .WriteCert (j .cfg .CACertPath , cfg .Clusters [cluster ].CertificateAuthorityData )
279
+ kubeletKubeConfig := filepath .Join (kubeadmconstants .KubernetesDir , kubeadmconstants .KubeletKubeConfigFileName )
280
+
281
+ // Loop on every falsy return. Return with an error if raised. Exit successfully if true is returned.
282
+ err := wait .PollImmediateInfinite (kubeadmconstants .APICallRetryInterval , func () (bool , error ) {
283
+ _ , err := os .Stat (kubeletKubeConfig )
284
+ return (err == nil ), nil
285
+ })
263
286
if err != nil {
264
- return fmt . Errorf ( "couldn't save the CA certificate to disk: %v" , err )
287
+ return nil , err
265
288
}
266
289
267
- fmt .Fprintf (out , joinDoneMsgf )
268
- return nil
290
+ return kubeconfigutil .ClientSetFromFile (kubeletKubeConfig )
269
291
}
0 commit comments