Containerized Applications on AWS

30 阅读15分钟

Reading 1.1

What is a container?

Containers provide a standard way to package your application's code, configurations, and dependencies into a single object. Containers share an operating system that's installed on the server. They run as resource-isolated processes, and are designed to provide quick, reliable, and consistent deployments—regardless of environment. For more information about containers and their benefits, see Containers Deep Dive.

Namespaces and cgroups

With containers, you can isolate processes from each other, which is a key component of how containers work. For more information about how namespaces and control groups (cgroups) work with containers, see What are Namespaces and cgroups, and how do they work? on the NGINX blog.

OCI

In this course, we mostly talk about using Docker containers. However, in 2015, Docker and other industry leaders came together to form the Open Container Initiative (OCI). The purpose of the OCI is to create standards for container formats and runtimes. For more information about the OCI, see About the Open Container Initiative.

Docker documentation

For more information about Docker, see the Docker documentation.

Benefits of containers

  • Optimization of resource utilization: You can fit multiple, lightweight containers on a single virtual machine, and increase the efficiency and density of your resources.
  • Automation: The standard packaging and interaction with containers can make it easier to automate software development lifecycle tasks, such as building, deploying, and scaling applications.
  • Speed: Containers are quick to run. You can start, scale, or delete containers in seconds.
  • Scalability: Because containers facilitate microservices architectures, you can meet demand by using containers to scale out horizontally both quickly and efficiently.
  • Increased developer productivity:
  • Developers can spend less time on operations and environment debugging, and spend more time on application development.
  • Code portability: Having confidence that your workload will behave consistently across environments is one of the major benefits of containers.

For more information about the benefits and use cases for using containers on AWS, see Containers at AWS.

Reading 1.2

For more information about the basic components of the Docker platform and how they work together, see Docker overview.

What is the Docker daemon?

The Docker daemon runs on a host and listens for API calls to manage Docker objects. For example, if you want to build an image, run a container, or create a volume, you can use the Docker command line interface (CLI) to create the request. The request will then be submitted to the Docker daemon to be managed.

What is the Docker CLI?

The Docker command line interface (CLI) is the client interface for interacting with Docker objects. The Docker CLI is how you issue commands to Docker to build your containers, run your containers, or stop your containers.

What is a Dockerfile?

A Dockerfile is a text document that contains instructions on how to build your container image. A Dockerfile includes instructions for what base layer to use (for example, whether you want to use a minimal version of Linux or use an image that has preinstalled software, such as a database engine). Other instructions include running commands in the container, or copying your application data, dependencies, and configurations into the container. For more information, see Best Practices for writing Dockerfiles.

What is a Docker image?

A container image is created when you run the build command from the Docker CLI and it follows the instructions in a Dockerfile. A container image is made up of a series of read-only layers, with one writable layer on top where files can be added, modified, or deleted. Each layer is created from an instruction in the Dockerfile.

What is an image registry?

An image registry is a repository where you can store container images. You can store the images either publicly or privately. From the repository, images can be pulled and deployed, or used by other developers.

How do I store data in my container?

For more information about how to store data with Docker containers, see Managing data in Docker.

Reading 1.3

What are the contents of a Dockerfile?

The Dockerfile example that’s used in the demonstration uses the following instructions. These instructions were used as a good starting point for learning. For more information about Dockerfile instructions, see Dockerfile reference.

  • FROM: Defines the base image. All the instructions that follow are run in a container launched from the base image.
  • WORKDIR: Sets the working directory for the subsequence instructions.
  • ENV: Sets environment variables.
  • COPY: Copies files and directories into the container image.
  • RUN: Runs commands in the new container. This instruction commits a new layer on top of the present layer.
  • CMD: Sets the default command to run when the container is launched.
  • EXPOSE: Is used to document the containers that the port exposes.

Docker commands

For more information, see the full reference for the docker base command.

  • docker build: Builds an image from a Dockerfile. In the demonstration, we pass -t to tag the image that’s created.
  • docker run: Creates and starts a container. In the demonstration, we use -p to expose ports, -e to set environment variables, and -v to bind mount volumes.
  • docker exec: Runs a command in a running container.
  • docker stop: Stops a container.
  • docker rm: Removes a container. Use -f to force the remove.

Reading 1.4

What is an image registry?

