1

I'm searching for a way to add a domain name to an ECS service (EC2 not Fargate).

To be clear I'm looking for a solution which DNS resolves a domain name A or AAAA name (possibly CNAME if it and points to an A or AAAA). It doesn't matter to me which network mode this works for. The container can be placed in any of host, bridge, awsvpc if the solution works!

awsvpc is not viable outside of Fargate

Solutions requiring AWS VPC seem to be incompatible with ECS/EC2 and only viable for Fargate. Reason here:

Each Amazon ECS task that uses the awsvpc network mode receives its own elastic network interface (ENI), which is attached to the Amazon EC2 instance that hosts it. There's a default quota for the number of network interfaces that can be attached to an Amazon EC2 Linux instance. The primary network interface counts as one toward that quota.

So a t3.medium can run only 2 tasks and even a t3.2xlarge can only run 3 (limits here)

Service discovery is not viable

Service Discovery will only add SRV type DNS records for host and bridge type network containers. Most software we run does not understand SRV records. We need A and AAAA records.

Service Discovery will create A and AAAA records for awsvpc network type containers... back to awsvpc not being viable.

AWS App Mesh is not viable

We tried setting up app mesh and were almost immediately told our tasks need to be awsvpc

¯\(ツ)

Load balancers appear to be unviable

This might work for some services. But then we fall down big holes either where the service is not HTTP or the service requires clients be authenticated with SSL client certificates.

Creating many IP load balancers for non HTTP / client SSL services is cost prohibitive.

<rant>

AFAIK, Kubernetes would have made this trivial. Even docker swarm has this. I'm really shocked how many hours we've spent searching for this one trivial thing.<\rant>

Question

How to add a domain name to an ECS/EC2 container without a load balancer?

Philip Couling
  • 1,535
  • 1
  • 17
  • 32

3 Answers3

0

I am not clear about the question. Service Discovery does support a domain name (namespace). It's actually mandatory as far as I can tell. In other words if you want to use SD for an ECS service called myservice you have to refer to it as myservice.<domain> where <domain> is an arbitrary namespace you have to define (such as .local or .my.domain). Here is an example of a stack that uses SD.

Note that all this is internal to the cluster and how internal service discovery works (e.g. how an ECS service discovers another ECS service).

[Edit] IF you want to expose your ECS services but DO NOT want to use a load balancer another option would be to use API GW as described in this blog post. In general you do not want to register random public IP addresses of Fargate tasks in R53 because they are ephemeral and you'd need to build complex mechanism to keep them aligned when Fargate tasks come and go. Have you also considered App Runner?

mreferre
  • 426
  • 1
  • 5
  • This only creates DNS SRV records as far as I know. Wen browsers and many other clients do not look for SRV records and don't know how to use them. ...Unless you run on fargate. – Philip Couling Sep 22 '21 at 08:24
  • Yes. That is what I meant by "Internal to the cluster". I have updated my answer. – mreferre Sep 22 '21 at 08:57
  • 1
    "Having a solution which tracks the changing IP of the service is kinda the point of the question" <- yes agreed. That solution is Service Discovery for internal service discovery and ELB / APIGW+CloudMap (see blog I linked) for external customer facing services. I don't think there are other solutions for that (other than exposing Fargate tasks with public IPs and build a reconciliation loop with Route53). – mreferre Sep 22 '21 at 11:27
  • I've run into this same rock again and again with slightly different angles every time. Service discovery has never yet been a viable solution because either it creates SRV records which are practically useless (existing software largely doesn't understand them) and A/AAAA name records can only be added to service discovery with `AWSVPC` networking. If you are running EC2, not fargate, then that's not a practical option because you are then limited to 1-2 containers per host. – Philip Couling Sep 16 '22 at 10:54
  • 1
    @PhilipCouling You are not limited to 1-2 containers per host; you can run up to 498 tasks on certain instance types. https://docs.aws.amazon.com/AmazonECS/latest/developerguide/container-instance-eni.html – ceejayoz Sep 16 '22 at 11:58
  • @ceejayoz I'll look into interface trunking is it may help. Though this doesn't appear to be a drop in solution. It needs to be enabled on the account (I have no idea what the impact of that is) and it seems to add other limitations as well as limiting instance tyes. The comparison is not correct either. Those instance types that can run 498 with trunking were already capable of running 9 tasks and are very expensive. The 1-3 task instances only achieve 10-40 with trunking. – Philip Couling Sep 16 '22 at 12:27
  • @PhilipCouling Impacts of enabling it are negligible in most cases and detailed at https://aws.amazon.com/fr/blogs/compute/optimizing-amazon-ecs-task-density-using-awsvpc-network-mode/; 10x as many tasks per instance is nothing to sneer at. – ceejayoz Sep 16 '22 at 12:31
0

To clarify, you don't want to have a unique elastic network interface attached to the ECS container (because of limits per instance), because that would be easy to terraform or whatever.

Roll your own AppMesh Solution via systemd :

Use a bash script run via systemd startup to access IMDS lookup the public ip-address for the ECS service, followed by an AWS CLI to update a dns record. This is obviously very late binding, so make sure you set the TTL very low.

Next Answer: "Don't do that"

Yes it does work, but this next post explains why the previous approach is bad/flawed: How to get the IP Address for a specific AWS ECS task?

Use Route53 (probably wont work well) alias records:

It's possible you could use Route53 Alias records (which are symbolic), but I don't think they'd update fast enough and cause all sorts of problems ..

https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-choosing-alias-non-alias.html

Roll your own:

This could be based on SRV records, but also doesn't implicitly need to be. Reverse engineer/roll your own AWS Load balancer and run that as a service on your EC2 ECS container (it could be lightweight, speak over named pipes, IPC, or IP to ECS). Consider using RUST as a base, perhaps pingora to use SRV records, modify it to suite your needs.

This is the only solution where I think it would be fast & reliable enough to actually work reasonably well.

Best Answer:

If you don't want to roll your own solution either pay Amazon, or move to a more enterprise solution such as K3s or K8s.