
서버(EC2 인스턴스 같은)에서 도커 에이전트를 실행하면 도커 컨테이너를 시작할 수 있다.
각 도커 컨테이너에서 Java 애플리케이션, node.js 애플리케이션, MySQL 데이터베이스 등의 실행이 가능하다. 서버 관점에서는 모두 도커 컨테이너로 보인다.
도커를 시작하려면 도커 컨테이너를 구성하는 Dockerfile을 작성해야 한다.
베이스 도커 이미지에 몇 가지 파일을 추가해서 구축하면 도커이미지가 된다.
도커이미지 예시
# 1. 베이스 이미지 선택 (Ubuntu 최신 버전 사용)
FROM ubuntu:latest
# 2. 작업 디렉터리 설정
WORKDIR /app
# 3. 필요한 파일 복사 (현재 디렉터리의 모든 파일을 컨테이너의 /app으로 복사)
COPY . /app
# 4. 필요한 패키지 설치 (패키지 목록 업데이트 후 curl 설치)
RUN apt-get update && apt-get install -y curl
# 5. 환경 변수 설정 (예제: Java 실행 옵션 설정)
ENV JAVA_OPTS="-Xmx512m"
# 6. 컨테이너에서 사용할 포트 지정 (8080 포트 사용)
EXPOSE 8080
# 7. 실행할 명령어 정의 (기본 실행 명령어를 Java 애플리케이션 실행으로 설정)
CMD ["java", "-jar", "app.jar"]
# 8. 추가 설정 (특정 사용자로 실행)
USER nonroot
# 9. 컨테이너의 상태를 체크하는 Health Check 설정 (30초마다 서버 상태 확인)
HEALTHCHECK --interval=30s --timeout=10s --retries=3 CMD curl -f http://localhost:8080 || exit 1
도커 이미지는 푸시(Push)해서 도커 리포지토리에 저장할 수 있다.
여러 리포지토리
1) Docker Hub : 많은 기술에 맞는 기본 이미지를 찾을 수 있다. Ubuntu나 MySQL과 같은 OS용 이미지도 마찬가지다.
2) Amazon ECR(Elastic Container Registry) : 비공개 이미지를 실행할 수 있지만 Public Gallery라 불리는 퍼블릭 리포지토리 옵션도 있다.
도커 리포지토리에서 이미지를 가져와서 실행하게 된다.
도커 이미지를 실행하면 도커 컨테이너가 되고 도커를 구축할 때 사용했던 코드를 실행한다.

대규모 컴퓨팅을 관리할 때 고려해야 할 점
컨테이너를 인스턴스에 어떻게 배치할 것인가?
컨테이너가 실패하면 어떻게 처리할 것인가?
인스턴스가 실패하면 어떤 영향을 받는가?
컨테이너 배포 상태를 어떻게 모니터링할 것인가?
이러한 문제를 해결하는 것이 컨테이너 오케스트레이션 서비스이며, AWS에서는 Amazon ECS와 Amazon EKS 두 가지 서비스를 제공한다.
Amazon ECS는 AWS의 관리형 컨테이너 오케스트레이션 서비스다.
AWS에서 컨테이너를 실행하면 EC2클러스터에 ECS태스크를 실행하는 것이다.

출처- Amazon
EC2 인스턴스의 클러스터에서 컨테이너를 실행하고 관리하며, 이를 위해 각각 EC2 인스턴스에서 ECS 에이전트를 실행해야 한다.
EC2 클러스터를 사용할 때는 인프라를 직접 프로비저닝하고 유지해야 한다.
1️⃣ 컨테이너 이미지 빌드 & Amazon ECR에 저장
2️⃣ ECS(EKS)에서 컨테이너 실행을 위한 리소스 정의
3️⃣ AWS에서 컨테이너 실행 & 자동 확장