An image registry is a repository where you can store container images. From this registry, both DevOps tools and people can pull down container images to run, deploy, or expand on. Image registries can be public or private. Public registries are useful for providing images that can be used as base images for software development. For example, if your company provided a database engine, you could host images with the database software preinstalled on it. Your customers could then use these images as base images to expand on, which would make it easier for them to get their software up and running. Private registries are useful in situations where you don’t want to expose container images to the public, which is often the case with proprietary software.

Docker Hub

Docker Hub is a popular repository for container images. It offers a variety of sources for container images that you can use, including images from container community developers, open-source projects, and software vendors. For more information about Docker Hub, see Docker Hub.

Amazon ECR

Amazon Elastic Container Registry (Amazon ECR) is a private, container image registry. With Amazon ECR, you can create multiple repositories to store and share your container images. To make it easier to deploy your containerized application, Amazon ECR integrates with other AWS services—such as Amazon Elastic Container Service (Amazon ECS), Amazon Elastic Kubernetes Service (Amazon EKS), and AWS Lambda.

Amazon ECR Public

Amazon ECR also offers a highly available repository for your public images. You can create a repository for your authenticated AWS Identity and Access Management (IAM) identities to push to a public image repository. Thus, an unauthenticated user with or without an AWS account can pull from your public repository. For more information and to see a searchable list of public repositories, see the Amazon ECR Public Gallery.

AWS App Runner

AWS App Runner provides a way to run your containerized application on AWS infrastructure. You only need to supply a container image or application source to App Runner. App Runner creates all the infrastructure needed to host your application, and it also supplies you with an HTTP endpoint. App Runner serves your application with end-to-end encryption. As load increases, it will also scale within parameters that you define.

Week 1 FAQs

Q: Where can I find the list of available Dockerfile instructions? A: The Docker documentation does a good job of providing a list of instructions you can use with examples and explanations at Dockerfile reference.

Q: Is there an application programming interface (API) reference for the Docker engine? A: Yes. For more information, see Develop with Docker Engine API.

Q: What is the difference between virtual machines (VMs) and containers? A: VMs make it possible to host multiple isolated guest operating systems (OSs) on top of a host machine by virtualizing the hardware environment and sharing host resources with guest OSs. Each guest OS must have its own full guest OS. The guest OS interacts with the hypervisor, which then interacts with the host OS. With containers, the OS is virtualized. Each container doesn’t need a full guest OS, and multiple containers on the same host can share layers where appropriate. This makes each container lightweight in nature when compared to VMs. The containers interact with the containerization engine (such as Docker) instead of with the hypervisor. That being said, you can run containers on top of VMs. So, these two technologies are not mutually exclusive. When running containers on AWS, both VMs and containers are being used together.

Q: Does the data that my applications write to the writable layer persist? A: No, any data that’s stored in the writable layer doesn’t persist when the container no longer exists. For more information, see Manage data in Docker.

Q: How does persistent storage work with containers?

A: With containers, you have a few options for storing data in a persistent manner. You can use Docker volumes or bind mounts. You can also use external databases, caches, object storage, or file storage. For more information about when and how to use volumes and bind mounts, see Manage data in Docker. For more information about available caching and database services for persistent storage on AWS, see Best Practices – Persistent storage and Cloud Storage on AWS.

Q: What’s the difference between Amazon Elastic Compute Cloud (Amazon EC2) and containers? A: Amazon EC2 is an AWS service that provides virtual machines on demand. Containers can be hosted on top of Amazon EC2, which you will learn more about in Week 2 of the course.

Q: How can I discover base images to use in my projects? A. It’s common practice to use public base images as the starting point for containerized application development. Using the work that other developers have done can help you speed up your application development. You can find many different community images at Docker Hub and in the Amazon ECR Public Gallery. For example, say that you need to containerize an application that uses MySQL. Instead of including the installation instructions for MySQL in your Dockerfile, you can instead start by using the MySQL public base image from Docker Hub. You could then include instructions in your Dockerfile to add any other libraries or features that are needed (such as backup tools, for example).

