실무에서 ECS를 쓰다가 좀더 깊은 레벨까지 알고 싶은 마음에 공식 문서를 정독하고 이때까지 잘 몰랐던 내용을 정리해보았습니다.
사용할 컨테이너(들)에 관한 정의로 JSON format으로 된 텍스트 파일이다. 최대 서로 다른 10개 컨테이너에 대한 설정을 작성할 수 있다. 따라서 굳이 하나의 task definition에 하나의 컨테이너만 기록하기 보다는 서로 관련된 컨테이너들은 하나의 task definition에 정의하는 것이 좋다.
이때
(A) 복수 개의 컨테이너를 하나의 task definition에 기록할지,
(B) 각 컨테이너를 여러 task definition들에 기록할지 고민이 될 수 있는데
만약 복수 개의 컨테이너들이
(A)로 하는 게 좋다.
task definition이 클러스터 안에서 구체화되어 실행된 것이다. 클러스터 안에서 총 몇 개의 태스크를 실행할지 지정할 수 있는데 이때, 태스크 하나만 실행할 수도 있고 태스크를 서비스의 일부로 실행할 수도 있다.
만약 딱 한 번 실행될 작업이나 주기적인 배치 작업은 계속 실행되어 있고, 끝나면 재시작될 필요가 없기 때문에 그냥 단순한 하나의 태스크로 실행하면 되고, 예를 들어 로드밸런서 뒤에서 계속 실행되고 있어야할 애플리케이션이라면 서비스를 생성하는 것이 좋다.
하나의 한 종류의 task 여러 개 또는 여러 종류의 task 여러 개를 실행할 수 있기 위해 필요한 설정으로, 클러스터 내에서 총 몇 개의 태스크를 유지할지에 관한 설정이라고 이해하면 쉽다. 만약 어떤 태스크들이 모종의 이유로 정료된다면 ECS service scheduler가 task definition을 보고 또 새 태스크를 생성하는데 이는 사용자가 서비스에 설정한 desired number of tasks 를 유지하기 위함이다.
서비스를 생성할 때는 로드밸런서도 함께 사용할 수 있는데 만약 로드밸런서를 사용하는 서비스를 생성했고, 해당 서비스에 속한 태스크가 실행될 때는 태스크가 로드밸런서와 함께 등록된다. 로드밸런서로부터 오는 트래픽은 로드밸런서에 있는 인스턴스들에 분배된다. 이에 관해서는 다음과 같은 제한사항들을 기억해두면 좋다.
ip를 선택해야 한닫. 왜냐하면 awsvpc 네트워크 모드를 사용하는 태스크들은 ENI(Elastic Network Interface)와 연결되어 있지 EC2와 연결되어 있지 않기 때문이다. the number of desired running tasks 를 만족시킬 때까지 계속된다. 클러스터는 logical grouping of tasks or services 이다. 서로 다른 클러스터는 하부 인프라스터럭쳐가 달라지기 때문에 클러스터 분리로 애플리케이션 분리를 할 수 있다. 하나의 클러스터 안에서 여러 종류의 task, 여러 개가 실행될 수 있다. 아래에 소개할 Fargate를 사용한다면 이 클러스터 또한 Fargate에 의해 자동으로 관리된다.
하나의 클러스터 안에는 AWS Fargate, EC2 instances, 또는 외부의 인스턴스들에 의해 호스트되는 다양한 태스크들이 함께 실행될 수 있다.
EC2 인스턴스를 사용하는 경우 각 EC2 인스턴스는 한번에 하나의 클러스터에만 등록될 수 있다.
서비스 또는 태스크들을 실행하는 방법에는 크게 두 가지가 있다.
(1) AWS Fargate
AWS가 제공하는 서버리스 인프라인 AWS Fargate 위에서 실행하는 방법(Serverless pay-as-you-go 방식)
(2) AWS EC2
클러스터에 여러 개의 AWS EC2를 구성하고 그 위에서 컨테이너를 실행하는 방법
EC2 등과 같은 가상머신 등을 직접 관리할 필요가 없는 AWS Fargate 방식이 더 편리하지만 persistent storage를 사용해야한다거나 좀더 커스텀한 설정들을 원한다면 AWS EC2 방식이 좋다.
Fargate으로 태스크를 실행할 때는 CPU, memory, networking, IAM policies 등만 정하고 실행할 수 있는데 각각의 Fargate 태스크들은 다른 Fargate 태스크들과 커널, CPU, memory, ENI 등을 공유하지 않는다.
그리고 이때 CPU와 memory를 태스크 레벨에서 설정할 수 있고, 컨테이너 레벨에서도 설정할 수 있는데 보통은 태스크 레벨에서만 설정해도 충분하다.
Fargate를 사용할 때는 하나의 컨테이너의 resource limits을 설정하기 위해 ulimit 파라미터를 설정할 수 있다. 보통 이 ulimit 파라미터는 해당 OS의 기본 값을 사용하지만 한 컨테이너가 사용할 수 있는nofile(restriction on the number of open files)의 경우
soft limit: 1024
hart limit: 4096
으로 제한되어 있다. 만약 이걸 수정하고 싶다면
"ulimits": [
{
"name": "nofile",
"softLimit": 2048,
"hardLimit": 8192
}
]
이런 식으로 수정해주면 된다.
이것은 Fargate task 인프라스트럭쳐를 위한 특정 runtime environment를 의미한다. 이것은 커널과 컨테이너 런타임의 조합이다. 만약 새로운 커널 및 OS의 업데이트, 신규 기능, 버그 픽스, 보안 업데이트 등이 있다면 이것이 업데이트될 수 있고 이러한 노티를 사용자에게 미리 해준다.