티스토리 뷰

컨테이너와 컨테이너 인스턴스라는 용어로 본문에 많이 등장합니다. 컨테이너 인스턴스는 클러스터에 묶여있는 EC2 인스턴스를 나타냅니다. 표준 표현을 따르다 보니 본문을 읽는데 어려움이 있을 수 있습니다.


 

이번 글에서는 Task, Container에 CPU와 Memory 설정에 대해 알아봅니다. ECS를 처음 접하면 리소스를 설정하는 곳이 너무 많아서 정신이 혼미해질 정도인데요, 추려보면 다음과 같습니다.

  • 인스턴스의 CPU, Memory 설정 (인스턴스 타입에 따라 고정, 혹은 custom 사용)
  • task의 CPU, Memory 설정
  • container의 CPU, Memory 설정

위에서 아래로 갈수록 작은 개념으로 이어집니다. 직감적으로 보면 container는 task 안에서 돌기 때문에 당연히 task에 할당된 리소스가 커야 하고, task는 인스턴스 위에서 돌기 때문에 인스턴스의 리소스가 더 크게 설정되어야 합니다. 사실 당연히 그렇겠죠?

우리가 ECS 위에서 서비스해야 하는 애플리케이션의 리소스 사용량이 가늠이 된다면, 혹은 고정이라면 Fargate는 훌륭한 선택이 될 수 있습니다. 비용은 EC2 대비해서 압도적으로 비싸지만요. ECS에서 task 타입을 EC2로 선택하는 이유는 단지 비용만의 문제는 아닙니다. 서비스해야 하는 애플리케이션의 리소스를 가늠하기 어려운 경우, EC2는 최고의 선택입니다.

본격적으로 container의 CPU, Memory에 대한 이야기를 해봅시다. Task Definition 등록/수정하는 곳에 보면 아래와 같이 설정하는 화면이 나옵니다. 1, 2, 3번 중에 3번 Hard/Soft memory limits를 먼저 알아보죠.

 

Container의 Soft memory limits은 컨테이너가 확보(예약)할 메모리입니다. 확보된 메모리는 다른 컨테이너가 사용하지 못합니다. 즉, 컨테이너 인스턴스의 메모리 영역에서 컨테이너가 할당한 soft limits이 빠진다고 생각하면 됩니다. 예를 들어 컨테이너 인스턴스가 8GiB 메모리로 설정되어 있고, 컨테이너가 soft memory limits를 512MiB로 설정했다면 컨테이너 인스턴스의 남은 메모리는 7680MiB(8192-512)가 됩니다. 다른 task, 다른 container를 띄울 때 확보할 수 있는 공간 자체가 줄어드는 거죠.

한편, Hard memory limits은 컨테이너 인스턴스 내에 확장 가능한 메모리 영역을 나타냅니다. 당장 확보는 하지 않지만 필요시 어디까지 확장하는지 제약을 거는 설정입니다. 위와 같이 1024MiB로 설정된 경우 컨테이너 메모리 사용량이 512를 넘어 계속 증가하다가 1024까지 늘 수 있겠죠. hard memory limits까지 메모리가 다 찼다면 컨테이너는 종료됩니다. OOM(out of memory)으로 생각하면 되겠네요.

컨테이너 인스턴스 내에서 여러 개의 컨테이너가 운영되는 경우, 그리고 메모리 사용량이 기본적으로 soft memory limits을 초과하는 경우는 문제가 생길 수 있습니다. 가령 위와 같은 메모리 설정의 컨테이너가 10개가 동작하고 있을 때 soft limits에 의해 확보된 메모리는 5120MiB(512x10)입니다. 여기에 모든 컨테이너가 메모리를 900MiB까지 사용하면 9000MiB(900x10)인데 컨테이너 인스턴스의 최대 메모리(8GiB)를 초과하기 때문에 불특정 컨테이너가 OOM을 만나게 될 겁니다. 이렇듯 메모리를 설정할 때 task가 스케일 될 것까지 고려해줘야 합니다.

이런 것까지 신경 쓰고 싶지 않다? 그러면 Hard limits 설정을 안 하면 됩니다. 마치 필수 입력처럼 이야기했지만 hard limits을 설정하지 않게 되면 컨테이너 메모리는 계속 늘어납니다. 컨테이너 인스턴스의 메모리(위의 경우 8GiB)까지 말이죠. soft limit도 필수 입력이 아닙니다. 이때는 컨테이너가 실제 사용하는 메모리만큼 컨테이너 인스턴스의 메모리가 사용량으로 잡힙니다. 

CPU의 경우도 메모리와 같습니다. CPU units(1vCPU = 1024 unit)을 지정한다는 건 컨테이너 인스턴스의 cpu units을 미리 확보하겠다는 의미입니다. 컨테이너의 CPU 사용량이 지정된 units보다 많은 경우 메모리에서 hard limits을 설정하지 않은 것처럼 컨테이너 인스턴스의 메모리를 사용하게 됩니다. 그럼 의문이 들죠. cpu units설정은 왜 한 걸까요? 답은 확장에 있습니다. 위의 화면을 보면 CPU Units이 256으로 설정되어 있는데 사용량이 256을 넘어서는 경우 설정된 단위에 비례해서 확장됩니다. 256 → 512 → 768 … 이런 식으로 요.  컨테이너 인스턴스에 똑같은 컨테이너만 운영된다면 어떤 값으로 설정하든 크게 상관없을지 모릅니다. 하지만 containerA(512MiB), containerB(1024MiB)가 같이 운영 중이고 둘 다 사용량을 초과하는 경우를 생각하면, containerB가 containerA의 2배 많은 CPU를 분할받게 됩니다.

자, 여기까지가 3번에 대한 설명입니다. 이제 위의 이미지에서 1, 2번, 그러니까 task의 CPU, Memory 설정을 알아봅시다. task의 cpu, memory를 설정하게 되면 컨테이너는 메모리 확장이 필요한 경우 컨테이너 인스턴스와 비교되지 않고 먼저 task의 cpu 메모리와 비교됩니다. 

즉, 컨테이너가 hard limits 없이 soft limits만 1024MiB로 되어 있어도 컨테이너 인스턴스의 메모리 8196MiB까지 확장되는 게 아니라 task에 설정된 메모리까지만 확장됩니다. task에 메모리를 4096MiB로 설정해뒀다면 딱 거기까지 확장이 되겠죠. 만약 task의 CPU와 메모리가 설정되어 있지 않다면 앞서 이야기한 것처럼 컨테이너 인스턴스의 cpu, 메모리가 바로 비교하게 됩니다.

 

# 마무리

정리하면, 사실 정답은 없습니다. 사례만 있을 뿐이죠. 클러스터 안에 CPU, Memory는 애플리케이션의 종류와 역할에 따라서, 그리고 조직의 변화에 따라 지속적으로 관리되어야 합니다. 높은 스펙의 인스턴스를 풀로 돌려도 되는 여건이라면 상관없겠지만 대부분의 조직은 그렇지 않아요. 그렇기 때문에 늘 최적화가 되어야 하는 겁니다. 설정을 이해하는데 도움이 되었기를 바라며 최적화에 성공하시기를 바랍니다.

댓글
댓글쓰기 폼