오늘의 인기 글
최근 글
최근 댓글
Today
Total
12-23 00:05
관리 메뉴

우노

[AWS ECS] ECS(Elastic Container Service) 란? 본문

AWS/ECS

[AWS ECS] ECS(Elastic Container Service) 란?

운호(Noah) 2020. 10. 13. 12:44

ECS란?

  • Docker는 최근 각광 받고 있는 컨테이너 기술이다.
  • 하지만 Docker를 이용해 서비스를 구축 하려면 여러가지 고려 해야할 사항이 많다.
  • 따라서 필연적으로 컨테이너를 적절하게 배치하고 관리할 수 있게 도와주는 컨테이너 오케스트레이션 도구의 필요성을 느끼게 된다.
  • AWS의 ECS는 Amazon에서 제공하는 '완전관리형 컨테이너 오케스트레이션 툴'로써,
  • Docker 컨테이너를 이용하여 인프라 환경을 좀 더 편리하게 운영,관리 할 수 있게 해주는 서비스이다.
  • 비슷한 툴로서는 Kubernetes나 Docker Swarm이 있다.

ECS 구성 요소

  • ECS는 크게 아래와 같은 컴포넌트들로 구성 되어 있다.

    • Task definition
    • Task
    • Service
    • Container Instance
    • Cluster
  • 먼저 이것들에 대해 하나하나 알아보자

    • Task / Service 관계

  • 1) Task definition

    • 원하는 Docker 컨테이너를 생성할 때, 어떤 설정으로 몇 개 이상 생성 할 지를 정의한 Set 이다.
      • 컨테이너의 이미지, CPU/메모리 리소스 할당 설정, port 매핑, volume 설정 같은 것들이 포함되며, 기존 docker run 명령에서 가능했던 대부분 옵션이 설정 가능하다.
      • 컨테이너 오케스트레이션에서는 컨테이너가 필요에 따라서 자동적으로 실행되거나 종료될 수 있다.
      • 따라서 매번 이러한 설정들을 지정하기보다는, 미리 설정들의 집합을 하나의 단위로 정의해놓고 사용한다.
      • 이 단위가 바로 태스크 디피니션이다.
      • 한 번 태스크 디피니션을 만들면 이 태스크 디피니션을 기반으로 특정 설정을 변경할 수 있다.
    • Task definition 에는 한 개 이상의 컨테이너에 대해 정의가 가능하며, Task definition 내부에 정의된 컨테이너 사이는 link 설정으로 연결이 가능하다.
    • Task definition 에서 정의된 대로 실제 생성된 container set 들을 Task 라고 부르게 된다.
  • 2) Task

    • Task definition 에서 정의된 대로 배포된 Container Set을 Task라고 부른다.
      • 즉, Task 안에는 한 개 이상의 컨테이너들이 포함되어 있으며 ECS에서 컨테이너를 실행하는 최소 단위는 Task이다.
    • Task는 Cluster에 속한 Container instance(EC2 Instance)에 배포되게 된다.
    • 또한, Task는 여러 Container instance(EC2 Instace)에 배포 가능하다.
  • 3) Service

    • Task 들의 Life cycle 을 관리하는 부분을 Service 라고 한다.
    • 각 Task 들은 각자 다른 서비스이다.
    • Task 를 Cluster에 몇 개나 배포할 것인지 결정하고, 실제 Task 들을 외부에 서비스 하기 위해 ELB 에 연동 되는 부분을 관리하게 된다.
    • 만약 실행 중인 Task 가 어떤 이유로 작동이 중지 되면 이것을 자동으로 감지해 새로운 Task를 Cluster에 배포 하는 고가용성에 대한 정책도 Service 에서 관리한다.
    • 즉, 오토스케일링과 로드밸런싱을 관리하는 역할이다.
  • 4) Container Instance (EC2 instance)

    • ECS 는 Container 배포(Task 배포)를 EC2 instance 기반에 올리도록 설계 되어 있다.
    • Task를 올리기 위해 등록된 EC2 instanceContainer Instance 라고 부른다.
    • ECS를 처음 시작하면 생성되는 Default Cluster 에는 Container instance를 자동으로 할당 시켜 주기도 하지만
    • 새롭게 Cluster 를 생성하게 되면 직접 Container instance 를 만들어야 한다.
    • Container instance 용 AMI 이미지는 AWS 측에서 제공해 주기 때문에 어렵지 않게 생성이 가능하다.
    • 하나의 Container Instace 내부에는 각각의 다른 Task가 여러 개 있을 수 있다.
  • 5) Cluster

    • Task 가 배포되는 Container Instance 들은 논리적인 그룹으로 묶이게 되는데 이 단위를 Cluster 라고 부른다.
    • Task 를 배포하기 위한 instance 는 반드시 Cluster 에 등록되어야 한다
  • Cluster, Container Instance와 Task, Service의 관계를 도식화 시켜 보면 아래와 같다.

