GitLab pipeline 에서 make build, make push 까지 했었다. (make test 의 경우에는 그냥 스테이지만 넣었고 실질적인 test를 넣은 건 아니었다.)
ECR까지 docker image가 등록이 된 상태다. 지속적인 통합 과정, CI 과정은 끝이 난 것.
이제 make deploy,
그러니까 AWS Cloud로의 배포까지 추가해서 사용자들이 사용할 수 있도록 하면 된다.
CI 까지 만들었으니까 CD 를 만든다는 것.
1. GitLab을 이용해서 프로젝트를 만들고
2. Docker Image를 빌드해서 ECR에 Push 했고
3. 이제 인터넷 사용자가 서비스를 사용할 수 있도록 Docker Image를 배포해야 한다.
4. AWS ECS 를 이용해서 우리가 개발한 어플리케이션을 AWS Cloud에 배포하게 된다.
5. 이를 통해서 개발, 통합, 빌드, 배포의 기본적인 CI/CD 파이프라인 전체를 구성해보게 된다.
AWS ECS와 CI/CD 파이프라인
AWS ECS(Amazon Elastic Container Service)는 컨테이너 오케스트레이션 도구로, Docker 컨테이너를 사용한 애플리케이션을 배포, 관리, 확장하는 데 사용됩니다. 특히 AWS CLI, Docker, 그리고 GitLab과 함께 사용하면 자동화된 CI/CD 파이프라인을 구축할 수 있습니다.
AWS ECS의 주요 기능
- 컨테이너 오케스트레이션
- Docker 컨테이너를 실행, 관리하며 여러 컨테이너를 클러스터 환경에서 조율합니다.
- ECS 작업(Task) 및 서비스(Service)를 통해 컨테이너의 실행 방식을 정의합니다.
- 유연한 실행 환경
- AWS Fargate: 서버리스 방식으로 컨테이너 실행.
- Amazon EC2: 사용자가 관리하는 가상 서버 환경에서 실행.
- 확장성
- ECS는 필요에 따라 자동으로 클러스터의 작업 수를 확장하거나 축소합니다.
- 통합 지원
- Docker: 컨테이너 이미지 생성 및 배포.
- AWS CLI: ECS 클러스터 및 작업 정의를 관리.
- GitLab: CI/CD 파이프라인의 소스 제어 및 자동화 트리거.
AWS ECS 기반 CI/CD 파이프라인의 구조
아래는 GitLab, Docker, AWS ECS, AWS CLI를 사용해 CI/CD 파이프라인을 구성하는 구조입니다:
1. CI/CD 파이프라인 흐름
- 코드 작성 및 Push
개발자는 애플리케이션 코드를 작성하고 GitLab의 리포지토리에 Push합니다. - GitLab CI/CD 트리거
GitLab CI/CD 파이프라인이 트리거되며, 다음 작업이 진행됩니다:- Docker 이미지를 빌드.
- AWS Elastic Container Registry(ECR)에 이미지 푸시.
- AWS ECS에 배포
GitLab의 파이프라인 스크립트를 통해 AWS CLI를 호출하여 ECS 서비스에 새 Docker 이미지를 배포합니다.
2. 파이프라인 구성의 주요 단계
- Docker 이미지 빌드 및 푸시
- Dockerfile을 기반으로 애플리케이션의 이미지를 빌드합니다.
- 이미지를 AWS ECR(Amazon Elastic Container Registry)에 푸시합니다.
- ECS 작업(Task) 및 서비스 배포
- AWS CLI 명령어를 사용해 ECS 클러스터와 서비스가 새 이미지를 기반으로 업데이트되도록 트리거합니다.
- ECS 서비스는 배포 중에 롤링 업데이트를 수행해 다운타임 없이 새 버전을 배포합니다.
- 자동 확장 및 모니터링
- Amazon CloudWatch를 사용하여 애플리케이션 상태를 모니터링.
- 필요한 경우 Auto Scaling을 통해 ECS 작업을 확장.
작업 구조의 세부 설명
- ECS 클러스터
Docker 컨테이너를 실행하는 리소스의 논리적 그룹입니다. 클러스터는 Fargate(서버리스) 또는 EC2(가상 머신 기반) 환경에서 실행됩니다. - 작업 정의(Task Definition)
실행할 컨테이너의 구성 정보입니다. 예를 들어, 사용해야 할 Docker 이미지, CPU/메모리 할당량, 네트워크 설정 등이 포함됩니다. - 서비스(Service)
ECS 서비스는 특정 수의 작업(Task)을 유지하며 로드 밸런싱 및 자동 복구를 지원합니다.
결론
AWS ECS는 Docker 기반 컨테이너를 자동으로 오케스트레이션하는 강력한 도구이며, GitLab과 AWS CLI를 활용하면 효율적이고 자동화된 CI/CD 파이프라인을 구축할 수 있습니다. 이 구조는 애플리케이션의 안정적인 배포와 빠른 반복 개발을 가능하게 합니다.
* Amazon ECS
- Kubernetes 같은 Container Orrchestration 서비스
- Kubernetes 에 비해서 저렴하고 사용하기가 쉽다
- serverless 로 구성하면 인스턴스를 구성/관리할 필요가 없다
- AWS의 다른 서비스와 쉽게 연동
- 운영, 모니터링, 스케일링의 완전 자동화
Amazon ECS의 작동 원리와 구조
**Amazon ECS(Amazon Elastic Container Service)**는 컨테이너화된 애플리케이션을 클러스터 기반으로 배포, 관리, 확장하는 서비스입니다. 이를 효과적으로 설명하기 위해 아래 키워드들을 사용해 구조를 풀어보겠습니다:
구성 요소와 역할
- Amazon ECR (Elastic Container Registry)
- ECR은 Docker 이미지를 저장하고 관리하는 서비스입니다.
- 예를 들어, Service-A Image, Service-B Image, Service-C Image, Service-D Image 같은 Docker 이미지를 저장합니다.
- 각 이미지는 컨테이너화된 애플리케이션이나 서비스의 실행 가능한 스냅샷입니다.
개발자는 애플리케이션 코드를 컨테이너화하여 Amazon ECR에 이미지를 푸시(push)합니다. - 클러스터(Cluster)
- 클러스터는 컨테이너가 실행되는 리소스의 논리적 그룹입니다.
- ECS 클러스터는 Service-A, Service-B 같은 서비스를 실행하며, 이들은 각각의 Docker 이미지를 기반으로 실행됩니다.
- 클러스터 내에 여러 EC2 인스턴스나 Fargate 작업(Task)이 존재하여 다양한 서비스를 실행합니다.
- 서비스(Service)
- ECS 서비스는 특정 컨테이너 작업(Task)을 실행하고 관리합니다.
- 예를 들어, Service-A는 Service-A Image를 사용해 클러스터 내 컨테이너를 실행합니다.
- 서비스는 지정된 수의 컨테이너를 유지하며, 작업이 실패하면 자동 복구를 수행합니다.
- 자동 확장(Auto Scaling)
- ECS는 Auto Scaling 기능을 통해 서비스나 클러스터의 작업(Task) 수를 자동으로 확장하거나 축소합니다.
- 예를 들어, Service-A가 트래픽 증가로 인해 부하를 받으면 추가 작업(Task)을 시작하여 서비스 용량을 확장합니다.
- ELB (Elastic Load Balancer)
- ELB는 클러스터 내에서 실행 중인 컨테이너 간의 부하를 분산합니다.
- 예를 들어, Service-B에서 3개의 작업(Task)이 실행 중이라면, ELB는 들어오는 요청을 각 작업으로 고르게 분산시켜 애플리케이션의 가용성을 높입니다.
- CloudWatch
- Amazon CloudWatch는 ECS 클러스터와 서비스의 성능 및 상태를 모니터링합니다.
- 예시:
- Service-C의 CPU 사용량이 80%를 초과하면 경고를 생성.
- 이를 기반으로 Auto Scaling을 트리거하거나 문제를 디버깅할 수 있습니다.
ECS 작업 흐름 예시
- 이미지 준비
- 개발자가 Docker 이미지를 생성하고 이를 Amazon ECR에 업로드합니다.
- 예:
- Service-A Image → 웹 서버
- Service-B Image → 데이터 처리 워커
- Service-C Image → 데이터베이스 관리
- Service-D Image → 백엔드 API
- 서비스와 클러스터 설정
- ECS 클러스터를 생성하고 각 이미지를 기반으로 서비스를 설정합니다.
- 예:
- Service-A는 3개의 작업(Task)을 실행.
- Service-B는 2개의 작업(Task)을 실행.
- 트래픽 처리
- ELB가 들어오는 요청을 받아 클러스터 내의 Service-A 작업(Task)로 분산합니다.
- 요청이 증가하면 CloudWatch가 이를 감지하고, Auto Scaling을 통해 작업(Task)을 추가 생성합니다.
- 모니터링 및 유지 관리
- CloudWatch에서 CPU 사용량, 메모리 소비량 등의 지표를 모니터링합니다.
- 비정상 상태의 작업(Task)은 ECS가 자동으로 재시작합니다.
ECS 구조 다이어그램 (설명)
- ECR
- Docker 이미지를 저장 (Service-A Image, Service-B Image 등).
- 클러스터
- 여러 서비스를 실행하는 컨테이너 작업(Task)의 집합.
- 예:
- Service-A는 클러스터 내에서 3개의 작업 실행.
- Service-B는 2개의 작업 실행.
- ELB
- 클라이언트의 요청을 클러스터 내 컨테이너로 라우팅.
- Auto Scaling
- 클러스터 또는 서비스의 작업(Task) 수를 자동으로 조정.
- CloudWatch
- 서비스 상태 및 성능을 실시간으로 모니터링.
결론
Amazon ECS는 ECR에서 저장된 Docker 이미지를 클러스터 내에서 서비스로 실행하며, ELB와 Auto Scaling을 통해 애플리케이션의 확장성과 안정성을 보장합니다. CloudWatch는 이를 실시간으로 모니터링하며, 문제 발생 시 빠른 복구 및 확장을 지원합니다.
아래는 Amazon ECS의 구조를 텍스트 기반으로 시각화한 예입니다. 키워드와 구성 요소의 관계를 계층적으로 보여줍니다.
Amazon ECS 구조
1. Amazon ECR
├── Service-A Image
├── Service-B Image
├── Service-C Image
└── Service-D Image
2. ECS Cluster
├── Service-A
│ ├── Task 1 (Docker Container: Service-A Image)
│ ├── Task 2 (Docker Container: Service-A Image)
│ └── Task 3 (Docker Container: Service-A Image)
├── Service-B
│ ├── Task 1 (Docker Container: Service-B Image)
│ └── Task 2 (Docker Container: Service-B Image)
├── Service-C
│ └── Task 1 (Docker Container: Service-C Image)
└── Service-D
├── Task 1 (Docker Container: Service-D Image)
└── Task 2 (Docker Container: Service-D Image)
3. Elastic Load Balancer (ELB)
├── Routes traffic to Service-A Tasks
└── Routes traffic to Service-D Tasks
4. Auto Scaling
├── Monitors Cluster or Service Metrics via CloudWatch
├── Scales up Service-A to 5 Tasks during high traffic
└── Scales down Service-D to 1 Task during low traffic
5. CloudWatch
├── Logs metrics for CPU, Memory, and Task Health
├── Sends alerts when thresholds are breached
└── Triggers Auto Scaling events
구조 설명
- Amazon ECR
- 모든 Docker 이미지는 ECR에 저장되며, ECS 서비스가 이를 가져다 사용합니다.
- ECS Cluster
- 클러스터는 여러 서비스로 구성되고, 각 서비스는 작업(Task)을 실행합니다.
- 예를 들어, Service-A는 3개의 작업(Task)을 실행하며, 각 작업은 동일한 Docker 이미지를 사용합니다.
- Elastic Load Balancer (ELB)
- 클라이언트의 요청을 클러스터 내 적절한 작업(Task)으로 라우팅합니다.
- 예: Service-A의 3개 작업(Task)로 요청을 분산.
- Auto Scaling
- 트래픽 증가 시 작업(Task) 수를 확장하고, 감소 시 축소합니다.
- 예: CloudWatch의 CPU 사용량 경고에 따라 Service-A 작업(Task)을 3개에서 5개로 증가.
- CloudWatch
- ECS의 성능과 상태를 모니터링하며, 경고 및 확장을 트리거합니다.
실제 동작 예시
- 클라이언트가 애플리케이션에 접속.
- ELB가 요청을 받아 Service-A의 작업(Task)으로 전달.
- 트래픽 증가로 인해 CloudWatch가 CPU 사용량 상승을 감지.
- Auto Scaling이 트리거되어 Service-A의 작업(Task)을 추가.
- 트래픽 감소 시 Auto Scaling이 작업(Task)을 축소.
Amazon ECS에서의 Task와 Task Definition
Task와 Task Definition은 Amazon ECS의 핵심 개념으로, 컨테이너화된 애플리케이션을 실행하고 관리하는 데 중요한 역할을 합니다.
1. Task란?
Task는 Amazon ECS에서 실행되는 컨테이너의 단위입니다.
- Task는 Task Definition을 기반으로 실행됩니다.
- 하나의 Task는 하나 이상의 컨테이너를 포함할 수 있습니다.
예를 들어, 웹 서버 컨테이너와 로깅 컨테이너를 하나의 Task로 정의할 수 있습니다. - Task는 ECS 클러스터 내에서 실행되며, Fargate(서버리스) 또는 EC2 인스턴스를 기반으로 작동할 수 있습니다.
예시
- "Task-A"는 Service-A에 의해 실행되는 단일 컨테이너 또는 여러 컨테이너를 포함하는 단위입니다.
- "웹 애플리케이션" 작업을 담당하는 Task가 3개 실행 중이면, 동일한 컨테이너가 3개 복제되어 클러스터에서 작동 중임을 의미합니다.
2. Task Definition이란?
Task Definition은 ECS에서 Task를 정의하는 설정 파일입니다.
- JSON 형식으로 작성되며, Task를 실행하기 위해 필요한 정보를 포함합니다.
- Task Definition은 Amazon ECS가 Task를 생성하고 실행하는 방법을 알려주는 설명서 역할을 합니다.
3. Task Definition이 담고 있는 내용
Task Definition에는 다음과 같은 정보가 포함됩니다:
1) 컨테이너 정의(Container Definitions)
- 컨테이너 이미지: 사용할 Docker 이미지의 위치(ECR, Docker Hub 등).
- 메모리 및 CPU: 컨테이너에 할당할 자원 크기.
- 네트워크 포트: 컨테이너가 수신 대기할 포트 정보.
- 환경 변수: 컨테이너에 전달할 환경 변수.
- 로깅: 컨테이너의 로그를 저장할 경로 및 설정.
예:
"containerDefinitions": [
{
"name": "web-app",
"image": "123456789012.dkr.ecr.us-east-1.amazonaws.com/my-web-app:latest",
"cpu": 256,
"memory": 512,
"portMappings": [
{
"containerPort": 80,
"hostPort": 80
}
],
"environment": [
{ "name": "ENV_VAR", "value": "production" }
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/my-web-app",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "ecs"
}
}
}
]
2) 네트워크 설정
- VPC(Network Mode): bridge, awsvpc 같은 네트워크 모드.
- Subnets 및 Security Groups: 컨테이너가 실행될 네트워크 위치.
3) Task의 실행 권한
- AWS 리소스에 접근할 수 있는 IAM 역할 정의.
예:
"taskRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole"
4) Task-level 옵션
- Task 전체의 메모리 및 CPU 제한.
- 실행 타입: EC2 또는 Fargate.
- 작업 개수: 몇 개의 복제본을 실행할 것인지 설정.
예:
"cpu": "1024",
"memory": "2048",
"requiresCompatibilities": ["FARGATE"]
4. Task와 Task Definition의 관계
- Task Definition 작성
개발자는 Task Definition에 컨테이너 이미지와 관련 설정을 정의합니다. - Task 실행
ECS는 Task Definition을 읽어 Task를 생성하고 실행합니다.
각 Task는 정의된 대로 컨테이너를 실행하며, ECS 클러스터 내에서 배포됩니다. - Task의 동작
실행된 Task는 ELB를 통해 요청을 처리하거나, Auto Scaling 설정에 따라 수가 조정됩니다.
Task와 Task Definition의 시각적 표현
Task Definition
└── Container Definitions
├── Container A (웹 서버 컨테이너)
│ ├── 이미지: my-web-app:latest
│ ├── 포트: 80
│ └── CPU: 256 / 메모리: 512 MB
└── Container B (로깅 컨테이너)
├── 이미지: logging-app:latest
├── 포트: 5000
└── CPU: 128 / 메모리: 256 MB
Task (Task Definition 기반 실행)
└── 실행 중인 컨테이너:
├── 웹 서버 컨테이너 (A)
└── 로깅 컨테이너 (B)
Cluster
└── 실행 중인 Task들:
├── Task 1
├── Task 2
└── Task 3
요약
- Task는 ECS 클러스터 내에서 실행되는 실제 작업 단위(컨테이너)입니다.
- Task Definition은 Task 실행에 필요한 설정(컨테이너 정의, 네트워크, 리소스 등)을 담은 설명서입니다.
- Task는 Task Definition을 기반으로 생성되며, ECS는 이를 자동으로 관리하고 확장할 수 있습니다.