-
Notifications
You must be signed in to change notification settings - Fork 25k
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
Default ec2 endpoint is ec2.us-east-1.amazonaws.com #27925
Conversation
Document that we are using by default `ec2.us-east-1.amazonaws.com` as the EC2 endpoint if not explicitly set. Also switch to non deprecated method when building the EC2 Client. Closes elastic#27464.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a few comments.
String region = buildRegion(endpoint); | ||
// TODO according to the documentation we should set the region instead of setting a endpoint | ||
// See https://github.com/elastic/elasticsearch/issues/27924 | ||
logger.debug("Setting endpoint to [{}] with region [{}]", endpoint, region); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already have a debug level message in findEndpoint that is roughly equivalent.
logger.debug("Setting endpoint to [{}] with region [{}]", endpoint, region); | ||
builder.setEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endpoint, region)); | ||
} else { | ||
logger.debug("No endpoint defined. We are falling back to [ec2.us-east-1.amazonaws.com]."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Normally we wouldn't use "we" in a log message like this. I suggest Using default endpoint [...]
.
String endpoint = findEndpoint(logger, settings); | ||
if (endpoint != null) { | ||
client.setEndpoint(endpoint); | ||
String region = buildRegion(endpoint); | ||
// TODO according to the documentation we should set the region instead of setting a endpoint |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Part of the reason we moved away from region was it required bumping the aws client dep whenever a new region was added. By setting endpoint, we avoid that. For this reason, I do not think we should go back to setting region.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sense.
import java.io.IOException; | ||
import java.util.Random; | ||
|
||
import static com.amazonaws.util.AwsHostNameUtils.parseRegion; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't static import methods like this. I was very confused looking for this method within this file.
Thanks @rjernst! I pushed a new commit to address your points. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple more comments.
docs/plugins/discovery-ec2.asciidoc
Outdated
figured out by the ec2 client based on the instance location, but | ||
can be specified explicitly. See http://docs.aws.amazon.com/general/latest/gr/rande.html#ec2_region. | ||
The ec2 service endpoint to connect to. See http://docs.aws.amazon.com/general/latest/gr/rande.html#ec2_region. | ||
This will default to `ec2.us-east-1.amazonaws.com`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: will default to
-> defaults to
return this.client; | ||
} | ||
|
||
protected static String buildRegion(String endpoint) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be private
return this.client; | ||
} | ||
|
||
protected static String buildRegion(String endpoint) { | ||
// We try to get the region from the metadata instance information | ||
String region = new InstanceMetadataRegionProvider().getRegion(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we only be inferring this if the endpoint is not set?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That should come in another PR related to #27924 IMO.
Here, the goal is to call new AwsClientBuilder.EndpointConfiguration(endpoint, region)
. As we don't have the region anymore, I need to guess the region either from the instance metadata and if not available from the endpoint with AwsHostNameUtils.parseRegion(endpoint, null)
.
Make sense?
@rjernst Could you tell me what you think of the PR now? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, one last request.
String region = new InstanceMetadataRegionProvider().getRegion(); | ||
if (region == null) { | ||
// Or we try to get it from the endpoint itself | ||
region = AwsHostNameUtils.parseRegion(endpoint, null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we need to check for null again here? pareRegion
can return null if the endpoint is "non standard". I think we need to throw an error in that case or the endpoint configuration will be incorrect (endpoint but null region)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah! Good catch. Indeed the AWS implementation returns null. I'm going to add this. Thanks
Also adding some tests
@rjernst I pushed a new change. LMK. Thanks! |
jenkins test this please |
@dadoonet I think you need to sync with master, it looks like CI failed because it can't find gradlew. |
@elastic/es-distributed Any idea on how to solve the test issue I mentioned earlier on? #27925 (comment) |
The documentation is the most important part of this pull request (took me hours to discover this behavior). What do you think about merging only the docs? |
Yeah. I probably should have start only with that. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only necessary configuration change to enable the plugin
is setting the unicast host provider for zen discovery
I guess it's not true if the cluster is not in us-east-1
.
I split elastic#27925 in two parts: * The documentation fix (this PR) * The code fix (still in elastic#27925) Closes elastic#27464.
I opened #30323 to fix only the documentation issue which will leave time to merge this PR. |
any updates here @dadoonet ? do we still want to merge this one? |
@javanna I'm still waiting for an answer about #27925 (comment) |
thanks @dadoonet . ping @elastic/es-distributed your input is needed here. Can we move this forward? |
@tlrx can you maybe help? |
@dadoonet It looks you need some kind of fixture that mimics ec2 like it is done for repository-s3: AmazonS3Fixture is started before integration test and passing a system property
AmazonS3Fixture handles some EC2 requests (auth for the case of repository-s3) : Line 392 in 7c0fc20
At least /latest/dynamic/instance-identity/document has to be handled, so minor: within Hope it helps you to proceed further. |
# Conflicts: # docs/plugins/discovery-ec2.asciidoc # plugins/discovery-ec2/src/main/java/org/elasticsearch/discovery/ec2/AwsEc2ServiceImpl.java # plugins/discovery-ec2/src/test/java/org/elasticsearch/discovery/ec2/AwsEc2ServiceImplTests.java
I don't know if this PR is still useful or not. I'd assume it might be useless now. Thoughts? Note that documentation was updated with #30323. There is something which bugs me though. The fact that we are still using deprecated methods to build the new AmazonEC2Client(credentials, configuration); We should now use instead a builder as proposed with the current PR: AmazonEC2ClientBuilder builder = AmazonEC2ClientBuilder.standard()
.withCredentials(credentials)
.withClientConfiguration(configuration)
.withEndpointConfiguration(endpointConfiguration);
final AmazonEC2 client = builder.build(); Would you like another PR for this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dadoonet having discussed this with @DaveCTurner we think it still makes sense to change the discovery plugin such that it by default uses the endpoint for the current region.
Given that this is potentially a breaking change (with master nodes in us-east-1 and data nodes in some other region, the data nodes will no longer be able to discover the master nodes), we should:
- Make the new default for
discovery.ec2.endpoint
explicit by a magic constant like 'current_region_endpoint' (ie. make that the default value for the setting) - Add a breaking changes documentation piece on it.
- Update docs to mention this default (kind of back to what it was?)
- Only do this in 8.0
Regarding the test failure, it looks like @tlrx may have addressed this in #31107, please check if that resolves the test issue.
endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(clientSettings.endpoint, | ||
buildRegion(clientSettings.endpoint)); | ||
} else { | ||
logger.debug("No endpoint defined. Using default endpoint [ec2.us-east-1.amazonaws.com]."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When using the AmazonEC2ClientBuilder
, the default endpoint is current regions endpoint, see:
https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/java-dg-region-selection.html
This seems like a good default to use, but is a breaking change. See general review comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@henningandersen @DaveCTurner @dadoonet
Hello All,
We are looking for multiple region ec2-discovery option.
Can you please update where are we with the below comment. Is it already implemented and in-use or its gonna be in future release ?
Given that this is potentially a breaking change (with master nodes in us-east-1 and data nodes in some other region, the data nodes will no longer be able to discover the master nodes)
Thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@suganselvaraj this is still outstanding, i.e., not implemented into master or any releases yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that:
We are looking for multiple region ec2-discovery option.
This is not something we really support AFAIK. You should have all nodes within the same region for latency reasons.
My 2 cents.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@suganselvaraj I think it will not work using "ec2-discovery" because under the hood it's searching for nodes inside the same aws region.
You can use a fixed list of IP's, but it can cause latency issues.
if (Strings.hasText(clientSettings.endpoint)) { | ||
logger.debug("using explicit ec2 endpoint [{}]", clientSettings.endpoint); | ||
client.setEndpoint(clientSettings.endpoint); | ||
endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(clientSettings.endpoint, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I understand it, the region and endpoint has to go together and really specifying the endpoint should not be done. The region is used to determine signing as well, which means that using a wrong region for an endpoint is unlikely to work (AFAIK). Given that we calculate the region from the endpoint anyway, we may as well just call AwsClientBuilder.withRegion
with the region, this will ensure both the endpoint and signing region are set.
return client; | ||
} | ||
|
||
// Package private for tests | ||
static String buildRegion(String endpoint) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should get the region from the endpoint or if endpoint is not set, simply return null. Ie. we do not really need to lookup the region using the InstanceMetadataRegionProvider
since the SDK does that by itself when using the client builder.
Note that we can add the new magical value, |
Document that we are using by default
ec2.us-east-1.amazonaws.com
asthe EC2 endpoint if not explicitly set.
Also switch to non deprecated method when building the EC2 Client.
Closes #27464.