TIL/개념정리

Terraform을 활용한 ECS와 ECR 개념정리

초집중 2024. 1. 13. 16:49

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 클러스터는 만들어지고 정상적으로 실행은 되는데 접근이 안됐다.

이것도 마찬가지로 직접 옵션을 살펴보고 콘솔로 만들고나니 어떤 옵션이 필요한지 이해하게 되었고 각 태스크, 서비스가 무슨 옵션을 설정하는 것인지 이해가 되었다.

 

이후에 다시 정리해보는게 좋을거같다