Skip to content

Commit e2e1900

Browse files
angusleesmogren
authored andcommitted
Don't cache dynamic VPC IPv4 CIDR info
Rather than cache and then update the cache - just don't cache :)
1 parent 4b0e4e1 commit e2e1900

File tree

7 files changed

+49
-59
lines changed

7 files changed

+49
-59
lines changed

pkg/awsutils/awsutils.go

Lines changed: 16 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ type APIs interface {
129129
DeallocIPAddresses(eniID string, ips []string) error
130130

131131
// GetVPCIPv4CIDRs returns VPC's CIDRs from instance metadata
132-
GetVPCIPv4CIDRs() []string
132+
GetVPCIPv4CIDRs() ([]string, error)
133133

134134
// GetLocalIPv4 returns the primary IP address on the primary ENI interface
135135
GetLocalIPv4() net.IP
@@ -164,7 +164,6 @@ type EC2InstanceMetadataCache struct {
164164
localIPv4 net.IP
165165
instanceID string
166166
instanceType string
167-
vpcIPv4CIDRs StringSet
168167
primaryENI string
169168
primaryENImac string
170169
availabilityZone string
@@ -401,16 +400,9 @@ func (cache *EC2InstanceMetadataCache) initWithEC2Metadata(ctx context.Context)
401400
return err
402401
}
403402

404-
// retrieve VPC IPv4 CIDR blocks
405-
err = cache.refreshVPCIPv4CIDRs(mac)
406-
if err != nil {
407-
return err
408-
}
409-
410403
// Refresh security groups and VPC CIDR blocks in the background
411404
// Ignoring errors since we will retry in 30s
412405
go wait.Forever(func() { _ = cache.refreshSGIDs(mac) }, 30*time.Second)
413-
go wait.Forever(func() { _ = cache.refreshVPCIPv4CIDRs(mac) }, 30*time.Second)
414406

415407
// We use the ctx here for testing, since we spawn go-routines above which will run forever.
416408
select {
@@ -484,36 +476,6 @@ func (cache *EC2InstanceMetadataCache) refreshSGIDs(mac string) error {
484476
return nil
485477
}
486478

487-
// refreshVPCIPv4CIDRs retrieves VPC IPv4 CIDR blocks
488-
func (cache *EC2InstanceMetadataCache) refreshVPCIPv4CIDRs(mac string) error {
489-
ctx := context.TODO()
490-
491-
ipnets, err := cache.imds.GetVPCIPv4CIDRBlocks(ctx, mac)
492-
if err != nil {
493-
return err
494-
}
495-
496-
// TODO: keep as net.IPNet and remove this round-trip to/from string
497-
vpcIPv4CIDRs := make([]string, len(ipnets))
498-
for i, ipnet := range ipnets {
499-
vpcIPv4CIDRs[i] = ipnet.String()
500-
}
501-
502-
newVpcIPv4CIDRs := StringSet{}
503-
newVpcIPv4CIDRs.Set(vpcIPv4CIDRs)
504-
addedVpcIPv4CIDRs := newVpcIPv4CIDRs.Difference(&cache.vpcIPv4CIDRs)
505-
deletedVpcIPv4CIDRs := cache.vpcIPv4CIDRs.Difference(&newVpcIPv4CIDRs)
506-
507-
for _, vpcIPv4CIDR := range addedVpcIPv4CIDRs.SortedList() {
508-
log.Infof("Found %s, added to ipamd cache", vpcIPv4CIDR)
509-
}
510-
for _, vpcIPv4CIDR := range deletedVpcIPv4CIDRs.SortedList() {
511-
log.Infof("Removed %s from ipamd cache", vpcIPv4CIDR)
512-
}
513-
cache.vpcIPv4CIDRs.Set(vpcIPv4CIDRs)
514-
return nil
515-
}
516-
517479
// GetAttachedENIs retrieves ENI information from meta data service
518480
func (cache *EC2InstanceMetadataCache) GetAttachedENIs() (eniList []ENIMetadata, err error) {
519481
ctx := context.TODO()
@@ -1454,8 +1416,21 @@ func (cache *EC2InstanceMetadataCache) getFilteredListOfNetworkInterfaces() ([]*
14541416
}
14551417

14561418
// GetVPCIPv4CIDRs returns VPC CIDRs
1457-
func (cache *EC2InstanceMetadataCache) GetVPCIPv4CIDRs() []string {
1458-
return cache.vpcIPv4CIDRs.SortedList()
1419+
func (cache *EC2InstanceMetadataCache) GetVPCIPv4CIDRs() ([]string, error) {
1420+
ctx := context.TODO()
1421+
1422+
ipnets, err := cache.imds.GetVPCIPv4CIDRBlocks(ctx, cache.primaryENImac)
1423+
if err != nil {
1424+
return nil, err
1425+
}
1426+
1427+
// TODO: keep as net.IPNet and remove this round-trip to/from string
1428+
asStrs := make([]string, len(ipnets))
1429+
for i, ipnet := range ipnets {
1430+
asStrs[i] = ipnet.String()
1431+
}
1432+
1433+
return asStrs, nil
14591434
}
14601435

14611436
// GetLocalIPv4 returns the primary IP address on the primary interface

pkg/awsutils/awsutils_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ func TestInitWithEC2metadata(t *testing.T) {
124124
assert.Equal(t, ins.primaryENI, primaryeniID)
125125
assert.Equal(t, len(ins.securityGroups.SortedList()), 2)
126126
assert.Equal(t, subnetID, ins.subnetID)
127-
assert.Equal(t, len(ins.vpcIPv4CIDRs.SortedList()), 2)
128127
}
129128
}
130129

pkg/awsutils/mocks/awsutils_mocks.go

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/ipamd/ipamd.go

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import (
1717
"fmt"
1818
"net"
1919
"os"
20-
"reflect"
2120
"strconv"
2221
"strings"
2322
"sync"
@@ -36,6 +35,7 @@ import (
3635
"github.com/aws/aws-sdk-go/service/ec2"
3736
"github.com/pkg/errors"
3837
"github.com/prometheus/client_golang/prometheus"
38+
"k8s.io/apimachinery/pkg/util/sets"
3939
"k8s.io/apimachinery/pkg/util/wait"
4040
"k8s.io/client-go/kubernetes"
4141
)
@@ -332,7 +332,10 @@ func (c *IPAMContext) nodeInit() error {
332332
return err
333333
}
334334

335-
vpcCIDRs := c.awsClient.GetVPCIPv4CIDRs()
335+
vpcCIDRs, err := c.awsClient.GetVPCIPv4CIDRs()
336+
if err != nil {
337+
return err
338+
}
336339
primaryIP := c.awsClient.GetLocalIPv4()
337340
err = c.networkClient.SetupHostNetwork(vpcCIDRs, c.awsClient.GetPrimaryENImac(), &primaryIP, c.enablePodENI)
338341
if err != nil {
@@ -382,6 +385,10 @@ func (c *IPAMContext) nodeInit() error {
382385
if err = c.configureIPRulesForPods(vpcCIDRs); err != nil {
383386
return err
384387
}
388+
// Spawning updateCIDRsRulesOnChange go-routine
389+
go wait.Forever(func() {
390+
vpcCIDRs = c.updateCIDRsRulesOnChange(vpcCIDRs)
391+
}, 30*time.Second)
385392

386393
if c.useCustomNetworking && c.eniConfig.Getter().MyENI != "default" {
387394
// Signal to VPC Resource Controller that the node is using custom networking
@@ -424,8 +431,6 @@ func (c *IPAMContext) nodeInit() error {
424431
return err
425432
}
426433

427-
// Spawning updateCIDRsRulesOnChange go-routine
428-
go wait.Forever(func() { vpcCIDRs = c.updateCIDRsRulesOnChange(vpcCIDRs) }, 30*time.Second)
429434
return nil
430435
}
431436

@@ -450,10 +455,16 @@ func (c *IPAMContext) configureIPRulesForPods(pbVPCcidrs []string) error {
450455
return nil
451456
}
452457

453-
func (c *IPAMContext) updateCIDRsRulesOnChange(oldVPCCidrs []string) []string {
454-
newVPCCIDRs := c.awsClient.GetVPCIPv4CIDRs()
458+
func (c *IPAMContext) updateCIDRsRulesOnChange(oldVPCCIDRs []string) []string {
459+
newVPCCIDRs, err := c.awsClient.GetVPCIPv4CIDRs()
460+
if err != nil {
461+
log.Warnf("skipping periodic update to VPC CIDRs due to error: %v", err)
462+
return oldVPCCIDRs
463+
}
455464

456-
if len(oldVPCCidrs) != len(newVPCCIDRs) || !reflect.DeepEqual(oldVPCCidrs, newVPCCIDRs) {
465+
old := sets.NewString(oldVPCCIDRs...)
466+
new := sets.NewString(newVPCCIDRs...)
467+
if !old.Equal(new) {
457468
_ = c.configureIPRulesForPods(newVPCCIDRs)
458469
}
459470
return newVPCCIDRs

pkg/ipamd/ipamd_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ func TestNodeInit(t *testing.T) {
112112
m.awsutils.EXPECT().IsUnmanagedENI(eni2.ENIID).Return(false).AnyTimes()
113113

114114
primaryIP := net.ParseIP(ipaddr01)
115-
m.awsutils.EXPECT().GetVPCIPv4CIDRs().AnyTimes().Return(cidrs)
115+
m.awsutils.EXPECT().GetVPCIPv4CIDRs().AnyTimes().Return(cidrs, nil)
116116
m.awsutils.EXPECT().GetPrimaryENImac().Return("")
117117
m.network.EXPECT().SetupHostNetwork(cidrs, "", &primaryIP, false).Return(nil)
118118

pkg/ipamd/rpc_handler.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,10 @@ func (s *server) AddNetwork(ctx context.Context, in *rpc.AddNetworkRequest) (*rp
140140
}
141141
addr, deviceNumber, err = s.ipamContext.dataStore.AssignPodIPv4Address(ipamKey)
142142
}
143-
pbVPCcidrs := s.ipamContext.awsClient.GetVPCIPv4CIDRs()
143+
pbVPCcidrs, err := s.ipamContext.awsClient.GetVPCIPv4CIDRs()
144+
if err != nil {
145+
return nil, err
146+
}
144147
for _, cidr := range pbVPCcidrs {
145148
log.Debugf("VPC CIDR %s", cidr)
146149
}

pkg/ipamd/rpc_handler_test.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func TestServer_VersionCheck(t *testing.T) {
3737
networkClient: m.network,
3838
dataStore: datastore.NewDataStore(log, datastore.NullCheckpoint{}),
3939
}
40-
m.awsutils.EXPECT().GetVPCIPv4CIDRs().Return([]string{})
40+
m.awsutils.EXPECT().GetVPCIPv4CIDRs().Return([]string{}, nil)
4141
m.network.EXPECT().UseExternalSNAT().Return(true)
4242

4343
rpcServer := server{
@@ -126,18 +126,19 @@ func TestServer_AddNetwork(t *testing.T) {
126126
},
127127
}
128128
for _, tc := range testCases {
129-
m.awsutils.EXPECT().GetVPCIPv4CIDRs().Return(tc.vpcCIDRs)
129+
m.awsutils.EXPECT().GetVPCIPv4CIDRs().Return(tc.vpcCIDRs, nil)
130130
m.network.EXPECT().UseExternalSNAT().Return(tc.useExternalSNAT)
131131
if !tc.useExternalSNAT {
132132
m.network.EXPECT().GetExcludeSNATCIDRs().Return(tc.snatExclusionCIDRs)
133133
}
134134

135135
addNetworkReply, err := rpcServer.AddNetwork(context.TODO(), addNetworkRequest)
136-
assert.NoError(t, err, tc.name)
136+
if assert.NoError(t, err, tc.name) {
137137

138-
assert.Equal(t, tc.useExternalSNAT, addNetworkReply.UseExternalSNAT, tc.name)
138+
assert.Equal(t, tc.useExternalSNAT, addNetworkReply.UseExternalSNAT, tc.name)
139139

140-
expectedCIDRs := append([]string{vpcCIDR}, tc.snatExclusionCIDRs...)
141-
assert.Equal(t, expectedCIDRs, addNetworkReply.VPCcidrs, tc.name)
140+
expectedCIDRs := append([]string{vpcCIDR}, tc.snatExclusionCIDRs...)
141+
assert.Equal(t, expectedCIDRs, addNetworkReply.VPCcidrs, tc.name)
142+
}
142143
}
143144
}

0 commit comments

Comments
 (0)