Skip to content

Commit 8205f81

Browse files
davidz627jsafrane
authored andcommitted
Wait for APIServer 'ok' forever during CSINode initialization during Kubelet init
1 parent 3842a92 commit 8205f81

File tree

1 file changed

+37
-11
lines changed

1 file changed

+37
-11
lines changed

pkg/volume/csi/csi_plugin.go

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,10 @@ func (p *csiPlugin) Init(host volume.VolumeHost) error {
227227

228228
if utilfeature.DefaultFeatureGate.Enabled(features.CSINodeInfo) &&
229229
utilfeature.DefaultFeatureGate.Enabled(features.CSIMigration) {
230-
// This function prevents Kubelet from posting Ready status until CSINodeInfo
230+
// This function prevents Kubelet from posting Ready status until CSINode
231231
// is both installed and initialized
232232
if err := initializeCSINode(host); err != nil {
233-
return errors.New(log("failed to initialize CSINodeInfo: %v", err))
233+
return errors.New(log("failed to initialize CSINode: %v", err))
234234
}
235235
}
236236

@@ -240,21 +240,27 @@ func (p *csiPlugin) Init(host volume.VolumeHost) error {
240240
func initializeCSINode(host volume.VolumeHost) error {
241241
kvh, ok := host.(volume.KubeletVolumeHost)
242242
if !ok {
243-
klog.V(4).Info("Cast from VolumeHost to KubeletVolumeHost failed. Skipping CSINodeInfo initialization, not running on kubelet")
243+
klog.V(4).Info("Cast from VolumeHost to KubeletVolumeHost failed. Skipping CSINode initialization, not running on kubelet")
244244
return nil
245245
}
246246
kubeClient := host.GetKubeClient()
247247
if kubeClient == nil {
248-
// Kubelet running in standalone mode. Skip CSINodeInfo initialization
249-
klog.Warning("Skipping CSINodeInfo initialization, kubelet running in standalone mode")
248+
// Kubelet running in standalone mode. Skip CSINode initialization
249+
klog.Warning("Skipping CSINode initialization, kubelet running in standalone mode")
250250
return nil
251251
}
252252

253-
kvh.SetKubeletError(errors.New("CSINodeInfo is not yet initialized"))
253+
kvh.SetKubeletError(errors.New("CSINode is not yet initialized"))
254254

255255
go func() {
256256
defer utilruntime.HandleCrash()
257257

258+
// First wait indefinitely to talk to Kube APIServer
259+
err := waitForAPIServerForever(kubeClient)
260+
if err != nil {
261+
klog.Fatalf("Failed to initialize CSINode while waiting for API server to report ok: %v", err)
262+
}
263+
258264
// Backoff parameters tuned to retry over 140 seconds. Will fail and restart the Kubelet
259265
// after max retry steps.
260266
initBackoff := wait.Backoff{
@@ -263,12 +269,12 @@ func initializeCSINode(host volume.VolumeHost) error {
263269
Factor: 6.0,
264270
Jitter: 0.1,
265271
}
266-
err := wait.ExponentialBackoff(initBackoff, func() (bool, error) {
267-
klog.V(4).Infof("Initializing migrated drivers on CSINodeInfo")
272+
err = wait.ExponentialBackoff(initBackoff, func() (bool, error) {
273+
klog.V(4).Infof("Initializing migrated drivers on CSINode")
268274
err := nim.InitializeCSINodeWithAnnotation()
269275
if err != nil {
270-
kvh.SetKubeletError(fmt.Errorf("Failed to initialize CSINodeInfo: %v", err))
271-
klog.Errorf("Failed to initialize CSINodeInfo: %v", err)
276+
kvh.SetKubeletError(fmt.Errorf("Failed to initialize CSINode: %v", err))
277+
klog.Errorf("Failed to initialize CSINode: %v", err)
272278
return false, nil
273279
}
274280

@@ -282,7 +288,7 @@ func initializeCSINode(host volume.VolumeHost) error {
282288
// using CSI for all Migrated volume plugins. Then all the CSINode initialization
283289
// code can be dropped from Kubelet.
284290
// Kill the Kubelet process and allow it to restart to retry initialization
285-
klog.Fatalf("Failed to initialize CSINodeInfo after retrying")
291+
klog.Fatalf("Failed to initialize CSINode after retrying: %v", err)
286292
}
287293
}()
288294
return nil
@@ -914,3 +920,23 @@ func highestSupportedVersion(versions []string) (*utilversion.Version, error) {
914920
}
915921
return highestSupportedVersion, nil
916922
}
923+
924+
// waitForAPIServerForever waits forever to get the APIServer Version as a proxy
925+
// for a healthy APIServer.
926+
func waitForAPIServerForever(client clientset.Interface) error {
927+
var lastErr error
928+
err := wait.PollInfinite(time.Second, func() (bool, error) {
929+
_, lastErr = client.Discovery().ServerVersion()
930+
if lastErr != nil {
931+
lastErr = fmt.Errorf("failed to get apiserver version: %v", lastErr)
932+
return false, nil
933+
}
934+
935+
return true, nil
936+
})
937+
if err != nil {
938+
return fmt.Errorf("%v: %v", err, lastErr)
939+
}
940+
941+
return nil
942+
}

0 commit comments

Comments
 (0)