여러 ECS 태스크들이 ECS 클러스터 안에서 실행되고 있다.
HTTP, HTTPS 엔드포인트로 태스크를 활용하기 위해 애플리케이션 로드 밸런서를 앞에서 실행하면 모든 사용자가 ALB 및 백엔드의 ECS 태스크에 직접 연결된다.
NLB는 처리량이 매우 많거나 높은 성능이 요구될 때,AWS Private Link와 사용할 때 권장한다.
데이터 볼륨이 필요하며 그 중 EFS가 자주 사용된다.
📍 사용사례) EFS와 ECS를 함께 사용해서 다중 AZ가 공유하는 컨테이너의 영구 스토리지
🚨 주의) S3는 ECS 태스크에 파일 시스템으로 마운트될 수 없다.
InfraStructure에서 Fargate, EC2 중 고를 수 있고 두 개 다 선택이 가능하다.
EC2 instances를 선택했다면 새로운 ASG를 생성해야 한다.
프로비저닝 모델과 AMI 등 인스턴스를 설정해준다.
네트워크도 설정해주고(기본 설정으로 일단 둔다) 클러스터를 생성해준다.
infrastructure를 선택하면 ECS 클러스터 안에 Capacity providers를 확인할 수 있다.
Fargate와 EC2를 모두 선택해 생성한 클러스터라면 3개가 있다.
ECS task를 생성하게 되면 Fargate, Fargate spot capacity provider, ASG의 일부인 컨테이너 인스턴스 중 하나로 보내진다.
EC2 인스턴스의 CPU와 메모리 사용 가능량이 다 찰 때까지 task를 보낼 수 있다.
Task definition family 이름을 설정해야 하는데 이 이름은 Docker Hub에 있는 동명의 Docker image로부터 가져온다.
태스크가 Fargate, EC2 중 어디서 실행되어야 하는 지 고른다.
OS도 선택하고 Fargate 컨테이너의 task 크기를 설정해야 한다.
Task role을 설정해 해당 태스크에 IAM Role을 부여할 수 있따. 이는 AWS 서비스로 API 요청을 하고 싶을 때 설정하면 된다.
컨테이너의 이름, Image URI(Docker Hub에 있는 이미지 이름)을 설정하면 Docker hub에서 이미지를 자동으로 가져온다.
포트 매핑에서 포트와 컨테이터 포트를 매핑할 수 있다.
환경 변수는 파일 혹은 수동으로 설정할 수 있다.
기본으로 두고 생성한다. 그러면 version 1의 task가 생성된다. (task name:1)
Compute option으로 Launch type 선택(Fargate, EC2, EXTERNAL 중 선택)
Platform version은 LATEST로 한다.
애플리케이션 타입은 Service와 Task중 선택.
🔹 Batch Job(배치 작업)이란?
배치 작업(Batch Job)은 일정한 시간 간격으로 또는 특정 조건이 충족될 때 자동으로 실행되는 작업을 말한다. 주로 대량의 데이터 처리, 예약된 작업 실행, 반복적인 업무 자동화에 사용된다.
서비스 이름은 task definition과 똑같은 이름을 작성한다.
서비스 타입은 Replica로, Desired tasks는 1로 한다.
나머지는 그대로 두고 Networking에서 VPC내의 서브넷에 배치하고 create a new security group을 누른다.
보안 그룹에서 HTTP를 허용하고 Public IP는 우선 Turned on 상태로 한다.
ALB를 선택해 생성하고 헬스체크 간격을 설정한다.
Service auto scaling 과 Task Placement는 ECS 서비스에서 실행되는 작업(Task) 개수를 자동으로 조정하고 ECS에서 새로운 Task가 실행될 때 어떤 EC2 인스턴스 또는 Fargate 노드에 배치할지 결정하는 방식을 설정할 수도 있다. (지금은 안건들임)
태스크 ID를 누르면 task 정보와 log 를 볼 수 있다.
서비스에서 태스크가 생성되고 대상 그룹에 등록되고 배포가 완료되고 어떤 상태에 있는 지 등을 확인할 수 있다.
Desired tasks에서 원하는 태스크 수를 입력하고 나머지는 그대로 두고 Update를 누르면 task가 개수만큼 생기게 된다. (Fargate에서 자동 프로비저닝)
그럼 Application Balancer가 ECS에 있는 컨테이너들에게 로드를 분배한다.
task definition은 비용이 들지 않는 그냥 정의기 때문에 삭제하지 않아도 됨.
Capacity Provider, AutoScalingGroup Cluster, LauchTemplate를 삭제하면 된다.
ECS 서비스의 세 가지 지표로 오토스케일링 설정을 할 수 있다.
1) CPU 사용률
2) RAM 사용률
3) 타겟당 요청수(ALB 관련 지표)
EC2 시작 유형이라면 태스크 레벨에서의 ECS 서비스 확장과 EC2 인스턴스 클러스터의 확장은 다르다는 것을 알아야 한다.
📍 EC2 인스턴스 오토 스케일링 두 가지 방법
1. ASG를 사용해 특정 지표에 따라 EC2 인스턴스를 자동 확장
2. ECS 클러스터 용량 공급자(Capacity Provider) 사용 (권장)
용량 공급자는 ASG와 함께 사용되며 새 태스크를 실행할 용량(RAM, CPU)이 부족하면 자동으로 ASG를 확장한다.
📍 사용자가 급증할 때 태스크와 EC2 인스턴스의 자동확장 과정
1. ECS 서비스 레벨에서 CPU사용량을 모니터링하여 ECS 서비스의 희망 용량이 증가하면 새 태스크가 생성된다.(태스크 확장 = 컨테이너 확장)
2. 생성된 태스크들이 실행되는 EC2 인스턴스들에서 새 태스크를 실행시킬 용량이 부족하다면 ECS 용량 공급자가 ECS 인스턴스를 추가해 ECS 클러스터 확장
ECS를 사용할 때의 몇가지 솔루션 아키텍처에 대해 살펴본다.
Fargate가 지원하는 ECS 클러스터가 있고 S3버킷이 있다.
사용자들은 객체들을 S3 버킷에 업로드하면 S3 버킷은 EventBridge와 통합되어 모든 이벤트를 전송할 수 있다.
EventBridge는 항상 ECS 태스크를 실행하기 위한 규칙을 갖고 있다.
ECS 태스크가 생성되면 태스크 Role을 부여받을 것이다. 그것을 통해 태스크에서 S3로부터 객체를 가져오고 처리된 결과를 DynamoDB로 전송할 수 있다.
Fargate와 EventBridge가 지원하는 Amazon ECS 클러스터가 있다.
1시간마다 트리거되는 규칙을 스케줄링 한다. 이 규칙은 Fargate에서 ECS태스크를 실행한다.
즉 1시간마다 Fargate클러스터 안에서 새로운 태스크가 생성된다. 그리고 태스크는 원하는 작업을 수행한다. 이 모든 아키텍처는 서버리스다.
2개의 ECS 태스크가 있는 서비스가 있다.
메시지는 SQS Queue로 전송된다.
서비스 자체가 SQS Queue로부터 메시지를 가져와서 그것들을 처리한다.
ECS 서비스 오토 스케일링을 활성화 하면 SQS Queue에 더 많은 메시지가 있을 때 오토스케일링으로 ECS 서비스에 태스크 수를 늘릴 수 있다.
ECS 클러스터에서 나가거나 시작되는 모든 태스크는 EventBridge에서 이벤트로서 트리거될 수 있다.
이벤트 규칙 추가 예시
aws events put-rule \
--name ecs-task-state-change-rule \
--event-pattern '{
"source": ["aws.ecs"],
"detail-type": ["ECS Task State Change"],
"detail": {
"clusterArn": ["arn:aws:ecs:us-east-1:123456789012:cluster/my-cluster"],
"desiredStatus": ["STOPPED"]
}
}' \
--role-arn arn:aws:iam::123456789012:role/EventBridgeInvokeLambda
이렇게 태스크의 상태가 바뀔 때의 이벤트의 규칙을 정할 수 있다.
이벤트가 발생하면 SNS 토픽으로 관리자에게 이메일을 발송할 수 있다.

