@@ -25,6 +25,7 @@ import (
25
25
"sort"
26
26
"strconv"
27
27
"strings"
28
+ "sync"
28
29
29
30
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-07-01/compute"
30
31
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2019-06-01/network"
@@ -60,10 +61,8 @@ type scaleSet struct {
60
61
// (e.g. master nodes) may not belong to any scale sets.
61
62
availabilitySet VMSet
62
63
63
- vmssCache * timedCache
64
- vmssVMCache * timedCache
65
- nodeNameToScaleSetMappingCache * timedCache
66
- availabilitySetNodesCache * timedCache
64
+ vmssVMCache * timedCache
65
+ availabilitySetNodesCache * timedCache
67
66
}
68
67
69
68
// newScaleSet creates a new scaleSet.
@@ -74,22 +73,12 @@ func newScaleSet(az *Cloud) (VMSet, error) {
74
73
availabilitySet : newAvailabilitySet (az ),
75
74
}
76
75
77
- ss .nodeNameToScaleSetMappingCache , err = ss .newNodeNameToScaleSetMappingCache ()
78
- if err != nil {
79
- return nil , err
80
- }
81
-
82
76
ss .availabilitySetNodesCache , err = ss .newAvailabilitySetNodesCache ()
83
77
if err != nil {
84
78
return nil , err
85
79
}
86
80
87
- ss .vmssCache , err = ss .newVmssCache ()
88
- if err != nil {
89
- return nil , err
90
- }
91
-
92
- ss .vmssVMCache , err = ss .newVmssVMCache ()
81
+ ss .vmssVMCache , err = ss .newVMSSVirtualMachinesCache ()
93
82
if err != nil {
94
83
return nil , err
95
84
}
@@ -99,39 +88,46 @@ func newScaleSet(az *Cloud) (VMSet, error) {
99
88
100
89
// getVmssVM gets virtualMachineScaleSetVM by nodeName from cache.
101
90
// It returns cloudprovider.InstanceNotFound if node does not belong to any scale sets.
102
- func (ss * scaleSet ) getVmssVM (nodeName string ) (ssName , instanceID string , vm compute.VirtualMachineScaleSetVM , err error ) {
103
- instanceID , err = getScaleSetVMInstanceID (nodeName )
104
- if err != nil {
105
- return ssName , instanceID , vm , err
106
- }
91
+ func (ss * scaleSet ) getVmssVM (nodeName string ) (string , string , * compute.VirtualMachineScaleSetVM , error ) {
92
+ getter := func (nodeName string ) (string , string , * compute.VirtualMachineScaleSetVM , error ) {
93
+ cached , err := ss .vmssVMCache .Get (vmssVirtualMachinesKey )
94
+ if err != nil {
95
+ return "" , "" , nil , err
96
+ }
107
97
108
- ssName , err = ss .getScaleSetNameByNodeName (nodeName )
109
- if err != nil {
110
- return ssName , instanceID , vm , err
111
- }
98
+ virtualMachines := cached .(* sync.Map )
99
+ if vm , ok := virtualMachines .Load (nodeName ); ok {
100
+ result := vm .(* vmssVirtualMachinesEntry )
101
+ return result .vmssName , result .instanceID , result .virtualMachine , nil
102
+ }
112
103
113
- if ssName == "" {
114
- return "" , "" , vm , cloudprovider .InstanceNotFound
104
+ return "" , "" , nil , nil
115
105
}
116
106
117
- resourceGroup , err := ss . GetNodeResourceGroup (nodeName )
107
+ _ , err := getScaleSetVMInstanceID (nodeName )
118
108
if err != nil {
119
- return "" , "" , vm , err
109
+ return "" , "" , nil , err
120
110
}
121
111
122
- klog .V (4 ).Infof ("getVmssVM gets scaleSetName (%q) and instanceID (%q) for node %q" , ssName , instanceID , nodeName )
123
- key := buildVmssCacheKey (resourceGroup , ss .makeVmssVMName (ssName , instanceID ))
124
- cachedVM , err := ss .vmssVMCache .Get (key )
112
+ vmssName , instanceID , vm , err := getter (nodeName )
125
113
if err != nil {
126
- return ssName , instanceID , vm , err
114
+ return "" , "" , nil , err
115
+ }
116
+ if vm != nil {
117
+ return vmssName , instanceID , vm , nil
127
118
}
128
119
129
- if cachedVM == nil {
130
- klog .Errorf ("Can't find node (%q) in any scale sets" , nodeName )
131
- return ssName , instanceID , vm , cloudprovider .InstanceNotFound
120
+ klog .V (3 ).Infof ("Couldn't find VMSS VM with nodeName %s, refreshing the cache" , nodeName )
121
+ ss .vmssVMCache .Delete (vmssVirtualMachinesKey )
122
+ vmssName , instanceID , vm , err = getter (nodeName )
123
+ if err != nil {
124
+ return "" , "" , nil , err
132
125
}
133
126
134
- return ssName , instanceID , * (cachedVM .(* compute.VirtualMachineScaleSetVM )), nil
127
+ if vm == nil {
128
+ return "" , "" , nil , cloudprovider .InstanceNotFound
129
+ }
130
+ return vmssName , instanceID , vm , nil
135
131
}
136
132
137
133
// GetPowerStatusByNodeName returns the power state of the specified node.
@@ -158,20 +154,49 @@ func (ss *scaleSet) GetPowerStatusByNodeName(name string) (powerState string, er
158
154
159
155
// getCachedVirtualMachineByInstanceID gets scaleSetVMInfo from cache.
160
156
// The node must belong to one of scale sets.
161
- func (ss * scaleSet ) getVmssVMByInstanceID (resourceGroup , scaleSetName , instanceID string ) (vm compute.VirtualMachineScaleSetVM , err error ) {
162
- vmName := ss .makeVmssVMName (scaleSetName , instanceID )
163
- key := buildVmssCacheKey (resourceGroup , vmName )
164
- cachedVM , err := ss .vmssVMCache .Get (key )
157
+ func (ss * scaleSet ) getVmssVMByInstanceID (resourceGroup , scaleSetName , instanceID string ) (* compute.VirtualMachineScaleSetVM , error ) {
158
+ getter := func () (vm * compute.VirtualMachineScaleSetVM , found bool , err error ) {
159
+ cached , err := ss .vmssVMCache .Get (vmssVirtualMachinesKey )
160
+ if err != nil {
161
+ return nil , false , err
162
+ }
163
+
164
+ virtualMachines := cached .(* sync.Map )
165
+ virtualMachines .Range (func (key , value interface {}) bool {
166
+ vmEntry := value .(* vmssVirtualMachinesEntry )
167
+ if strings .EqualFold (vmEntry .resourceGroup , resourceGroup ) &&
168
+ strings .EqualFold (vmEntry .vmssName , scaleSetName ) &&
169
+ strings .EqualFold (vmEntry .instanceID , instanceID ) {
170
+ vm = vmEntry .virtualMachine
171
+ found = true
172
+ return false
173
+ }
174
+
175
+ return true
176
+ })
177
+
178
+ return vm , found , nil
179
+ }
180
+
181
+ vm , found , err := getter ()
165
182
if err != nil {
166
- return vm , err
183
+ return nil , err
184
+ }
185
+ if found {
186
+ return vm , nil
167
187
}
168
188
169
- if cachedVM == nil {
170
- klog .Errorf ("couldn't find vmss virtual machine by scaleSetName (%s) and instanceID (%s)" , scaleSetName , instanceID )
171
- return vm , cloudprovider .InstanceNotFound
189
+ klog .V (3 ).Infof ("Couldn't find VMSS VM with scaleSetName %q and instanceID %q, refreshing the cache" , scaleSetName , instanceID )
190
+ ss .vmssVMCache .Delete (vmssVirtualMachinesKey )
191
+ vm , found , err = getter ()
192
+ if err != nil {
193
+ return nil , err
194
+ }
195
+ if ! found {
196
+ return nil , cloudprovider .InstanceNotFound
172
197
}
173
198
174
- return * ( cachedVM .( * compute. VirtualMachineScaleSetVM )) , nil
199
+ return vm , nil
175
200
}
176
201
177
202
// GetInstanceIDByNodeName gets the cloud provider ID by node name.
@@ -463,9 +488,15 @@ func (ss *scaleSet) listScaleSets(resourceGroup string) ([]string, error) {
463
488
return nil , err
464
489
}
465
490
466
- ssNames := make ([]string , len (allScaleSets ))
467
- for i := range allScaleSets {
468
- ssNames [i ] = * (allScaleSets [i ].Name )
491
+ ssNames := make ([]string , 0 )
492
+ for _ , vmss := range allScaleSets {
493
+ name := * vmss .Name
494
+ if vmss .Sku != nil && to .Int64 (vmss .Sku .Capacity ) == 0 {
495
+ klog .V (3 ).Infof ("Capacity of VMSS %q is 0, skipping" , name )
496
+ continue
497
+ }
498
+
499
+ ssNames = append (ssNames , name )
469
500
}
470
501
471
502
return ssNames , nil
@@ -500,7 +531,7 @@ func (ss *scaleSet) getAgentPoolScaleSets(nodes []*v1.Node) (*[]string, error) {
500
531
}
501
532
502
533
nodeName := nodes [nx ].Name
503
- ssName , err := ss .getScaleSetNameByNodeName (nodeName )
534
+ ssName , _ , _ , err := ss .getVmssVM (nodeName )
504
535
if err != nil {
505
536
return nil , err
506
537
}
@@ -599,7 +630,7 @@ func (ss *scaleSet) GetPrimaryInterface(nodeName string) (network.Interface, err
599
630
return network.Interface {}, err
600
631
}
601
632
602
- primaryInterfaceID , err := ss .getPrimaryInterfaceID (vm )
633
+ primaryInterfaceID , err := ss .getPrimaryInterfaceID (* vm )
603
634
if err != nil {
604
635
klog .Errorf ("error: ss.GetPrimaryInterface(%s), ss.getPrimaryInterfaceID(), err=%v" , nodeName , err )
605
636
return network.Interface {}, err
@@ -816,8 +847,9 @@ func (ss *scaleSet) EnsureHostInPool(service *v1.Service, nodeName types.NodeNam
816
847
}
817
848
818
849
// Invalidate the cache since we would update it.
819
- key := buildVmssCacheKey (nodeResourceGroup , ss .makeVmssVMName (ssName , instanceID ))
820
- defer ss .vmssVMCache .Delete (key )
850
+ if err = ss .deleteCacheForNode (vmName ); err != nil {
851
+ return err
852
+ }
821
853
822
854
// Update vmssVM with backoff.
823
855
ctx , cancel := getContextWithCancel ()
@@ -1094,8 +1126,9 @@ func (ss *scaleSet) ensureBackendPoolDeletedFromNode(service *v1.Service, nodeNa
1094
1126
}
1095
1127
1096
1128
// Invalidate the cache since we would update it.
1097
- key := buildVmssCacheKey (nodeResourceGroup , ss .makeVmssVMName (ssName , instanceID ))
1098
- defer ss .vmssVMCache .Delete (key )
1129
+ if err = ss .deleteCacheForNode (nodeName ); err != nil {
1130
+ return err
1131
+ }
1099
1132
1100
1133
// Update vmssVM with backoff.
1101
1134
ctx , cancel := getContextWithCancel ()
0 commit comments