Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix device number and update table name the device index #1071

Merged
merged 1 commit into from
Sep 1, 2020

Conversation

mogren
Copy link
Contributor

@mogren mogren commented Jul 3, 2020

Description of changes:
When we attach new ENIs, we store the deviceNumber. We used to add +1 to all except the primary (device number 0). This was done because of how we named the route tables. This PR does the following:

  • Store the actual device number value in deviceNumber in the ENI struct (visible through introspect endpoint)
  • Have a tableNumber that matches the existing number used by previous versions
  • Set a hard upper limit of 100 for the device number to avoid clashes with vlan table names.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Copy link
Contributor

@jayanthvn jayanthvn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good :)

pkg/awsutils/awsutils.go Show resolved Hide resolved
pkg/networkutils/network.go Show resolved Hide resolved
@SaranBalaji90
Copy link
Contributor

This change is failing in our internal pipeline. Ip rule table number and actual route table table numbers were different.

@SaranBalaji90
Copy link
Contributor

Does eth1 gets route table number: 1 ?because I usually see different route table for eth1

Comment on lines -672 to -673
// 0 is reserved for primary ENI, the rest of them has to +1 to avoid collision at 0
return eni, int(deviceNum + 1), nil
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SaranBalaji90 Before this PR, eth1 gets table 2 because of this code, since it has device number 1. eth2 gets table 3 and so on.

Copy link
Contributor

@SaranBalaji90 SaranBalaji90 Aug 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure? Because on a c5.18xlarge eth1 got 15 but rest of them got similar number as device number - for eg eth2 got route table number 2 and so on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was the device index of eth1 14 at that time? The device index does not always match the interface name, especially when deleting and attaching a lot of ENIs. I have also seen eth4 get table 3 since it had the device number 2.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have the node now but I think looking at the code it should be 14. I wonder how is this number populated? Because of pod ENI feature we don't want this number to go beyond 100.

Copy link
Contributor

@anguslees anguslees Aug 31, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of pod ENI feature we don't want this number to go beyond 100

I know we're assuming that currently, but do we enforce that in the code anywhere? It sounds like this warrants a nice loud/obvious error message - if we ever accidentally trigger it.

Fwiw, I think the relevant code currently always looks for the lowest unoccupied DeviceNumber, so it will continue to reuse the same low numbers (bounded indirectly by max-eni) (good). In addition, I note the relevant bit of code imposes an artifical max of 128, for no particular reason (the code uses a fixed size array, whereas it could have dynamically resized the array, or used a sparse hash). We should probably lower maxENIs to 100, with a comment explaining why 100 is actually a real limit we have.

Copy link
Contributor

@SaranBalaji90 SaranBalaji90 Aug 31, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point Gus. For some reason I missed that we were setting the device index. I agree we should change it to 100 and raise error if there is no available index within 100.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call, set 100 as a hard limit.

// 0 is reserved for primary ENI, the rest of them has to +1 to avoid collision at 0
return eni, int(deviceNum + 1), nil
// 0 is reserved for primary ENI
return eniID, deviceNumber, nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has to be deviceNumber +1 to maintain backward compatibility otherwise how would this work on existing clusters? existing clusters might already have route for deviceNumber.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right that we can't change the table name now and stay backwards compatible on nodes that are already running. We are stuck using the name we currently have.

I have a different suggestion on how to solve it though. Let's use tableNumber := deviceNumber + 1 where we set up the routes, and stop having a variable called deviceNumber that doesn't actually store the device number. I'll update the PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯 If we're stuck with the +1 thing, we should absolutely stop calling it deviceNumber

@mogren mogren force-pushed the fix-device-id branch 2 times, most recently from a3b4b3f to c19ef53 Compare August 30, 2020 23:07
@mogren mogren force-pushed the fix-device-id branch 3 times, most recently from e690fa9 to 3c38011 Compare August 31, 2020 16:29
log.Errorf("Device number of primary ENI is %d! It was expected to be 0", deviceNumber)
// TODO: Can this happen? Is the only option to panic?
}
return eniID, deviceNumber, nil
Copy link
Contributor

@SaranBalaji90 SaranBalaji90 Aug 31, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we return 0 instead? (logger will help us to debug if something is not right?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, better to always return 0 here, together with an error log.

Copy link
Contributor

@SaranBalaji90 SaranBalaji90 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you test this change by upgrading running cluster and make sure everything works as expected?

@mogren
Copy link
Contributor Author

mogren commented Sep 1, 2020

@SaranBalaji90 Updated a running cluster both from v1.6.3, and from v1.7.1 to this build. Table numbers match.

Dst: &net.IPNet{IP: gw, Mask: net.CIDRMask(32, 32)},
Scope: netlink.SCOPE_LINK,
Table: eniTable,
Table: tableNumber,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This didn't fail any test is it? Because now the value that is passed to this method and table number are different, I would expect mock to fail?

// 0 is reserved for primary ENI, the rest of them has to +1 to avoid collision at 0
return eni, int(deviceNum + 1), nil
// 0 is reserved for primary ENI
return eniID, deviceNumber, nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change should have failed some unit test right? For eg instead of returning x now it will be returning x-1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SaranBalaji90
Copy link
Contributor

Thanks @mogren. Will definitely help in future when reading the code.

@SaranBalaji90 SaranBalaji90 merged commit 6eb28fa into aws:master Sep 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants