components-contrib icon indicating copy to clipboard operation
components-contrib copied to clipboard

AWS ECS name resolution component

Open yaron2 opened this issue 3 years ago • 20 comments

It'd be great to add support for service invocation in AWS ECS so that Dapr sidecars can communicate between them securely.

Name resolution components sit here: https://github.com/dapr/components-contrib/tree/master/nameresolution.

Info on AWS ECS dns: https://aws.amazon.com/blogs/compute/service-discovery-for-amazon-ecs-using-dns/.

For anyone who wants to pick this up, please respond /assign in this issue.

yaron2 avatar Oct 13 '21 20:10 yaron2

I do not know the details of that, my concern is that each CSP has its own DNS service, is it better to add interfaces to call extern DNS rather than add?

daixiang0 avatar Oct 14 '21 00:10 daixiang0

@yaron2 I believe @daixiang0 is correct. Currently, we were able to enable ECS Service Discovery and assign each ECS Task it's own DNS Name.

For example: We currently have 3 ECS Tasks running using the same namespace ecssd.com:

  • Placement Service:
    • DNS = place.ecssd.com
  • CustomerA
    • DNS = customera.ecssd.com
    • SideCar using ./daprd -app-id customera.ecssd.com -placement-host-address place.ecssd.com:50005
  • CustomerB
    • DNS = customerb.ecssd.com
    • SideCar using ./daprd -app-id customerb.ecssd.com -placement-host-address place.ecssd.com:50005

CustomerA and CustomerB can communicate without any problem to Placement. CustomerA App and CustomerB can communicate directly without problems between each other

However, Dapr Sidecars Service to Service communication fails with the following error: fail to invoke, id: customera.ecssd.com, err: invalid app id customera.ecssd.com

Also, it evens fails when CustomerA Sidecar tries to communicate with it's own "CustomerA" app.

How hard would it be to implement what @daixiang0 is suggesting? I can volunteer to do this if it is in my reach.

fbridger avatar Oct 20 '21 11:10 fbridger

@daixiang0 I've noticed an unmentioned dns nameresolution component

Might this solved our problem and be used for ECS Service Discovery?

fbridger avatar Oct 20 '21 14:10 fbridger

@yaron2 @abogdanov37 Could the dns resolution included in PR https://github.com/dapr/dapr/pull/2903 might help us here?

fbridger avatar Oct 23 '21 16:10 fbridger

@yaron2 @abogdanov37 Could the dns resolution included in PR dapr/dapr#2903 might help us here?

Hi @fbridger! I think yes. It can resolve to use any DNS services. Maybe it needs some fixes. If that I will help with pleasure.

abogdanov37 avatar Oct 24 '21 08:10 abogdanov37

Thanks for your reply @abogdanov37!

@yaron2 @daixiang0 or @artursouza could any of you confirm this and suggest next steps to get the DNS resolution component merged and available to everyone?

fbridger avatar Oct 24 '21 14:10 fbridger

@fbridger @abogdanov37 @daixiang0 a general purpose DNS component can certainly do the trick here, but I want to get in the weeds about how this is going to work.

for example, one implementation can be that the ID of the target app IS actually the target DNS address. Or, we can configure the base DNS address in a component, like:

apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
  name: appconfig
spec:
  nameResolution:
    component: "dns"
    configuration:
      baseAddress: ecssd.com

And then the app-id is customera and customerb. Thoughts?

yaron2 avatar Oct 30 '21 04:10 yaron2

@yaron2: Having to configure the namespace or domain would definitely work in our implementation.

However, there may be scenarios where you may want to use different namespaces or domains for DNS entries like customera.ecssd.com and customerb.otherecssd.com.

So I would try to keep things as simple as possible (minimum yaml configuration) and allow AppIds to fully contain the entire DNS entry. If this is the case, would additional code changes be needed in Dapr Sidecars to support full DNS names in AppIds?

fbridger avatar Oct 30 '21 14:10 fbridger

@fbridger @abogdanov37 @daixiang0 a general purpose DNS component can certainly do the trick here, but I want to get in the weeds about how this is going to work.

for example, one implementation can be that the ID of the target app IS actually the target DNS address. Or, we can configure the base DNS address in a component, like:

apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
  name: appconfig
spec:
  nameResolution:
    component: "dns"
    configuration:
      baseAddress: ecssd.com

And then the app-id is customera and customerb. Thoughts?

Hi everyone! In current dns implementation I based on NAMESPACE. In my opinion, it is enough. If you have any cases in with it is not work please share it.

abogdanov37 avatar Nov 01 '21 13:11 abogdanov37

@abogdanov37 Do you mean the namespace that is configured in the config.yaml

Example:

apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
  name: config
  namespace: default # THIS NAMESPACE?

If this is the case, doing a Service Invocation from customerA to customerB like http://localhost:3500/v1.0/invoke/customerB/method/ping would result in a HTTP request to customerB.default ([AppId].[namespace]) ?

fbridger avatar Nov 01 '21 13:11 fbridger

Actually, thinking about this more, for simple "bring your own DNS" use cases (which I come to realize are important) we should decouple the name resolution component from the "discovery" aspect of it.

I propose the following:

An app can specify the address of the service it's calling via an HTTP header for HTTP requests and a new proto field on the Invoke method for gRPC calls.

Example

This example shows an app calling a different app, named serviceB over a well known DNS address:

curl http://localhost:3500/v1.0/invoke/cart/method/add -X POST  -H 'dapr-app-address: serviceb-prod.mydomain.com:8080'

This effectively tells Dapr "for this call, override the name resolution lookup".

@artursouza @beiwei30 what do you think?

yaron2 avatar Nov 01 '21 16:11 yaron2

@abogdanov37 Do you mean the namespace that is configured in the config.yaml

Example:

apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
  name: config
  namespace: default # THIS NAMESPACE?

If this is the case, doing a Service Invocation from customerA to customerB like http://localhost:3500/v1.0/invoke/customerB/method/ping would result in a HTTP request to customerB.default ([AppId].[namespace]) ?

Yes!

abogdanov37 avatar Nov 03 '21 12:11 abogdanov37

Actually, thinking about this more, for simple "bring your own DNS" use cases (which I come to realize are important) we should decouple the name resolution component from the "discovery" aspect of it.

I propose the following:

An app can specify the address of the service it's calling via an HTTP header for HTTP requests and a new proto field on the Invoke method for gRPC calls.

Example

This example shows an app calling a different app, named serviceB over a well known DNS address:

curl http://localhost:3500/v1.0/invoke/cart/method/add -X POST  -H 'dapr-app-address: serviceb-prod.mydomain.com:8080'

This effectively tells Dapr "for this call, override the name resolution lookup".

@artursouza @beiwei30 what do you think?

IMHO. In this case, we move the discovery function to client. And we will have problems with deployment in different environments. For example, deploy on test and on prod. We should change addresses in all calls. In another case, if we want to divide discovery ability from name resolution we should exclude consul name resolution.

abogdanov37 avatar Nov 03 '21 12:11 abogdanov37

@yaron2 @artursouza Any thoughts about this PR (https://github.com/dapr/dapr/pull/2903) on how we could allow the "bring your own DNS" feature so Dapr can work in environments like AWS ECS?

fbridger avatar Nov 14 '21 14:11 fbridger

/assign

jigargandhi avatar Dec 21 '21 14:12 jigargandhi

I can take up the work forward We can implement cloud specific DNS resolution based on the same DNS component in components contrib. Of course this will need to provide configuration for authentication in the component yaml.

@fbridger for your suggestion regarding full DNS entries, what would be the use cases for that, do you think that services may also be called externally, can we use CNAME for that redirection

jigargandhi avatar Dec 21 '21 14:12 jigargandhi

AWS ECS has integrated Service Discovery. We would like to simply be able to simply use the DNS name provided by this feature. I think this also applies to many other DNS components.

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-discovery.html

https://aws.amazon.com/es/blogs/aws/amazon-ecs-service-discovery/

fbridger avatar Dec 21 '21 15:12 fbridger

Any update on this?

Jan-Jasek avatar Feb 26 '23 18:02 Jan-Jasek

Any update on this ?

itsoli91 avatar Jan 11 '24 13:01 itsoli91

Actually, thinking about this more, for simple "bring your own DNS" use cases (which I come to realize are important) we should decouple the name resolution component from the "discovery" aspect of it.

I propose the following:

An app can specify the address of the service it's calling via an HTTP header for HTTP requests and a new proto field on the Invoke method for gRPC calls.

Example

This example shows an app calling a different app, named serviceB over a well known DNS address:

curl http://localhost:3500/v1.0/invoke/cart/method/add -X POST  -H 'dapr-app-address: serviceb-prod.mydomain.com:8080'

This effectively tells Dapr "for this call, override the name resolution lookup".

@artursouza @beiwei30 what do you think?

I wonder - what are the options currently to invoke a remote gRPC service.

dkuida avatar Apr 07 '24 21:04 dkuida