4
4
"context"
5
5
"fmt"
6
6
7
+ "k8s.io/apimachinery/pkg/api/errors"
7
8
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
8
9
clientset "k8s.io/client-go/kubernetes"
9
10
cloudprovider "k8s.io/cloud-provider"
@@ -29,16 +30,22 @@ func StartCloudNodeLifecycleControllerWrapper(initContext app.ControllerInitCont
29
30
30
31
//nolint:gocritic // need to follow upstream function signature
31
32
func startCloudNodeLifecycleController (ctx context.Context ,
32
- initContext app.ControllerInitContext ,
33
+ _ app.ControllerInitContext ,
33
34
controlexContext controllermanagerapp.ControllerContext ,
34
35
completedConfig * config.CompletedConfig ,
35
36
cloud cloudprovider.Interface ,
36
37
) (controller.Interface , bool , error ) {
38
+ // Use CCM's kubeconfig to create a clientset for the custom node lifecycle controller because we need permissions
39
+ // to list and delete VolumeAttachments
40
+ ccmClientSet , err := clientset .NewForConfig (completedConfig .Kubeconfig )
41
+ if err != nil {
42
+ return nil , false , fmt .Errorf ("failed to create clientset from ccm kubeconfig: %w" , err )
43
+ }
44
+
37
45
// Start the cloudNodeLifecycleController
38
46
cloudNodeLifecycleController , err := NewCloudNodeLifecycleController (
39
47
completedConfig .SharedInformers .Core ().V1 ().Nodes (),
40
- // cloud node lifecycle controller uses existing cluster role from node-controller
41
- completedConfig .ClientBuilder .ClientOrDie (initContext .ClientName ),
48
+ ccmClientSet ,
42
49
cloud ,
43
50
completedConfig .ComponentConfig .KubeCloudShared .NodeMonitorPeriod .Duration ,
44
51
)
@@ -54,19 +61,24 @@ func startCloudNodeLifecycleController(ctx context.Context,
54
61
}
55
62
56
63
func CleanUpVolumeAttachmentsForNode (ctx context.Context , kubeClient clientset.Interface , nodeName string ) error {
57
- volumeAttachments , listErr := kubeClient .StorageV1 ().VolumeAttachments ().List (ctx ,
58
- metav1.ListOptions {FieldSelector : fmt .Sprintf ("spec.nodeName=%s" , nodeName )})
59
-
64
+ volumeAttachments , listErr := kubeClient .StorageV1 ().VolumeAttachments ().List (ctx , metav1.ListOptions {})
60
65
if listErr != nil {
61
- return fmt .Errorf ("failed to list volume attachments for node %s : %w" , nodeName , listErr )
66
+ return fmt .Errorf ("failed to list all volume attachments: %w" , listErr )
62
67
}
63
68
64
69
for index := range len (volumeAttachments .Items ) {
65
70
volumeAttachment := volumeAttachments .Items [index ]
71
+ if volumeAttachment .Spec .NodeName != nodeName {
72
+ continue
73
+ }
66
74
deleteErr := kubeClient .StorageV1 ().VolumeAttachments ().Delete (ctx , volumeAttachment .Name , metav1.DeleteOptions {})
67
75
if deleteErr != nil {
68
- klog .Errorf ("failed to delete volume attachment %s for node %s: %v" ,
69
- volumeAttachment .Name , nodeName , deleteErr )
76
+ if errors .IsNotFound (deleteErr ) {
77
+ klog .Infof ("volume attachment %s for node %s already deleted, skipping delete" , volumeAttachment .Name , nodeName )
78
+ } else {
79
+ klog .Errorf ("failed to delete volume attachment %s for node %s: %v" ,
80
+ volumeAttachment .Name , nodeName , deleteErr )
81
+ }
70
82
}
71
83
}
72
84
0 commit comments