728x90
반응형
1. Amazon ECS 란?
- ECS(Elastic Container Service)는 컨테이너화된 애플리케이션을 쉽게 배포, 관리, 스케일링할 수 있도록 도와주는 완전 관리형 컨테이너 오케스트레이션 서비스
- API호출을 사용해서 컨테이너 기반의 애플리케이션을 시작 중지 가능
- ECS의 인프라는 Fargate(서버리스), EC2, 외부(External) 인스턴스로 호스팅에 대한 레이어를 선택하여 생성 가능
2. ECS의 구성 요소
2-1) Cluster
- 작업 또는 서비스의 논리적 그룹으로 Fargate, EC2, External 선택하여 사용
2-2) Task Definition
- 애플리케이션을 구성하기위한 텍스트(JSON)를 정의하는 것
- 시작유형(Fargate, EC2, External)
- 컨테이너 이미지
- CPU/메모리 리소스 할당
- 데이터 볼륨
- 포트
- Task Definition을 통해 Task를 실행하는 방법과 Service를 생성하는 방법 2가지가 존재
- Task Definition으로 직접 실행된 Task의 경우 처음 실행되고나면 이후 관리되지 않음
2-3) Task
- Task Definition에서 정의된 설정으로 Cluster의 EC2나 Fargate에 배포하는 것
- Fargate의 경우 예약작업이 가능하며 Batch서버와 같이 (매출데이터 집계, 사용자로그 수집 후 유저군 업데이트, 상품데이터 수집 후 검색 서버에 색인 등) 여러개의 작업 실행 후 종료가 가능하기에 Batch인스턴스를 따로 띄울 필요X
2-4) Service
- 클러스터에서 지정된 수의 작업을 동시에 실행하고 관리 가능한 구성으로 Service에는 Task가 포함되어 있으며, Auto Scaling과 Load Balancing 또한 관리 가능
3. ECS Fargate 배포 (w. Terraform)
3-0) 사전 준비 작업
1. ECR Repository Image Push
# ECR Repository Image Push
# ECR에 Image Push를 위한 login
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin {AWS AccountID}.dkr.ecr.ap-northeast-2.amazonaws.com
# dockerfile 생성
cat > ./dockerfile << EOF
FROM nginx:1.21.1
COPY ./index.html /usr/share/nginx/html/index.html
EXPOSE 80
EOF
cat > ./index.html << EOF
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nginx Page</title>
</head>
<body>
<h1>Hello, this is my Nginx page!</h1>
<p>first</p>
</body>
</html>
EOF
# docker file을 통한 Image 생성
docker build -t nginx:local-build .
# ECR로 Image Push
docker tag nginx:local-build {AWS AccountID}.dkr.ecr.ap-northeast-2.amazonaws.com/{RepoName}:0.1
docker push {AWS AccountID}.dkr.ecr.ap-northeast-2.amazonaws.com/{RepoName}:0.1
2. task가 ECR에서 이미지를 다운받을 있는 권한 생성
# task excution role
data "aws_iam_policy_document" "task_excution_role_policy" {
statement {
sid = ""
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["ecs-tasks.amazonaws.com"]
}
}
}
resource "aws_iam_role" "task_excution_role" {
name = "${local.company}-${local.env}-TaskExcutionRole"
assume_role_policy = data.aws_iam_policy_document.task_excution_role_policy.json
tags = { Name = "${local.company}-${local.env}-TaskExcutionRole" }
}
resource "aws_iam_role_policy_attachment" "taskexcutionrole_policy_attach" {
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
role = aws_iam_role.task_excution_role.name
}
# task role
data "aws_iam_policy_document" "task_role_policy" {
statement {
sid = ""
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["ecs-tasks.amazonaws.com"]
}
}
}
resource "aws_iam_role" "task_role" {
name = "${local.company}-${local.env}-Task-Role"
assume_role_policy = data.aws_iam_policy_document.task_role_policy.json
tags = { Name = "${local.company}-${local.env}-Task-Role" }
}
resource "aws_iam_role_policy_attachment" "task_policy_attach" {
policy_arn = "arn:aws:iam::aws:policy/AmazonS3FullAccess"
role = aws_iam_role.task_role.name
}
3. (옵션) LB생성
- Service생성시 public IP를 붙여 서비스 접근 가능하지만 해당 문서에서는 LB를 따로 생성하여 Service 구축
- (해당 과정 설명 생략)
3-1) ECS Cluster 생성
resource "aws_ecs_cluster" "ecs_cluster" {
name = "${local.company}-${local.env}-ecs-clstr-apne2"
setting {
name = "containerInsights"
value = "enabled"
}
}
- setting - CloudWatch Container Insights를 활성화
> 생성 확인
3-2) Task Definition 생성
resource "aws_ecs_task_definition" "web" {
family = "${local.company}-${local.env}-webtest"
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
cpu = 512
memory = 1024
execution_role_arn = aws_iam_role.task_excution_role.arn
task_role_arn = aws_iam_role.task_role.arn
skip_destroy = true
runtime_platform {
operating_system_family = "LINUX"
cpu_architecture = "X86_64"
}
container_definitions = <<TASK_DEFINITION
[
{
"name": "web",
"image": "128079576215.dkr.ecr.ap-northeast-2.amazonaws.com/{ECR Repo Name}:0.2",
"cpu": 0,
"portMappings": [
{
"name": "web-80-tcp",
"containerPort": 80,
"hostPort": 80,
"protocol": "tcp",
"appProtocol": "http"
}
],
"essential": true,
"environment": [],
"environmentFiles": [],
"mountPoints": [],
"volumesFrom": [],
"ulimits": [],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-create-group": "true",
"awslogs-group": "/ecs/${local.company}-${local.env}-web",
"awslogs-region": "ap-northeast-2",
"awslogs-stream-prefix": "ecs"
}
}
}
]
TASK_DEFINITION
tags = {
Name = "${local.company}-${local.env}-web"
}
}
> 생성 확인
3-3) Service 생성
resource "aws_ecs_service" "web" {
name = "${local.company}-${local.env}-svc-web"
cluster = aws_ecs_cluster.ecs_cluster.id
task_definition = aws_ecs_task_definition.web.arn
desired_count = 2
launch_type = "FARGATE"
network_configuration {
security_groups = [aws_security_group.web_sg.id]
subnets = aws_subnet.pri_subnet[*].id
assign_public_ip = "false"
}
load_balancer {
target_group_arn = aws_lb_target_group.web_target_group.arn
container_name = "web"
container_port = "80"
}
tags = {
Name = "${local.company}-${local.env}-svc-web"
}
}
> 생성 확인 및 LB를 통한 서비스 확인
4) Terraform을 통한 revision관리
테스트 시 문제점1)
- 문제점: 이전 Revision 삭제
- Terraform을 통해 Task Definition를 관리하게 되면 latest revision만 남고 이전 revision들이 지워지게됨.
- AWS에서 ECS Task Definition의 이전 revision들만 지워지는 것처럼 보이지만 실제론 Task Definition이 지워졌다 다시 생김. (Task Definition이 지워지고 다시 생성되는데 revision 이름은 예전 revision 정보가 있는지 1부터 시작되지 않음.. 의문..)
- 해결 방법: skip destroy 옵션을 통해 이전 revision삭제 방지
테스트 시 문제점2)
- 문제점 : Task Definition을 통해 Service 생성 시 lastest revision만 가져와 Service 동작
- Task Definition의 skip_destroy 옵션을 통해 삭제 방지로 이전 revision들이 삭제가 되지 않았지만 state 파일에는 최신 revision의 정보만 남아있기에 Service 생성 시 최신 revision으로 서비스 동작
- 해결 방법: Service 생성시 특정 버전 명시를 통해 Service 실행
728x90
반응형
'Terraform' 카테고리의 다른 글
[Terraform] Variables, Outputs, Data, functions (0) | 2024.05.12 |
---|---|
[Terraform] Resource Block 구문 문법(lifecycle, depends_on) (0) | 2024.05.12 |
[테라폼] EKS 배포 및 Add on 설치 (0) | 2023.10.20 |
[테라폼] Workflow & gitlab runner 프로비저닝 파이프라인 (0) | 2023.08.20 |
[테라폼] State & Module (1) | 2023.07.29 |