Q: How can I scan my images for security vulnerabilities? A: You can use many tools to scan your container images for vulnerabilities. Ideally, you would perform the scan immediately after a container is checked into a repository. Amazon Elastic Container Registry (Amazon ECR) provides built-in image scanning for vulnerabilities. Amazon ECR offers the following scanning types:

  • Enhanced scanning: 

    • Amazon ECR integrates with Amazon Inspector to provide automated, nearly continuous scanning of your repositories. 
    • Your container images are scanned for vulnerabilities in both operating systems and programming language packages. 
    • As new vulnerabilities appear, the scan results are updated, and Amazon Inspector notifies you by emitting an event to Amazon EventBridge.
  • Basic scanning: 

    • Amazon ECR uses the Common Vulnerabilities and Exposures (CVEs) database from the open-source Clair project. 

    • With basic scanning, you have a couple of options:

      • First, you can configure your repositories to scan on push. 
      • You can also perform manual scans, and Amazon ECR will provide a list of scan findings.

For more information about Amazon ECR image scanning, see Image scanning. For more information about open-source image-scanning tools, see 5 open source tools for container security on opensource.com.

Q: Do I need to use Amazon Elastic Container Registry (Amazon ECR) to use AWS container-hosting services? A: No. You can also use other container registry services to integrate with AWS container-hosting services (such as Docker Hub, for example). For more information, see the AWS Blog post Authenticating with Docker Hub for AWS Container Services.

Reading 2.1

MICROSERVICE APPLICATIONS

When you design a new application or upgrade an existing application, you make decisions about the architecture of the application. You might have seen a small or older application that has a monolithic architecture. In a monolithic architecture, your application layers are built into a single deployable artifact, and calls between layers are simple function calls. This is a straightforward way to work, but it does have some disadvantages. Each application deployment is a deployment of the entire application, even if you change a single layer. It can also become difficult to mix programming languages if you need to make function calls between languages. A microservice architecture is a popular alternative. With a microservice architecture, your application is decomposed into smaller, independent services. Services run independently and communicate with network protocols. By using independent services, you can do the following:

  • Scale and deploy individual services
  • Build teams around services that match business functions
  • Choose the correct programming language and technology for each service

The rapid pace of deployment in a distributed microservices architecture lends itself to containerization. If you need to make a change to a single service, you can deploy containers of the new version of the service and switch all communications to the new containers.

DOCKER COMPOSE

Docker Compose is a tool for automating tasks in a multi-container environment. You can define the container settings—such as ports, volumes, and commands—into a single YAML file. You can use a single Docker Compose command to launch multiple containers from the YAML file. Starting with a sample docker-compose.yaml file, you can see how Docker parameters are defined into a declarative file.

services: wordpress: image: wordpress:latest ports: - "80:80" database: image: mysql:5.7 environment: MYSQL_RANDOM_ROOT_PASSWORD: 1 MYSQL_DATABASE: wordpress

The example YAML file creates two containers. The image setting sets the Docker image that will be used for the container. The ports setting defines the container ports that are made available on the host. The database container is configured with environment variables in the environment settings. The simple example can be the following command: docker compose up. Docker Compose launches containers with the provided parameters, and creates a Docker network for the containers to communicate. These are all tasks you could perform by using Docker commands. Docker Compose can automate these steps for you. After the containers launch, you can use some additional Docker Compose commands to interact with the containers and inspect them, such as the following:

  • docker compose exec: Run commands inside of the containers (for example, launch a shell inside the container environment)
  • docker compose logs: Inspect log output
  • docker compose down: Stop and remove the running containers

For more information, see the Overview of Docker Compose.

Reading 2.2

Comparing the control plane and the data plane

The control plane ****consists of the cluster control components that expose APIs and interfaces to define, deploy, and manage the lifecycle of containers. For Amazon Elastic Container Service (Amazon ECS), you interact with the control plane by using the Amazon ECS API. The data plane ****is the infrastructure that provides the capacity for containers to run, such as CPU, memory, network, and storage.

Amazon ECS

Amazon ECS is a highly scalable and fast container-management service. You can use it to run, stop, and manage containers on a cluster. With Amazon ECS, your containers are defined in a task definition that you use to run an individual task or a task within a service. In this context, a service is a configuration that you can use to run and maintain a specified number of tasks simultaneously in a cluster. You can run your tasks and services on a serverless infrastructure that's managed by AWS Fargate. Alternatively, for more control over your infrastructure, you can run your tasks and services on a cluster of Amazon Elastic Compute Cloud (Amazon EC2) instances that you manage.For more information about Amazon ECS, see What is Amazon Elastic Container Service?

