:bulb: AWS에서 애플리케이션과 컨테이너를 실행하는 대표 서비스인 Elastic Beanstalk, ECS, EKS를 비교한다. ① 무엇이 다른지, ② PaaS·IaaS·CaaS 중 어디에 속하는지, ③ 사용자가 Pod를 실제로 어떻게 배포하는지까지 순서대로 다룬다.


[01] 한눈에 보는 비교

구분 Elastic Beanstalk ECS (Elastic Container Service) EKS (Elastic Kubernetes Service)
핵심 정체 애플리케이션 배포 플랫폼 AWS 자체 컨테이너 오케스트레이터 관리형 Kubernetes
표준/엔진 AWS 독자 규격, 내부적으로 EC2/ECS 활용 AWS 독자 규격, task/service 개념 표준 Kubernetes, Pod/Deployment
추상화 수준 가장 높음 (코드만 올리면 됨) 중간 가장 낮음 (가장 많은 제어권)
사용자 책임 코드/설정 태스크 정의, EC2 실행 방식이면 노드까지 매니페스트, 자체 노드면 워커 노드까지
이식성 낮음, AWS 종속 낮음, AWS 종속 높음, 어디서나 동일한 K8s API
러닝 커브 낮음 중간 높음
대표 사용처 단순/전통 웹앱, 빠른 배포 AWS 안에서만 실행하는 컨테이너 워크로드 멀티클라우드·복잡한 MSA·생태계(헬름 등) 필요

:bulb: 한 문장 요약. 빨리 올리고 싶으면 Beanstalk, AWS 안에서 컨테이너만 실행하면 ECS, 표준 쿠버네티스 생태계가 필요하면 EKS다.


[02] 각 서비스 깊게 보기

2-1. Elastic Beanstalk: 코드 업로드만으로 배포

코드나 Docker 이미지를 업로드하면 EC2 인스턴스, 로드 밸런서, 오토 스케일링 그룹, health check까지 AWS가 자동으로 프로비저닝한다. 사용자는 인프라를 거의 신경 쓰지 않는다.

  • 지원 런타임: Java, .NET, Node.js, Python, PHP, Go, Ruby, Docker
  • 인프라가 숨겨져 있지만 접근이 막혀 있지는 않다. 필요하면 생성된 EC2와 보안 그룹을 직접 수정할 수 있다.
  • 컨테이너 오케스트레이션 도구가 아니다. 애플리케이션 배포를 자동화하는 플랫폼이다.

:warning: 멀티 컨테이너를 정교하게 다루거나, 세밀한 스케줄링·서비스 메시·헬름 같은 생태계가 필요하면 Beanstalk은 금방 한계에 부딪힌다. 그럴 땐 ECS/EKS로 넘어가야 한다.

2-2. ECS: AWS 자체 컨테이너 오케스트레이터

쿠버네티스가 아닌 AWS 자체 오케스트레이터다. Task Definition(컨테이너 스펙)과 Service(원하는 개수 유지) 개념으로 동작한다. 실행 방식이 두 가지다.

실행 방식(Launch Type) 설명 성격
EC2 사용자가 EC2 노드를 직접 관리하고 그 위에 컨테이너 배치 IaaS에 가까움
Fargate 서버리스. 노드 관리 없이 컨테이너만 실행 PaaS(서버리스)에 가까움
  • 장점: AWS 서비스(IAM, ALB, CloudWatch 등)와 기본 연동, 쿠버네티스를 몰라도 사용 가능, 컨트롤 플레인 비용 없음.
  • 단점: AWS 종속이라 다른 클라우드로 이식 불가, 쿠버네티스 생태계인 헬름과 오퍼레이터를 사용할 수 없음.

2-3. EKS: 관리형 쿠버네티스

표준 쿠버네티스를 AWS가 운영한다. 컨트롤 플레인(API 서버, etcd 등)은 AWS가 관리하고, 사용자는 워커 노드와 워크로드 Pod에 집중한다.

노드 운영 방식 설명
관리형 노드 그룹 AWS가 EC2 워커 노드 라이프사이클 관리
자체 관리형 노드 워커 노드를 직접 운영 (최대 제어권)
Fargate 노드 없이 Pod를 서버리스로 실행
  • 장점: 표준 K8s API를 그대로 쓰므로 온프레미스나 다른 클라우드에서도 동일하게 운영 가능. 생태계(Helm, Operator, Istio, ArgoCD 등)를 사용할 수 있음.
  • 단점: 러닝 커브 높음, 컨트롤 플레인 시간당 비용 발생, 운영 복잡도 큼.

