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