ECS의 구조적 특징 및 주의사항

  • 1) ECS의 Docker host 역할은 EC2 Instance가 담당한다.

    • 컨테이너는 보통 물리 서버에 Docker daemon 을 설치하고, 그 위에 컨테이너를 하나씩 배포하게 되는데, Hypervisor 기반에서 동작되는 VM 보다 훨씬 더 많은 서비스를 올릴 수 있는게 큰 장점 중 하나이다.
    • 하지만, AWS는 ECS를 위한 container 전용 서버팜을 따로 구성하지 않고, VM 형태의 EC2 instance 에서 container 를 동작시키는 방법을 택했다.
    • 이유는 무엇일까?
    • AWS의 전체 서비스 설계를 보면 EC2 instance를 중심으로 다양한 서비스들이 연계되는 모양새를 갖추고 있다. 이는 AWS의 가장 큰 장점이기도 하다.
      • Network 서비스인 VPC와 ELB, EIP 에서 부터 Auto scaling, Cloud Formation 등 수십가지의 서비스가 조직적으로 엮여 있으며 이 중심에는 사용자들이 가장 많이 사용하는 EC2 instance 가 있다.
      • 만약, AWS가 ECS 서비스를 위해 새로운 Container 서버팜 환경을 구성하고 설계했다면, 기존 EC2 를 중심으로 한 다양한 서비스들과의 연계에 대하여 굉장히 많은 고민을 할 수 밖에 없을 것이다.
      • 차라리 컨테이너를 EC2 instance에 올림으로서, EC2 중심으로 엮여 있는 기존의 서비스를 이용하는 장점을 흡수하는게 훨씬 이득이 많았을 거라 생각한다.
  • 2) Overlay network가 아닌 ELB를 이용한 Network 구조

    • Docker 를 사용하려는 사람들이 늘어나면서 컨테이너를 대규모로 운영하려는 시도가 점점 많아지고, 자연스럽게 다수의 Docker host 를 clustering 형태로 통합 관리하려는 필요성이 커지게 되었다.

      • host 에 container 를 어떻게 배포할 것인지에 대한 스케줄링 관련 문제, 다른 host에 배포된 container 사이의 통신 문제, 동일 Port 를 사용 하는 컨테이너들을 동시 수용할때의 host 포트 맵핑 이슈 등이 대표적인 문제들이다.
    • 최근 주목 받고 있는 컨테이너 orchestration 시스템인 Kubernetes나 Docker swarm의 경우 위와 같은 이슈를 해결하기 위해 overlay network 구조를 추가해 이런 문제를 해결하고 있다.

      • host간 네트워크를 논리적으로 묶어서 연결해 주는 overlay network 는 컨테이너 orchestration 을 위한 중요 구성 요소로 고려되고 있는 추세이다.
    • 그렇다면 ECS 의 host clustering 을 위한 network 구조는 어떠할까.

    • ECS의 Cluster 는 매우 단순하다.

    • Cluster는 docker host 의 논리적 묶음일 뿐이지, 이를 위해 추가적인 network 설계 구조가 들어가지 않은 것으로 보인다.

      • Overlay network 가 없다면, 다른 host에 상주한 컨테이너 사이에는 컨테이너에 할당된 Private IP 를 이용해 native 하게 통신하게 어려우며, 대신 외부 통신과 동일하게 각 host IP로 컨테이너에 맵핑된 port 를 이용하는 방법 밖엔 없다.
      • 이는 컨테이너간 통신을 빈번히 요구 하는 application 을 올리는 경우에 상당히 어려움을 겪을 수 있다.
      • host 사이를 논리적으로 묶어줄 network 구조가 없다면, 결국 컨테이너 사이 통신을 위해서는 각 컨테이너가 상주한 host의 정보를 추가로 알아야만 통신이 가능하기 때문이다.
    • 하지만, ECS 는 이러한 문제를 기존 서비스 중 하나로 어느정도 해소하였다. 바로 ELB 이다

    • ECS는 service 내부에 여러개의 task 가 배포될때 ELB 의 밸런싱 그룹에 task 들이 자동으로 들어가도록 설계되어 있다.

    • 즉, service 사이의 통신은 ELB를 통해 통신을 함으로서 task의 life cycle 을 유연하게 관리할 수 있게 만든 구조이다.

    • 물론, 같은 service 에 속한 task 들이 다른 host에 있게 된다면 이들 사이의 통신은 여전히 어렵다는 한계는 있지만, 굳이 동일한 service 안에 동일한 task 끼리 통신할 일은 많지 않을 것이기에 큰 문제는 없을 것으로 보인다.

      • ( 보통 web 서버가 was 나 DB 와 통신하지, 굳이 동일한 일을 하는 web 서버 끼리는 통신을 주고 받을 일이 없다)
  • 3) 하나의 Host에는 한 개의 Task만 수용 가능하다.

    • 사실 ECS에서 가장 안타까운 점이라고 생각한다.

    • 컨테이너가 host의 특정 port 를 점유 해야만 하는 구조는, 결국 같은 port로 서비스 하려는 컨테이너가 한 host한 개 밖에 올라갈 수 없다는 의미이다.

    • ECS 구조적 측면에서 보면, service 안에 task 를 올릴수 있는 최대 숫자는 cluster에 등록된 container instance 개수 이상이 될 수 없다는 것이다.

      • 예를 들어, service 안에 apache 컨테이너가 정의된 task 를 2개 올리고 싶다면, 반드시 host 는 두대 이상이 필요하다는 말이다.
    • 이는 컨테이너 집적도가 그만큼 낮아질 수 밖에 없는 구조적 한계이다.

    • Kubernetes 의 경우 Overlay network 과 Pods / Service 라는 논리적 개념으로 이러한 문제를 해결한 것과 비교하면 아쉬운 부분임이 분명하다.

    • 대신 host 마다 다른 task 들이 공존하도록 만들어 집적도를 올리는 방법이 그나마 단점을 상쇄하는 방법으로 보인다.

    • 아래와 같이 Container instance 는 두대이지만, 각각 다른 포트를 사용하는 service를 여러 개 올려 컨테이너 집적도를 높일 수 있다.

  • 4) ECS 특성에 맞는 Application 설계가 필요하다.

    • ECS 기반으로 Application을 잘 운영하려면, Task 와 Service 개념의 구조적 특징을 이해하고 Application을 설계 해야 한다.

    • 아래는 ECS 설계적 관점에 따른 몇가지 유의 사항이다.

    • 4-1) Task definition 에는 단일 Tier 속성의 컨테이너만 정의하는게 유리하다.

      • 사실 Task 에는 여러 컨테이너를 정의할 수 있다.
      • 하지만, 최소 배포 단위가 Task 단위 이므로 단일한 속성의 컨테이너 하나만 정의하는 게 좋은 설계 방향일 것이다.
        • 예를 들어, Task definition 에 Web / WAS / DB 컨테이너를 한꺼번에 정의했다고 가정해 보자.
        • 만약 task 가 하나인 상황에서는 큰 문제가 없을것이다. 하지만 task 를 추가로 늘리려고 한다면, task에 속한 Web / WAS / DB 셋이 한꺼번에 늘어나게 된다.
        • 보통 서비스에 부하가 일어나면, 각 tier 별로 어떤 구간에서 스트레스를 받는지 판단 후 해당 tier 의 서버만 추가하여 LB에 넣는 방식으로 해결한다. ( = Scale-out )
        • 하지만, task에 모든 tier 를 혼합시켜 구성하면 scale-out 형태의 증설은 불가능할 것이다.
        • 따라서, task 의 Scale-out 구조를 고려하여 task 를 tier 단위로 분리해서 정의하는게 좋다.
    • 4-2) 용도에 맞게 Container Instance 를 VPC로 구분해 사용하면 보안성을 높일 수 있다.

      • 컨테이너를 올릴 host 는 EC2 를 사용함으로 EC2 에 적용되는 다양한 서비스들을 그대로 이용할 수 있다.
      • 따라서 VPC 와 같은 기능을 이용하여, 컨테이너가 올라가게 될 EC2 를 구분해 사용한다면 더욱 보안성을 높일 수 있다.
        • 예를 들어, Cluster A 는 외부로 노출할 Web 컨테이너들을 배포하고, Cluster B 에는 외부 노출을 하지 않는 WAS 컨테이너를 배포한다고 가정해 보자.
        • 이때, Cluster A 에 속하는 EC2 instance 들은 VPC의 public subnet 에 속하도록 하고, Cluster B 에 속하는 EC2 instance 들은 VPC 의 private subnet 에 속하도록 구성할 수 있다.
        • 단, private subnet 에 배포된 EC2 instance 들은 외부 통신과 단절되게 되므로, ECS 를 사용하려면 NAT Gateway 와 같은 서비스를 이용해 outbound 트래픽에 대한 처리를 추가해 주어야 한다.
    • 4-3) 컨테이너 특성상 DB 와 같은 stateful 한 서버는 컨테이너 보다는 EC2 나 RDS 를 이용해 연계해서 사용한다.

      • 컨테이너는 기존의 인프라 방식에 비해 생성과 소멸에 좀 더 유연하다.
      • 바꿔 말하면 컨테이너는 언제든 삭제 될 수 있음을 전제로 해야 한다.
      • 그러므로 data store 가 목적인 DB 는 컨테이너의 컨셉과는 상반된 형태임을 고려해야한다.
      • 따라서, 컨테이너의 특성상 stateless 한 성격의 web 이나 was 서버에 이용하기를 권장한다.
      • DB 의 경우 AWS의 RDS 와같은 서비스를 이용해 컨테이너와 함께 쓴다면 안전하면서도 유연한 인프라 구성을 갖출 수 있을 것으로 생각된다.
    • 4-4) ECR 과 같은 컨테이너 서비스들과 연계하여 사용하면 좋다.

      • AWS 에는 ECS 말고도 컨테이너 이미지 Repository 서비스인 ECR 도 서비스 하고 있다.
      • 이를 ECS 와 엮어서 사용한다면 더욱 좋을 것으로 생각 된다.

마치며

  • 개인적인 견해로는 ECS 는 EC2 instance 위에 Docker 컨테이너를 올려 운영하기 쉽도록 도와 주는 일종의 managed 서비스에 가까운 느낌이다.
  • 하지만 굳이 복잡한 구성의 여타 컨테이너 orchestration 시스템을 도입하는 것 보다는 차라리 ECS 를 이용하면 손쉽게 컨테이너를 이용해 서비스를 올리는 것도 좋은 방법이라고 생각된다.
  • 특히 최근에 자주 언급되는 MSA ( Micro Service Architecture ) 형태의 구성에는 아주 적합한 서비스라고 생각된다.
Comments