노드를 원치 않는 경우 선택. 유지 관리가 필요없고 노드 관리도 필요없다.
EKS에서 컨테이너만 실행하면 된다.
EKS 클러스터에 스토리지 클래스 메니페스트를 지정해야 한다.
컨테이너 스토리지 인터페이스(CSI)라는 규격 드라이버를 활용한다.
🚨 프리티어 아니라서 과금된다.
이름 입력하고 쿠버네티스 버전은 기본값 선택
먼저 IAM 콘솔로 가서 EKS용 역할(서비스 선택시 EKS-cluster 선택하면 된다)을 생성하고 이름은 eksClusterRole로 한다.
KMS 암호화를 사용해서 암호화할 수 있지만 지금은 안한다.
관리형 노드 그룹을 추가하거나 Fargate 프로필을 생성해야 한다.
EKS > 클러스터 선택 > Resources 탭에서 모든 Kubernetes 리소스가 관리된다.
Compute 탭에서는 노드 그룹을 추가할 수 있다.
Add node group을 누르고 노드그룹의 IAM Role을 새로 생성해준다.
해당 Role은 EC2인스턴스 용이며 관리형 노드 그룹의 일부가 된다.
정책은 AmazonEKSWorkerNodePolicy, AmazonEC2ContainerRegistryReadOnly 를 선택해 적용한다.
역할의 이름은 AmazonEKSNodeRole로 설정한다.
노드 그룹에 몇 개의 노드를 둘지 오토스케일링그룹 설정도 할 수 있다.
노드 그룹 업데이트 구성에서는 업데이트 시 중단 상태를 용인할 노드 수를 설정한다.
다른 노드를 생성하려면 Compute 탭에서 Fargate를 생성하면 된다. Fargate 프로필만 추가하면 된다.
Add-ons 탭에서 EBS 볼륨을 쓰고자 할 경우 Add new를 선택해 EBS CSI Driver를 추가해준다.
쿠버네티스는 관련 전문 지식이 필요해 별도의 강의 시청이 필요하다~~!
두 가지 옵션이 있다.
1. 계정에 한해 이미지를 비공개로 저장
2. 퍼블릭 저장소를 사용해 ECR Public Gallery에 게시
ECR 저장소에 있는 도커이미지를 ECS 클러스터의 EC2 인스턴스에 이미지를 끌어오기 위해서는 EC2 인스턴스에 IAM Role을 지정하여 ECR로의 접근을 허용하면 된다.
🚨 Seoul 리전에선 서비스 되지 않는다.
📍 사용 사례
🚨 프리티어 아니라서 vCPU와 사용하는 GB당 비용을 지불해야 한다.
배포소스를 정해야 한다. 컨테이너 레지스트리의 일부인지 소스코드의 일부인지, GitHub에 연결할지 등을 설정할 수 있다.
컨테이너 레지스트리를 선택했다면 Provider는 인프라 내부 프라이빗 Docker 컨테이너라면 Amazon ECR을, 퍼블릭 이미지를 배포하려면 Amazon ECR Public을 선택한다.
Amazon ECR Public Gallery로 가서 httpd를 검색해 아주 간단한 http 서버를 배포할 수 있다.(아무 기능 없음)
https://gallery.ecr.aws/docker/library/httpd 여기서 Copy로 주소를 복사해 컨테이너 이미지 URI에 붙여 넣는다.
애플리케이션을 수동 혹은 자동으로 배포할지 정할 수 있다. 소스 코드 저장소나 Amazon ECR을 선택했다면 자동 배포가 가능하다.
원하는 vCPU의 수와 메모리 용량을 설정한다.
서비스 포트를 설정해야하는데 우리가 사용하는 Docker 이미지의 문서를 보면 해당 이미지의 포트가 80번이기 때문에 포트를 80으로 입력한다.
기본 구성에서 인스턴스의 최소 크기는 1, 최대 크기는 25다. 동시성은 해당 설정으로 인스턴스당 100개의 요청을 동시에 받을 수 있다는 뜻이다.
사용자 지정 오토 스케일링 구성을 추가할 수도 있다.
애플리케이션이 정상인지 확인 가능하다.
컨테이너에 인스턴스 Role을 정한다.
나머지는 다 기본구성으로 두고 만든다.
백그라운드에서 App Runner가 오토 스케일링 그룹과 스케일링 트리거를 배포할 것이다.
Fargate 컨테이너도 배포할 것이고 로드 밸런서까지 배포하면 이 도메인을 사용할 수 있게 된다.
만들어진 서비스를 클릭하고 Defalut domain의 주소를 클릭하면 기본 도메인으로 액세스할 수 있다.