Skip to content

Commit 50437b4

Browse files
authored
Merge pull request kubernetes#85885 from nilo19/qi-vmss-cache
Provider/Azure: Add cache for VMSS.
2 parents 77a95dc + a5226f6 commit 50437b4

File tree

2 files changed

+87
-2
lines changed

2 files changed

+87
-2
lines changed

staging/src/k8s.io/legacy-cloud-providers/azure/azure_vmss.go

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ type scaleSet struct {
6060
// (e.g. master nodes) may not belong to any scale sets.
6161
availabilitySet VMSet
6262

63+
vmssCache *timedCache
6364
vmssVMCache *timedCache
6465
availabilitySetNodesCache *timedCache
6566
}
@@ -77,6 +78,11 @@ func newScaleSet(az *Cloud) (VMSet, error) {
7778
return nil, err
7879
}
7980

81+
ss.vmssCache, err = ss.newVMSSCache()
82+
if err != nil {
83+
return nil, err
84+
}
85+
8086
ss.vmssVMCache, err = ss.newVMSSVirtualMachinesCache()
8187
if err != nil {
8288
return nil, err
@@ -85,6 +91,43 @@ func newScaleSet(az *Cloud) (VMSet, error) {
8591
return ss, nil
8692
}
8793

94+
func (ss *scaleSet) getVMSS(vmssName string, crt cacheReadType) (*compute.VirtualMachineScaleSet, error) {
95+
getter := func(vmssName string) (*compute.VirtualMachineScaleSet, error) {
96+
cached, err := ss.vmssCache.Get(vmssKey, crt)
97+
if err != nil {
98+
return nil, err
99+
}
100+
101+
vmsses := cached.(*sync.Map)
102+
if vmss, ok := vmsses.Load(vmssName); ok {
103+
result := vmss.(*vmssEntry)
104+
return result.vmss, nil
105+
}
106+
107+
return nil, nil
108+
}
109+
110+
vmss, err := getter(vmssName)
111+
if err != nil {
112+
return nil, err
113+
}
114+
if vmss != nil {
115+
return vmss, nil
116+
}
117+
118+
klog.V(3).Infof("Couldn't find VMSS with name %s, refreshing the cache", vmssName)
119+
ss.vmssCache.Delete(vmssKey)
120+
vmss, err = getter(vmssName)
121+
if err != nil {
122+
return nil, err
123+
}
124+
125+
if vmss == nil {
126+
return nil, cloudprovider.InstanceNotFound
127+
}
128+
return vmss, nil
129+
}
130+
88131
// getVmssVM gets virtualMachineScaleSetVM by nodeName from cache.
89132
// It returns cloudprovider.InstanceNotFound if node does not belong to any scale sets.
90133
func (ss *scaleSet) getVmssVM(nodeName string, crt cacheReadType) (string, string, *compute.VirtualMachineScaleSetVM, error) {
@@ -903,7 +946,7 @@ func (ss *scaleSet) ensureVMSSInPool(service *v1.Service, nodes []*v1.Node, back
903946
}
904947

905948
for vmssName := range vmssNamesMap {
906-
vmss, err := ss.GetScaleSetWithRetry(service, ss.ResourceGroup, vmssName)
949+
vmss, err := ss.getVMSS(vmssName, cacheReadTypeDefault)
907950
if err != nil {
908951
return err
909952
}
@@ -1208,7 +1251,7 @@ func (ss *scaleSet) ensureBackendPoolDeletedFromVMSS(service *v1.Service, backen
12081251
}
12091252

12101253
for vmssName := range vmssNamesMap {
1211-
vmss, err := ss.GetScaleSetWithRetry(service, ss.ResourceGroup, vmssName)
1254+
vmss, err := ss.getVMSS(vmssName, cacheReadTypeDefault)
12121255

12131256
// When vmss is being deleted, CreateOrUpdate API would report "the vmss is being deleted" error.
12141257
// Since it is being deleted, we shouldn't send more CreateOrUpdate requests for it.

staging/src/k8s.io/legacy-cloud-providers/azure/azure_vmss_cache.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ limitations under the License.
1919
package azure
2020

2121
import (
22+
"context"
2223
"strings"
2324
"sync"
2425
"time"
@@ -33,10 +34,12 @@ import (
3334
var (
3435
vmssNameSeparator = "_"
3536

37+
vmssKey = "k8svmssKey"
3638
vmssVirtualMachinesKey = "k8svmssVirtualMachinesKey"
3739
availabilitySetNodesKey = "k8sAvailabilitySetNodesKey"
3840

3941
availabilitySetNodesCacheTTL = 15 * time.Minute
42+
vmssTTL = 10 * time.Minute
4043
vmssVirtualMachinesTTL = 10 * time.Minute
4144
)
4245

@@ -48,6 +51,45 @@ type vmssVirtualMachinesEntry struct {
4851
lastUpdate time.Time
4952
}
5053

54+
type vmssEntry struct {
55+
vmss *compute.VirtualMachineScaleSet
56+
lastUpdate time.Time
57+
}
58+
59+
func (ss *scaleSet) newVMSSCache() (*timedCache, error) {
60+
getter := func(key string) (interface{}, error) {
61+
localCache := &sync.Map{} // [vmssName]*vmssEntry
62+
63+
allResourceGroups, err := ss.GetResourceGroups()
64+
if err != nil {
65+
return nil, err
66+
}
67+
68+
for _, resourceGroup := range allResourceGroups.List() {
69+
allScaleSets, err := ss.VirtualMachineScaleSetsClient.List(context.Background(), resourceGroup)
70+
if err != nil {
71+
klog.Errorf("VirtualMachineScaleSetsClient.List failed: %v", err)
72+
return nil, err
73+
}
74+
75+
for _, scaleSet := range allScaleSets {
76+
if scaleSet.Name == nil || *scaleSet.Name == "" {
77+
klog.Warning("failed to get the name of VMSS")
78+
continue
79+
}
80+
localCache.Store(*scaleSet.Name, &vmssEntry{
81+
vmss: &scaleSet,
82+
lastUpdate: time.Now().UTC(),
83+
})
84+
}
85+
}
86+
87+
return localCache, nil
88+
}
89+
90+
return newTimedcache(vmssTTL, getter)
91+
}
92+
5193
func extractVmssVMName(name string) (string, string, error) {
5294
split := strings.SplitAfter(name, vmssNameSeparator)
5395
if len(split) < 2 {

0 commit comments

Comments
 (0)