Terraform을 활용한 ECS와 ECR 개념정리
Process
Terraform Packer가 AMI를 빌드하는 것과 비슷하게 도커를 사용해서 도커 이미지를 빌드할 수 있습니다.
해당 이미지는 도커 엔진이 설치된 모든 리눅스 호스트에서 실행 가능합니다.
ECR
- ECR 생성하기
provider "aws" {
region = var.AWS_REGION
}
resource "aws_ecr_repository" "myapp" {
name = "myapp"
}
output "myapp-repository-URL" {
value = aws_ecr_repository.myapp.repository_url
}
- Docker build
docker build -t {AWS account ID}.dkr.ecr.{Region Code}.amazonaws.com/{REPOSITORY}:{TAG} .
ECR에 엑세스하기 위해선 Docker 로그인이 필요합니다.
ECR 리포지토리에 있는 Docker 이미지에 대한 보안 액세스 및 관리가 Docker CLI의 인증 메커니즘을 사용하여 보장되기 때문입니다.
따라서 aws ecr get-login-password 을 통해 임시 토큰(credential)을 사용하여 임시 자격증명을 생성하고 토큰이 Docker CLI에서 AWS 계정에 대해 인증하는 데 사용되어 Docker 클라이언트가 특정 ECR 리포지토리에 액세스할 수 있는 권한이 있는지 확인합니다.
aws ecr get-login-password \\
--region {Region Code} \\
| docker login
--username AWS \\
--password-stdin {AWS account ID}.dkr.ecr.{Region Code}.amazonaws.com
docker push {AWS account ID}.dkr.ecr.{Region Code}.amazonaws.com/{REPOSITORY}:{TAG}
ECS
ECR로 업로드된 이미지가 있다면 ECS로 시작할 수 있습니다.
아마존에서 유지 관리되는 AMI에는 ECS 에이전트가 포함되어 있습니다. ECS가 온라인되면 클러스터에서 작업과 서비스를 시작할 수 있습니다.
클러스터는 단순히 ECS 에이전트가 있는 EC2 인스턴스 그룹으로 이해할 수 있고 이를 ECS를 통해 관리하는 것입니다.
ECS 태스크 정의
도커 앱을 시작하기 전에 태스크 정의가 필요하며 클러스터에서 실행할 도커 컨테이너를 정의해야합니다.
- 도커 이미지 지정(ECR)
- 최대 CPU 사용량, 최대 메모리 사용량
- 인스턴스 당 몇개의 컨테이너를 가지는지, 컨테이너를 연결해야하는지 여부
- DB 컨테이너와 APP 컨테이너 연결 가능
- 환경 변수
태스크는 태스크 정의의 설정 값으로 만들어지며 태스크는 실행된 Cluster 하위 인스턴스 or Fargate 컨테이너로 관리됩니다.
하나의 컨테이너가 어떻게 실행되어야하는지를 지정할 수 있습니다.
# app.json.tpl
[
{
"essential": true,
"memory": 256,
"name": "myapp",
"cpu": 256,
"image": "${REPOSITORY_URL}:1",
"workingDirectory": "/app",
"command": ["npm", "start"],
"portMappings": [
{
"containerPort": 3000,
"hostPort": 3000
}
]
}
]
resource "aws_ecs_task_definition" "myapp-task-definition" {
family = "myapp"
container_definitions = templatefile("templates/app.json.tpl", {
REPOSITORY_URL = replace(aws_ecr_repository.myapp.repository_url, "https://", "")
})
}
ECS 서비스 정의
서비스 정의는 태스크 정의를 기반으로 만들어진 특정 양의 컨테이너를 실행시키는 방식을 정의합니다. 이 외에도 실행된 컨테이너가 어떻게 연결되는지를 정의할 수 있습니다.
- 항상 실행되며 컨테이너가 중지되어도 다시 시작됩니다.
- 서비스는 확장 가능하며 인스턴스를 한 개부터 여러 개까지 실행 가능합니다.
- 로드밸런서를 통해 고가용성을 확보할 수 있습니다.
설정값
- 시작 유형(Fargate / EC2)
- 태스크 정의
- 클러스터
- 배포 유형( Rolling / Blue-Green)
- 네트워크 구성
- Load Balancing 설정
- Auto Scaling 설정
컨테이너들이 어떤 환경에서 실행되어야하는지를 지정할 수 있습니다.
resource "aws_launch_configuration" "ecs-example-launchconfig" {
name_prefix = "ecs-launchconfig"
image_id = var.ECS_AMIS[var.AWS_REGION]
instance_type = var.ECS_INSTANCE_TYPE
key_name = aws_key_pair.mykeypair.key_name
iam_instance_profile = aws_iam_instance_profile.ecs-ec2-role.id
security_groups = [aws_security_group.ecs-securitygroup.id]
user_data = "#!/bin/bash\\necho 'ECS_CLUSTER=example-cluster' > /etc/ecs/ecs.config\\nstart ecs"
lifecycle {
create_before_destroy = true
}
}
resource "aws_autoscaling_group" "ecs-example-autoscaling" {
name = "ecs-test-autoscaling"
vpc_zone_identifier = [aws_subnet.main-public-1.id, aws_subnet.main-public-2.id]
launch_configuration = aws_launch_configuration.ecs-example-launchconfig.name
min_size = 1
max_size = 1
tag {
key = "Name"
value = "ecs-ec2-container"
propagate_at_launch = true
}
}
ssh -i mykey {public_ip} -l ec2-user
Service
클러스터에
회고
ECS 클러스터는 만들어지고 정상적으로 실행은 되는데 접근이 안됐다.
이것도 마찬가지로 직접 옵션을 살펴보고 콘솔로 만들고나니 어떤 옵션이 필요한지 이해하게 되었고 각 태스크, 서비스가 무슨 옵션을 설정하는 것인지 이해가 되었다.
이후에 다시 정리해보는게 좋을거같다