[03] PaaS·IaaS·CaaS 분류

셋 다 IaaS와 PaaS 사이의 CaaS(Container as a Service) 범위에 있다. 구분 기준은 사용자가 어디까지 책임지는지, 곧 추상화 수준이다.

1
2
3
4
관리 책임 많음(IaaS) ←─────────────────────────────→ 적음(PaaS/서버리스)

  EC2          ECS(EC2) / EKS(자체노드)      ECS(Fargate) / EKS(Fargate)      Beanstalk        Lambda
 [IaaS]            [CaaS, IaaS 쪽]              [CaaS, 서버리스/PaaS 쪽]        [PaaS에 근접]    [FaaS]
서비스 분류 한 줄 설명
Elastic Beanstalk PaaS에 가장 근접 코드를 주면 플랫폼이 실행 환경 전체를 책임짐
ECS / EKS, EC2·자체 노드 CaaS, IaaS 쪽 노드를 직접 관리 → 인프라 책임이 남아 IaaS 성격
ECS / EKS, Fargate CaaS, PaaS/서버리스 쪽 노드 관리가 사라져 PaaS에 근접

:bulb: ECS와 EKS는 실행 방식에 따라 IaaS와 PaaS 사이를 오간다. Fargate를 쓰면 노드를 직접 다루지 않으므로 PaaS와 서버리스에 가까워지고, EC2나 자체 노드를 쓰면 인프라 책임이 늘어 IaaS에 가까워진다. “EKS는 PaaS다” 또는 “IaaS다”라고 단정할 수 없는 이유다.


[04] EKS에서 Pod를 배포하는 절차

쿠버네티스에서 배포의 최소 실행 단위는 Pod다. 다만 Pod를 직접 만들지 않고 원하는 상태를 선언하는 Deployment로 관리한다. 전체 흐름은 다음 7단계다.

1
2
3
4
5
6
7
8
9
10
[1] 코드          [2] 이미지 빌드        [3] 레지스트리(ECR) push
  app.py    ──▶   docker build    ──▶   <acct>.dkr.ecr...amazonaws.com/app:v1
                                              │
                                              ▼
[4] 매니페스트 작성     [5] kubectl apply        [6] 스케줄러가 노드에 Pod 배치
 deployment.yaml  ──▶   API 서버에 제출   ──▶   Node A: [Pod] [Pod]
                                              Node B: [Pod]
                                                  │
                                                  ▼
[7] Service/Ingress 로 외부 노출 + HPA 오토스케일 + 롤링 업데이트

4-1. 이미지 빌드 → 레지스트리 push

1
2
3
4
5
6
7
8
# 1) 컨테이너 이미지 빌드
docker build -t my-app:v1 .

# 2) ECR 로그인 + 태그 + push
aws ecr get-login-password --region ap-northeast-2 \
  | docker login --username AWS --password-stdin <acct>.dkr.ecr.ap-northeast-2.amazonaws.com
docker tag my-app:v1 <acct>.dkr.ecr.ap-northeast-2.amazonaws.com/my-app:v1
docker push <acct>.dkr.ecr.ap-northeast-2.amazonaws.com/my-app:v1

4-2. Deployment 매니페스트 작성

Pod를 직접 만들지 않고 Deployment로 Pod를 몇 개, 어떤 이미지로 유지할지 선언한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# deployment.yaml — 원하는 상태(desired state)를 선언
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3                 # Pod를 항상 3개 유지
  selector:
    matchLabels:
      app: my-app
  template:                   # ↓ 이 부분이 Pod 템플릿
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app
          image: <acct>.dkr.ecr.ap-northeast-2.amazonaws.com/my-app:v1
          ports:
            - containerPort: 8080

4-3. 클러스터에 적용 → 스케줄링

1
2
3
4
5
# 클러스터 접속 설정 (EKS)
aws eks update-kubeconfig --name my-cluster --region ap-northeast-2

# 매니페스트 적용 — API 서버에 "원하는 상태" 제출
kubectl apply -f deployment.yaml