Core concepts for Amazon ECS

  • Cluster: A logical grouping of tasks or services. Your tasks and services are run on infrastructure that’s registered to a cluster, such as AWS Fargate nodes, EC2 instances, or remote virtual machines (VMs). For more information about clusters for Amazon ECS, see Amazon ECS clusters.

  • Container instances: A container instance is an EC2 instance that’s a part of your Amazon ECS cluster. A container instance isn’t the same as a task, which contains a running instance of your container. For more information about container instances, see Amazon ECS container instances.

  • Container agent: The container agent allows container instances to connect to your Amazon ECS cluster. For more information about the Amazon ECS container agent, see Amazon ECS container agent.

  • Task definition: A task definition contains configuration information for the containers you want to run on Amazon ECS. You need to create a task definition to run containers on Amazon ECS. Task definitions include parameters, such as the following:

    • The Docker image to use with each container in your task.
    • How much CPU and memory to use with each task or each container within a task.
    • The launch type to use, which determines the infrastructure where your tasks are hosted.
    • The Docker networking mode to use for the containers in your task.
    • The logging configuration to use for your tasks.
    • Whether the task should continue to run if the container finishes or fails.
    • The command the container should run when it’s started.
    • Any data volumes that should be used with the containers in the task.
    • The AWS Identity and Access Management (IAM) role that your tasks should use.

For more information about task definitions, see Amazon ECS task definitions.

  • Task: A task is a running instantiation of your task definition.
  • Service: A service runs a specified number of tasks simultaneously on your cluster. For more information about services, see Amazon ECS services.

Reading 2.3

Scheduling tasks with Amazon ECS

To run a task on Amazon Elastic Container Service (Amazon ECS), you must schedule it. The scheduling engine determines how and when to launch a task. There are multiple ways you can schedule tasks: through service scheduling, manual scheduling, cron scheduling, or by using custom schedulers. For more information about scheduling tasks on Amazon ECS, see Scheduling Amazon ECS tasks.

Placing tasks with Amazon ECS

After you determine when you want to run a task through scheduling, Amazon ECS then needs to determine where to run the task, and how to place that task based on requirements that you define. For more information about task placement on Amazon ECS, see Amazon ECS task placement.

Launch types

For Amazon ECS, the launch type you choose, either EC2 or Fargate, is chosen when you run a service or launch a task.

  • Fargate launch type: Run your containerized applications without the need to provision and manage the backend infrastructure. AWS Fargate is the serverless way to host your Amazon ECS workloads.
  • EC2 launch type: Run your containerized applications on Amazon EC2 instances that you register to your Amazon ECS cluster and manage yourself.

For more information about launch types, see Amazon ECS Launch types.

Capacity providers

Capacity providers manage the infrastructure that the tasks in your clusters use. For more information about capacity providers and how to use them, see this blog post by Adam Keller: Managing compute for Amazon ECS clusters with capacity providers.For more detailed information about capacity providers, see Amazon ECS capacity providers.

Scaling your cluster

Amazon ECS cluster auto scaling provides control over how you scale the Amazon Elastic Compute Cloud (Amazon EC2) instances within a cluster. When you use managed scaling, Amazon ECS creates the infrastructure for the Auto Scaling group capacity provider, and manages the scale-in and scale-out actions of the Auto Scaling group based on your clusters' task load. For more information about cluster auto scaling, see Amazon ECS cluster auto scaling.

Scaling your tasks

To scale your tasks automatically based on demand, you can use service auto scaling. Amazon ECS publishes Amazon CloudWatch metrics with your service’s average CPU and memory usage. You can then use these metrics to scale your service as demand changes. For more information about scaling tasks, see Service auto scaling.

Service Discovery with AWS Cloud Map

Amazon ECS uses AWS Cloud Map for service discovery. For more information about how Amazon ECS integrates with AWS Cloud Map, see Service Discovery.

Reading: 2.4

For more information about Amazon Elastic Container Service (Amazon ECS), consider watching AWS conference talks on YouTube, such as AWS re:Invent 2021 - The powerful simplicity of Amazon ECS.

Amazon ECS best practices

For more information about best practices with Amazon ECS, see Amazon Elastic Container Service Best Practices Guide.

