aws / aws/containers-roadmap

[ECS] [Feature Request]: Implement a delay between CloudMap DeregisterInstance and when task is stopped during service update.

Open
#1,639 0 comments 21 reactions 0 assignees View on GitHub
ECS Proposed
Dominant language
Shell
Stars
5.4k
Forks
334
PR merge metrics
No merged PRs in 30d

Description

### Community Note

* Please vote on this issue by adding a 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to the original issue to help the community and maintainers prioritize this request
* Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
* If you are interested in working on this issue or have submitted a pull request, please leave a comment

**Tell us about your request**
When using API gateway and Cloud Map integration, there is an issue with requests being sent to tasks after SIGTERM is received when tasks are stopped during service updates. A delay between the time the CloudMap instance is deregistered and when the task is stopped it would allow for CloudMap to stop routing traffic to the task.

**Which service(s) is this request for?**
This could be Fargate, and ECS

**Tell us about the problem you're trying to solve. What are you trying to do, and why is it hard?**
API gateway uses CloudMap's DiscoverInstances API to determine the targets. During a service update, the task is stopped as soon as the target is deregistered. However, there is a cache on the API gateway side as requests are still routed to tasks which have received SIGTERM, resulting in 503 errors. A delay between the deregistration and StopTask would reduce these errors during the service update.

**Are you currently working around this issue?**
It is possible to use ALB, but would prefer to use service discovery and Cloud Map.

**Additional context**
To replicate the setup, API gateway with ECS Service Discovery integration is detailed in the below AWS blog post:
https://aws.amazon.com/blogs/architecture/field-notes-integrating-http-apis-with-aws-cloud-map-and-amazon-ecs-services/

The example uses a Flask App, accessed using the below S3 link:
https://cloudmap-shared.s3.eu-central-1.amazonaws.com/ExampleFlask.zip

We can modify `app.py` so that it can keep accepting requests after receiving SIGTERM. Below code snippet keeps accepting requests for 60 seconds after receiving SIGTERM:

```
from flask import Flask
import json
import signal
import time
import logging
import threading
import os

app = Flask(__name__)
app.logger.setLevel(logging.INFO)

@app.route('/')
def home():
return json.dumps({'result': 'Basic HTTP API Test'})

# sleep is a blocking action, hence creating another thread to sleep to prevent blocking of flask thread

def sleep_execution():
time.sleep(60)
app.logger.info('Done')
os._exit(1)

def shutdown(signum, frame):
app.logger.info('Caught SIGTERM, sleeping for 60 seconds')
sleep_thread = threading.Thread(target=sleep_execution)
sleep_thread.start()

if __name__== "__main__":
signal.signal(signal.SIGTERM, shutdown)
app_thread = threading.Thread(target=app.run(host='0.0.0.0',port=80))
app_thread.start()
```

`stopTimeout` in the ECS task definition should also be updated to 90 seconds. In my test, I am only using 1 task.

After initial deploy, we can force deploy a new deployment to replace the existing tasks. We can continuously access the API gateway endpoint during the update. I used the below bash script to send 10 requests per second to the API gateway endpoint:

```
#!/bin/bash

while true
do date | tee -a curl-output.log
curl 2> /dev/null | tee -a curl-output.log
printf "\nResponse Code: " | tee -a curl-output.log
curl -sL -w "%{http_code} \\n" -o /dev/null | tee -a curl-output.log
printf "\n" | tee -a curl-output.log
sleep 0.1
done
```

During update, we can see that requests are sent to task after SIGTERM is received:

| Timestamp | Message |
| --- | --- |
| 1643464479304 | 10.0.190.40 - - [29/Jan/2022 13:54:39] "GET / HTTP/1.1" 200 - |
| 1643464479589 | 10.0.190.40 - - [29/Jan/2022 13:54:39] "GET / HTTP/1.1" 200 - |
| 1643464480115 | [2022-01-29 13:54:40,115] INFO in app: Caught SIGTERM, sleeping for 60 seconds |
| 1643464480314 | 10.0.190.40 - - [29/Jan/2022 13:54:40] "GET / HTTP/1.1" 200 - |
| 1643464483332 | 10.0.190.40 - - [29/Jan/2022 13:54:43] "GET / HTTP/1.1" 200 - |
| 1643464487383 | 10.0.190.40 - - [29/Jan/2022 13:54:47] "GET / HTTP/1.1" 200 - |
| 1643464494315 | 10.0.190.40 - - [29/Jan/2022 13:54:54] "GET / HTTP/1.1" 200 - |
| 1643464540166 | [2022-01-29 13:55:40,166] INFO in app: Done |

**Attachments**
None

Contributor guide

Open the contributing guide

Research direction

The request concerns ECS service updates, Cloud Map deregistration, and task stopping; no repository files, tests, or implementation entry points are identified. Start with the linked AWS architecture example and the described API Gateway behavior; done would be a defined delay between deregistration and task stopping that prevents cached requests from reaching terminated tasks.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws
Domain
api, cloud
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.