이후 흐름은 쿠버네티스가 처리한다.

  1. API 서버가 요청을 받아 etcd에 “Pod 3개 필요” 상태를 저장한다.
  2. 컨트롤러가 현재 0개에서 3개가 되도록 Pod 생성을 요청한다.
  3. 스케줄러가 리소스 여유가 있는 노드에 각 Pod를 배치한다.
  4. 각 노드의 kubelet이 컨테이너 런타임으로 이미지를 받아 컨테이너를 실행한다.
1
2
3
# 배포 상태 확인
kubectl get pods -o wide      # Pod가 어느 노드에서 Running인지
kubectl get deployment my-app # 3/3 READY 확인

4-4. 외부 노출 (Service / Ingress)

Pod는 IP가 수시로 바뀌므로 안정적인 진입점으로 Service나 Ingress를 둔다.

1
2
3
4
5
6
7
8
9
10
11
12
# service.yaml — Pod 묶음에 고정 진입점 + 로드밸런서 부여
apiVersion: v1
kind: Service
metadata:
  name: my-app
spec:
  type: LoadBalancer          # AWS LB 자동 생성 (EKS)
  selector:
    app: my-app               # label이 app=my-app인 Pod로 트래픽 분배
  ports:
    - port: 80
      targetPort: 8080
1
2
kubectl apply -f service.yaml
kubectl get svc my-app        # EXTERNAL-IP(LB 주소) 확인

4-5. 스케일링 & 무중단 업데이트

1
2
3
4
5
6
7
8
9
10
# 수동 스케일: Pod 3개 → 5개
kubectl scale deployment my-app --replicas=5

# 자동 스케일(HPA): CPU 50% 기준 2~10개로 자동 조절
kubectl autoscale deployment my-app --cpu-percent=50 --min=2 --max=10

# 새 버전 롤링 업데이트(무중단): 이미지만 교체하면 점진 교체
kubectl set image deployment/my-app my-app=<acct>.dkr.ecr.ap-northeast-2.amazonaws.com/my-app:v2
kubectl rollout status deployment/my-app   # 진행 상황 추적
kubectl rollout undo deployment/my-app     # 문제 시 롤백

:bulb: 핵심은 선언형 동작이다. 사용자는 “이렇게 만들어라”가 아니라 “이런 상태이길 원한다”를 선언하고(replicas: 3, image: v2), 쿠버네티스가 현재 상태를 그 목표로 수렴시킨다. ECS도 task/service로 개념이 유사하고, Beanstalk은 이 과정을 한 번 더 감싸 eb deploy 하나로 끝낸다.


[05] 선택 기준

상황 추천
쿠버네티스/컨테이너를 잘 모르고, 전통 웹앱을 빨리 올리고 싶다 Elastic Beanstalk
AWS 안에서만 컨테이너를 실행하고, K8s 운영 부담은 피하고 싶다 ECS. 노드 관리까지 피하려면 Fargate
멀티클라우드·이식성·헬름/오퍼레이터 등 표준 K8s 생태계가 필요하다 EKS
노드를 직접 다루고 싶지 않다 Fargate, ECS와 EKS 공통

:warning: “남들이 EKS 쓰니까 우리도”는 흔한 착오다. 쿠버네티스는 운영 복잡도와 컨트롤 플레인 비용을 동반한다. 단일 AWS 환경에서 컨테이너 몇 개만 실행한다면 ECS Fargate가 더 싸고 단순한 경우가 많다.


[06] 핵심 요약

# 요약
1 Beanstalk=애플리케이션 배포 플랫폼, ECS=AWS 자체 오케스트레이터, EKS=관리형 표준 쿠버네티스
2 셋 다 엄밀히는 IaaS와 PaaS 사이의 CaaS이고, Beanstalk이 PaaS에 가장 근접하다
3 ECS·EKS는 실행 방식에 따라 위치가 이동한다. Fargate면 PaaS/서버리스 쪽, EC2·자체 노드면 IaaS 쪽
4 EKS는 표준 K8s API 덕분에 이식성이 높고, ECS와 Beanstalk은 AWS 종속이 강하다
5 Pod 배포 7단계: 빌드 → ECR push → 매니페스트 → kubectl apply → 스케줄러 배치 → Service 노출 → 스케일/롤링업데이트
6 쿠버네티스는 선언형으로 동작한다. “원하는 상태”를 선언하면 시스템이 그 상태로 수렴시킨다

:bulb: 세 서비스의 차이는 결국 추상화 수준이다. 인프라를 덜 볼수록 Beanstalk과 Fargate 쪽이고, 제어권이 더 필요할수록 EKS 쪽이다.