Amazon ECS troubleshooting

To collect diagnostic information and troubleshoot issues quickly, you can Use Amazon ECS exec for debugging. For more information about troubleshooting Amazon ECS deployments, see Amazon ECS troubleshooting.

Reading 2.6

AWS Copilot

AWS Copilot is a command line tool that you can use with Amazon Elastic Container Service (Amazon ECS). Copilot automates the creation of many resources that you need to host your container workloads on Amazon ECS.

To deploy a simple website with AWS Copilot, you need to create three things: an application, an environment, and a service. An application is a logical grouping of resources. An environment is used for different settings and stages of your application (such as testing, staging, and production). Your application can have multiple services, which are where your code lives. Services can be one of several different types. The example application in this course creates two services: a load balanced web service for the frontend, and a backend service for the API.

Each service uses your Dockerfile to define an application container image. Copilot creates Amazon Elastic Container Registry (Amazon ECR) repositories. It then builds and pushes the container images as part of the automated deployment. Copilot creates the Amazon ECS and load balancer resources that are needed to run your service inside Amazon ECS. These resources are different for each service type. For more information, see Services in the AWS Copilot CLI documentation.

Everything created by Copilot is defined in a manifest file. The manifest file contains all the details that are used to deploy your services, such as scaling the number of tasks hosting your application. Source-controlling your manifest file is a good way to follow some DevOps practices. When the state of your deployed applications is committed to source control, where you have a full history of all changes. By using source control, you can capture much of your team’s knowledge about your applications. If you created Amazon ECS application resources manually, you could lose this knowledge and deployments might no longer be repeatable.

For more information about Copilot, see the AWS Copilot CLI documentation.

Week 2 FAQ

Q: When should I use the EC2 launch type, and when should I use the Fargate launch type?

A: For your tasks, whether you choose the EC2 or Fargate launch type depends on your use case. You can have a cluster that uses both launch types, so you can choose which one is a better fit on a service-by-service or task-by-task basis.

You can use the EC2 launch type when you want more control over the infrastructure that your tasks run on. For example, you might have a compliance requirement for your application where you must use only approved AWS Amazon Machine Images (AMIs).

If your workload has a consistent demand for many CPU cores and many gigabytes of memory—and you want to optimize for price—you can consider running a cluster of Amazon Elastic Compute Cloud (Amazon EC2) Reserved Instances or Spot Instances. You would be responsible for maintaining this cluster and optimizing it, but you can then take advantage of savings strategies for EC2 instances (such as Spot Instances or Reserved Instances).

You could use the Fargate launch type if you want to manage less infrastructure. Managing a large cluster of EC2 instances can be complex. For example, you would need to make sure that all instances are patched, secure, and updated to the latest version of Docker and the Amazon Elastic Container Service (Amazon ECS) agent. If you don’t want to handle this kind of overhead, AWS Fargate can be a good choice.

Another reason to use Fargate is if your workload is small, with the occasional burst—such as a website that has traffic during the day, but low traffic at night. In this case, Fargate can also be a good choice. You can scale down to one small container at night (which could lower the cost). However, you can then also scale up during the day, while only paying for the CPU cores and gigabytes of memory that your task requires.

For more examples and more information, see EC2 or AWS Fargate?

Q: What technology powers Fargate?

A: Fargate uses Firecracker microVMs to run containers. For more information about the Fargate data plane, see the following AWS Blog post: Under the hood: AWS Fargate data plane.

Q: Are there any tools to help me run my Amazon ECS tasks locally?

A: There are! To test workloads locally, you can use Docker Compose, the Amazon ECS Local Endpoints tool, and the Amazon ECS command line tool. For more information about using Amazon ECS locally, see the following AWS Blog post: A Guide to Locally Testing Containers with Amazon ECS Local Endpoints and Docker Compose.

Q: Where can I find examples of Amazon ECS task definitions?

A: There are examples in the AWS documentation at Example task definitions.

Q: Can I take advantage of the different Amazon EC2 pricing models for my Amazon ECS cluster?

A: You can. When you use the EC2 launch type, you can use Reserved Instances, Savings Plans, Spot Instances, or On-Demand Instances for your Amazon ECS cluster. For Fargate based services, you can use AWS Fargate Spot pricing, which can also help you optimize for cost.