Container images
A container image is a set of instructions on how to build the container. A container image holds your application code and all the dependencies that your application code requires to run. Application dependencies include the source code packages that your application code relies on, a language runtime for interpreted languages, and binary packages that your dynamically linked code relies on.
Use the following guidelines when you design and build your container images:
-
Make your container images complete by storing all application dependencies as static files inside the container image.
If you want to change something in the container image, build a new container image with the changes applied to it.
-
Run a single application process within a container.
The container lifetime is as long as the application process runs.
Crashed processes are replaced through a centralized decision making process in the Amazon ECS control plane. The control plane makes smarter choices about where to launch the replacement process. This makes the overall deployment more resilient than if each individual compute instance attempts to relaunch its own processes locally.
-
Handle
SIGTERM
within the applicationWhen Amazon ECS stops a task, it first sends a SIGTERM signal to the task to notify the application needs to finish and shut down, and then Amazon ECS sends a
SIGKILL
message. When applications ignore theSIGTERM
, the Amazon ECS service must wait to send theSIGKILL
signal to terminate the process..To prepare your application, you need to identify how long it takes your application to complete its work, and ensure that your applications handles the
SIGTERM
signal. Within the application's signal handling, you need to stop the application from taking new work and complete the work that is in-progress, or save unfinished work to storage outside of the task if it would take too long to complete. -
Configure containerized applications to write logs to
stdout
andstderr
.When you decouple log handling from your application code, it gives you greater flexibility to adjust log handling at the infrastructure level. Assume that you want to switch from one logging system to another. You can do so by adjusting a few settings at the container orchestrator level, rather than having to change code in all your services, build a new container image, and deploy it.
-
Use tags to version your container images.
Container images are stored in a container registry. Each image in a registry is identified by a tag. There's a tag called
latest
. This tag functions as a pointer to the latest version of the application container image, similar to theHEAD
in a git repository. We recommend that you use thelatest
tag only for testing purposes. As a best practice, tag container images with a unique tag for each build. We recommend that you tag your images using the git SHA for the git commit that was used to build the image.You don’t need to build a container image for every commit. However, we recommend that you build a new container image each time you release a particular code commit to the production environment. We also recommend that you tag the image with a tag that corresponds to the git commit of the code that's inside the image. If you tagged the image with the git commit, you can more quickly find which version of the code the image is running.
We also recommend that you turn on immutable image tags in Amazon Elastic Container Registry. With this setting, you can't change the container image that a tag points at. Instead Amazon ECR enforces that a new image must be uploaded to a new tag, rather than overwriting a pre-existing tag. For more information, see Image tag mutability in the Amazon ECR User Guide.
In addition to the above list, when you architect your application to run on Amazon ECS using AWS Fargate, you must decide between deploying multiple containers into the same task definition and deploying containers separately in multiple task definitions.
If the following conditions are required, we recommend deploying multiple containers into the same task definition:
-
Your containers share a common lifecycle (that is, they're launched and terminated together).
-
Your containers must run on the same underlying host (that is, one container references the other on a localhost port).
-
You containers share resources.
-
Your containers share data volumes.
If these conditions aren't required, we recommend deploying containers separately in multiple task definitions. This is because, by doing so, you can scale, provision, and deprovision them separately.
Lazy loading container images using Seekable OCI (SOCI)
Amazon ECS tasks on Fargate that use Linux platform version 1.4.0
can use
Seekable OCI (SOCI) to help start tasks faster.
With SOCI, containers only spend a few seconds on the image pull before
they can start, providing time for environment setup and application
instantiation while the image is downloaded in the background.
This is called lazy loading. When Fargate starts an Amazon ECS task, Fargate automatically detects
if a SOCI index exists for an image in the task and starts the container without waiting
for the entire image to be downloaded.
For containers that run without SOCI indexes, container images are downloaded completely before the container is started. This behavior is the same on all other platform versions of Fargate and on the Amazon ECS-optimized AMI on Amazon EC2 instances.
Seekable OCI indexes
Seekable OCI (SOCI) is an open source technology developed by AWS that can launch
containers faster by lazily loading the container image. SOCI works by creating an index
(SOCI Index) of the files within an existing container image. This index helps to launch
containers faster, providing the capability to extract an
individual file from a container image before downloading the entire image.
The SOCI index must be stored as an artifact in the same repository as the image
within the container registry. You should only use SOCI indices from trusted sources,
as the index is the authoritative source for the contents of the image.
For more information, see Introducing Seekable OCI for lazy loading container
images
Considerations
If you want Fargate to use a SOCI index to lazily load container images in a task, consider the following:
-
Only tasks that run on Linux platform version
1.4.0
can use SOCI indexes. Tasks that run Windows containers on Fargate aren't supported. -
Tasks that run on X86_64 or ARM64 CPU architecture are supported. Linux tasks with the ARM64 architecture do not support the Fargate Spot capacity provider.
-
Container images in the task definition must have SOCI indexes in the same container registry as the image.
-
Container images in the task definition must be stored in a compatible image registry. The following lists the compatible registries:
-
Amazon ECR private registries.
-
-
Only container images that use gzip compression or are not compressed are supported. Container images that use zstd compression aren't supported.
-
We recommend that you try lazy loading with container images greater than 250 MiB compressed in size. You are less likely to see a reduction in the time to load smaller images.
-
Because lazy loading can change how long your tasks take to start, you might need to change various timeouts like the health check grace period for Elastic Load Balancing.
-
If you want to prevent a container image from being lazy loaded, delete the SOCI index from the container registry. If a container image in the task doesn't meet one of the considerations, that container image is downloaded by the default method.
Creating a Seekable OCI index
To create SOCI indexes, first you create the index of the files in
the container image. To do this, you can use the open
source CLI tool awslabs/soci-snapshotter
Note
For the SOCI index to be created for an image, the image must exist in the
containerd image store on the computer running soci-snapshotter
.
If the image is in the Docker image store, the image can't be found.
Verifying that a task used lazy loading
To verify that a task was lazily loaded using SOCI, check the task
metadata endpoint from inside the task. When you query the task metadata endpoint
version 4, there is a Snapshotter
field in the default path for the
container that you are querying from. Additionally, there are
Snapshotter
fields for each container in the /task
path.
The default value for this field is overlayfs
,
and this field is set to soci
if SOCI is used. For more information, see Task metadata endpoint version 4 in the Amazon Elastic Container Service User Guide for AWS Fargate.