EC2와 EC2 & Docker 가상화 방식
도커 구동 방식
도커 컨테이너와 도커 이미지는 어떻게 생성될까요 ?
먼저 도커 파일을 생성해야 합니다. 기본 이미지 등을 작성하고 데이터를 도커 이미지에 복사하는 겁니다. 그러면 애플리케이션을 구동할 수 있고 애플리케이션을 실행해 주는 명령을 내릴 수 있게 됩니다. 도커 파일을 정의하면 그 파일이 도커 이미지를 만듭니다. 도커 이미지가 생기면 도커를 실행할 수 있고 이것이 도커 컨테이너를 만들어줍니다.
도커 이미지는 저장도 되는데 도커 푸시를 통해 도커 리포지토리에 푸시할 수 있습니다. 도커 허브나 Amazon ECR이 될 수 있습니다. 이미지를 풀하면 도커 풀도 가능한데 그러면 구동이 가능해집니다. 이것이 도커의 작동원리입니다.
컨테이너 관리 플랫폼이 필요합니다. 세 가지 선택지가 있는데 먼저 ECS
는 Amazon 자체의 컨테이너 플랫폼이며 Fargate
는 ECS와 비슷하지만 Amazon 자체의 서버리스 컨테이너 플랫폼입니다. 마지막으로 EKS
는 Amazon의 관리형 Kubernetes 플랫폼으로 오픈소스 컨테이너 관리 플랫폼입니다.
ECS
ECS는 Elastic Container Service의 약자이며 AWS에서 도커 컨테이너를 실행하게 해주는 서비스입니다. 그러기 위해 인프라를 유지하고 프로비저닝해야 합니다. EC2 인스턴스가 ECS 클러스터를 지원합니다. Fargate와 함께 EC2 인스턴스를 유지하지 않아도 되는 솔루션도 있습니다. ECS는 한 번 컨테이너를 갖추고 나면 애플리케이션 로드 밸런서와 통합해서 여러분의 서비스와 태스크를 세상에 노출시킵니다.
ECS 서비스는 각각 다른 유형의 컨테이너를 작동시키고 있습니다. ECS 서비스는 새 도커 컨테이너를 시작하고 싶을 때 도커 컨테이너를 어디에 위치시킬지 찾습니다. EC2 인스턴스에서 말이죠. 이 경우 EC2 인스턴스들은 리소스와 CPU와 RAM입니다. 도커 컨테이너는 요구 사항이 있는데 필요한 CPU와 RAM의 용량이 정해져 있습니다. 그 도커 컨테이너는 특정 EC2 인스턴스에 위치하게 됩니다.
ECS 실행 유형
EC2 실행 유형
먼저 살펴볼 것은 Amazon EC2 실행 유형입니다. 리전과 VPC 두 개의 가용 영역과 함께 Amazon ECS 클러스터가 있다고 해봅시다. 보시다시피 VPC는 하나인데 다중 AZ에 걸쳐 정의돼있습니다. 오토 스케일링 그룹을 생성해서 EC2 인스턴스와 컨테이너 인스턴스들을 생성합니다. 컨테이너 인스턴스들도 서로 유형이 다릅니다. m5.xlarge나 t2.mall이 있고 다른 가용 영역에도 마찬가지로 m5.xlarge와 t2.small이 있습니다. 이 컨테이너들은 모두 하나 또는 그 이상의 오토 스케일링 그룹에 속해 있습니다. 그리고 이것들을 Amazon ECS 클러스터에 등록하길 원합니다. 그러려면 ECS 에이전트를 인스턴스들에서 운영해야 하는데 수동으로 하지 않아도 됩니다. ECS를 위해 만들어진 AMI를 사용한다면 ECS 에이전트는 사전 구성이 됩니다. 그래서 ECS 에이전트가 이 모든 컨테이너 인스턴스들에서 구동됩니다.
ECS 에이전트로 인해 이 컨테이너 인스턴스들은 Amazon ECS 클러스터에 등록될 것이고 ECS 태스크들을 실행하는 데 사용될 수 있을 겁니다. 따라서 컨테이너 인스턴스가 크다면 ECS 태스크를 많이 실행할 수 있습니다.
Fargate 실행 유형
또 다른 서비스로는 Fargate가 있습니다.Fargate는 AWS에서 도커 컨테이너 실행을 하게 합니다. 인프라를 프로비저닝할 필요가 없는 겁니다. 관리하거나 실행할 EC2가 없어서 아주 간단합니다. 그래서 서버리스 오퍼링이라고 불립니다. 서버를 관리하지 않기 때문에요. 그래서 도커 컨테이너를 실행하기가 더 간단하고 쉽습니다.
AWS는 CPU와 RAM이 얼마나 필요한지에 따라 컨테이너를 실행해 줍니다. 그리고 백엔드의 어디에서 실행되는지는 상관 없습니다. AWS가 알아서 처리하고 숨기기 때문입니다. Fargate 서비스를 살펴보면 아주 간단하게 새 도커 컨테이너가 필요하고 Fargate 클러스터에서 새 ECS 태스크가 실행돼야 한다고 하면 Fargate는 우리가 원하는 걸 실행해 줍니다. EC2 인스턴스도 필요 없습니다. 컨테이너가 그냥 실행됩니다. ECS의 Fargate 실행 유형에서는 Fargate가 ECS의 일부입니다.
ECS를 위한 Fargate 실행 유형에서는 똑같이 두 개의 가용 영역과 VPC, 리전, 클러스터가 있다고 가정해봅니다. 이번에는 Fargate 서비스가 태스크를 실행할 것이고 EC2 인스턴스를 미리 생성해 줄 필요가 없어서 훨씬 간단해집니다. Fargate 태스크에 액세스하려면 ENI, 즉 일래스틱 네트워크 인터페이스가 필요한데 VPC에서 실행되는 것으로 태스크를 네트워크 IP에 바인딩해줍니다. 이렇게 태스크에 액세스할 수 있게 됩니다. 태스크가 늘어나면 ENI도 더 생성되며 태스크마다 전부 다른 ENI가 생성됩니다. 위 사진에서는 4개의 Fargate 태스크가 실행 중이며 따라서 VPC에서는 네 개의 ENI가 실행 중입니다. ENI가 별개의 IP이기 때문에 충분한 IP 주소들을 가지고 있는지 확인해야 합니다. VPC에 사설 IP가 충분한 지 살펴봐야합니다. 즉 Fargate 클러스터를 가동할 만큼 충분히 큰 VPC가 있어야 합니다. 태스크가 많을 경우를 대비해서요.
ECS 태스크들은 AWS 서비스에서 연산을 실행할 수도 있습니다. 예를 들면 DynamoDB나 Amazon S3와 통신하는 겁니다. 그래서 IAM 역할이 있어야 합니다. EC2 인스턴스에 IAM 역할이 있는 건 알지만 ECS 태스크에도 IAM 역할이 있습니다. EC2 인스턴스가 Amazon ECS 클러스터를 가동하는 예시를 살펴봅니다.
ECS IAM Role
도커 컨테이너가 애플리케이션을 가동하면 이 태스크 역할은 태스크에 연결되므로 태스크를 생성하면 태스크 역할을 연결하게 됩니다. 그래서 각 태스크가 특정 역할을 가지게 됩니다. EC2 인스턴스를 가동한 두 번째 태스크가 있다면 그 태스크를 위한 새 ECS 태스크 역할을 생성하는 게 좋습니다. ECS 서비스가 여러 개고 태스크를 구동할 거라면 서비스마다 다른 ECS 태스크 역할을 주는 것이 좋습니다. 그리고 태스크 정의에서 정의합니다. 한 번 태스크 역할이 ECS 태스크에 연결되면 예를 들어 Amazon S3 버킷에 액세스할 수 있고 Amazon EC2 인스턴스에서 가동 중인 태스크일 경우 S3 버킷에 액세스하는 것이 허용됩니다. 마찬가지로 두 번째 태스크 역할이 DynamoDB와 통신한다면 역할은 그 태스크만 DynamoDB에 액세스하는 것을 허용합니다. 그래서 보안이 세분화됩니다. 태스크의 유형이 다양한 만큼 많은 태스크 역할도 있게 됩니다. 특정 AWS 서비스에 액세스해야 하는 태스크가 있는 ECS 서비스가 있다면 ECS 태스크 역할을 새로 만드는 겁니다.ECS 태스크의 데이터 공유
ECS는 EFS 파일 시스템과 통합됩니다. EC2 인스턴스가 존재하고 태스크가 여러 개라면 EFS 파일 시스템을 생성해서 파일 시스템에 ECS 태스크를 직접 마운트하는 것도 가능하며 EC2 인스턴스에도 작동합니다. Fargate 태스크도 가능합니다. 태스크에 EFS 볼륨을 마운트하면 데이터를 공유할 수 있습니다. EFS는 다중 가용 영역에 걸쳐 사용할 수 있기 때문에 태스크 역시 어느 가용 영역에서든 실행할 수 있습니다. EFS 볼륨에서도 동일한 데이터를 공유할 수 있습니다. Fargate와 EFS를 함께 사용한다면 서버리스 태스크 관리와 데이터 저장소 EFS를 쓸 수 있는데 그러면 서버를 관리하지 않고 완전한 서버리스 형태로 데이터를 저장하고 컴퓨팅을 실행할 수 있습니다. ECS와 EFS를 함께 쓰는 사용 사례는 컨테이너를 위한 지속형 다중 AZ 공유 스토리지를 사용하는 것입니다.
ECS 서비스, 로드 밸런싱
Amazon ECS 클러스터에 EC2 실행 타입으로 두 개의 컨테이너 인스턴스가 있다고 가정할 때 Amazon ECS 클러스터에 여러 서비스를 가동할 수 있습니다. 여러 태스크를 여러 EC2 인스턴스에 걸쳐 가동하는 서비스 A가 있습니다. 이 태스크를 사용자들에게 노출시키고 싶다면 애플리케이션 로드 밸런서를 생성해서 태스크에 직접 통합시킬 수도 있습니다. 사용자들에게 애플리케이션 로드 밸런서의 DNS나 URL만을 주는 방법도 있습니다. 로드 밸런서의 뒤에서는 ECS 태스크에 오는 모든 요청을 포워딩합니다. ECS 서비스의 일부로서 가동되고 있는 요청들입니다. Amazon ECS 클러스터 하나에서 다중 서비스를 가동할 수 있습니다. 만약 서비스 B라는 또 다른 서비스를 생성하면 태스크를 두 개만 가동합니다. 마찬가지로 애플리케이션을 노출시키려면 같거나 새로운 애플리케이션 로드 밸런서를 연결합니다. 가장 좋은 방법은 예를 들자면 컨테이너를 지정된 포트 없이 실행하는 겁니다. 컨테이너를 실행할 때 예를 들어 NodeJS 애플리케이션이라면 EC2 인스턴스에 배정된 무작위 포트를 얻는 겁니다. 이런 경우에는 컨테이너에 무작위 포트가 지정되는데 서로 다른 네 개의 태스크에 서로 다른 두 개의 ECS 컨테이너 인스턴스가 배정된 것입니다.
로드 밸런서는 어떤 포트와 통신해야 할지 어떻게 알까요 ?
애플리케이션 로드 밸런서는 특정 포트와 통신이 가능한데 ECS로는 ALB 밖으로 포트 80, 443을 노출할 수 있습니다. ALB의 동적 포트 포워딩 기능 덕분에 ALB가 ECS 태스크에 대한 올바른 포트를 EC2 인스턴스에서 찾을 수 있게 됩니다. ALB가 ECS에서 특정 서비스에 한 번 등록되면 태스크를 찾아서 자동으로 올바른 포트를 통해 통신하게 됩니다. 같은 컨테이너에서 원하는 만큼 많은 인스턴스를 하나의 EC2 인스턴스에서 가동하고 하나의 애플리케이션 로드 밸런서를 통해 노출시킬 수 있다는 것입니다. 그러기 위해서는 네트워크 보안을 짚고 넘어가야 합니다.
EC2 인스턴스와 ALB의 보안그룹
EC2 인스턴스의 보안 그룹에서 ALB 보안그룹으로부터 오는 포트를 허용해야 합니다. ALB가 인스턴스 상의 다양한 포트 그룹과 통신할 테고 네트워킹을 위해 보안 규칙을 설정해야 하는 것입니다. 하지만 Fargate의 경우 조금 다릅니다.
Fargate 태스크와 ALB의 보안 그룹
Fargate는 가동되고 있는 모든 태스크에 대해 ENI를 생성하는데 그래서 ENI는 고유의 IP가 있지만 포트는 그대로입니다. 예를 들어 태스크가 세 개 있고 각 태스크의 IP는 다르지만 모두 80번 포트를 가지고 있다고 가정했을 때 로드 밸런서를 생성하면 서로 다른 IP들과 통신하겠지만 전부 같은 포트, 80번과 통신합니다. 네트워크 보안 측면에서 이를 가능하게 하려면 보안 그룹으로서의 ENI가 태스크 보드에서 애플리케이션 로드 밸런서를 반드시 허용해야 합니다.
ECS 클러스터 스케일링 (서비스 스케일링)
다양한 지표에서 ECS 서비스를 스케일링할 수 있습니다. 예를 들어 서비스 CPU 사용량입니다. 서비스에 태스크가 두 개 실행되고 액세스하는 사용자는 하나일 때 CPU 사용량은 매우 낮습니다. 갑자기 오토 스케일링을 설정해서 여러 사용자가 서비스에 액세스할 수 있게 되면 CPU 사용령도 높아지게 됩니다. CloudWatch 지표를 ECS 서비스 전체 평균 CPU 사용량으로 설정해서 특정 임계값을 넘길 때 CloudWatch 경보를 작동하도록 만들 수 있습니다. 그러면 ECS 서비스가 자동 스케일링되어 새로운 태스크를 시작합니다. Fargate와 EC2 실행 유형 모두에서 이렇게 작동합니다. 오토 스케일링 그룹과 굉장히 비슷한 과정입니다. 그러나 EC2 인스턴스에 이런 태스크를 실행할 때가 있습니다. EC2 실행 유형을 사용하는 경우인데 그래서 때때로 EC2 인스턴스를 스케일링할 필요가 있습니다. 그렇지 않으면 새로운 태스크를 실행할 공간이 남지 않을 겁니다.
ECS 클러스터 스케일링 (EC2 인스턴스 스케일링)
따라서 EC2 인스턴스의 ECS 클러스터를 스케일링하려면 Amazon ECS의 Capacity Provider를 쓰는데 EC2 인스턴스 실행 유형에서만 선택할 수 있는 옵션입니다. 즉 ECS 스케일링은 태스크를 실행할 충분한 용량이 없는 경우 해당 서비스를 지원하는 EC2 인스턴스의 오토 스케일링 그룹을 실행하고 ECS 클러스터에 EC2 인스턴스를 추가합니다. EC2 서비스에는 두 가지 수준의 스케일링이 있습니다. 바로 서비스 스케일링 및 백엔드 EC2 인스턴스 스케일링입니다. Fargate 실행 유형을 사용하지 않고 다른 방법으로 ECS 서비스를 스케일링하려면 Amazon SQS 대기열 길이를 사용합니다. SQS 대기열에서 메시지를 읽는 서비스가 있어서 메시지를 폴링한다고 가정할 때 ECS 서비스에 오토 스케일링을 설정해서 CloudWatch 지표의 대기열 길이를 보면 특정 임계값을 초과할 경우가 있습니다. 대기열에 메시지가 너무 많을 때입니다. 이제 CloudWatch 경보를 작동하고 Amazon ECS 서비스의 오토 스케일링 서비스가 스케일링되고 나면 새로운 태스크가 생성됩니다. 즉 사용 중인 EC2 인스턴스를 스케일링하고 싶다면 ECS Capacity Provider를 설정해 주면 됩니다.
- Minumum healthy percent: 100
- Maximum percent: 200
이번에는 ECS 서비스를 업데이트하는 방법입니다. 바로 롤링 업데이트를 사용하는데 즉 ECS 서비스를 v1에서 v2로 업데이트할 때 태스크가 한 번에 얼마나 어떤 순서로 시작되고 중지되는지 제어할 수 있습니다. 그래서 ECS 업데이트를 보면 새로운 태스크 정의의 개수를 선택하고 ECS 서비스를 업데이트할 때 두 가지 설정이 있습니다. 최소 정상 백분율 및 최대 백분율입니다.
예를 들어 ECS 서비스에 실행 중인 태스크가 9개이고 실제 실행 가능 용량의 100%를 차지합니다. 이때 최소 정상 백분율을 100이하로 설정해 봅시다. 이 경우 남아있는 태스크가 최소 정상 백분율만큼 충분하다면 오른쪽에 있는 작업은 모두 종료할 수 있게 됩니다. 그리고 최대 백분율은 버전 2에서 얼마나 많은 태스크를 생성할지 나타내는데 기본적으로 서비스를 롤링 업데이트합니다. 이렇게 두 가지 설정이 업데이트에 영향을 줍니다. 계속해서 새로운 태스크를 생성하고 태스크를 전부 종료하는 등 이 모든 과정이 태스크를 전부 종료해서 새로운 버전으로 업데이트하기 위해서입니다.
ECS Rolling Update Senario
- Minumum healthy percent:
50%
- Maximum percent:
100%
- 시작 태스크:
4
- Minumum healthy percent:
50%
- Maximum percent:
150%
- 시작 태스크:
4
ECR (Elastic Container Registry)
- 관리 배포하기 위해 사용, 스토리지 사용에 따라 비용 청구
- Amazon ECS로 완전히 통합
- IAM 사용, ECR로 업로드된 이미지는 모두 Amazon S3에 저장
- 이미지 취약성 스캔, 버전 관리, 태깅, 이미지 수명 주기 지원
EKS (Elastic Kubernetes Service)
- AWS에 관리형 쿠버네티스 클러스터를 실행
- 오픈 소스 시스템으로 컨테이너화된 애플리케이션(도커)등을 자동으로 배포, 스케일링, 관리
- 일종의 규격화를 제공하는 다양한 클라우드 공급자 사용 (Cloud-Agnostic)
- Azure나 Google 클라우드 등 어떤 클라우드에서도 사용 가능
- EC2 실행모드, Fargate 모드
- 온프레미스로 호스팅된 다중 도커 기반의 애플리케이션이 있으며, 이를 AWS로 이전시키려 합니다. 여러분은 인프라를 프로비저닝하거나 관리할 의향이 없으며 그냥 컨테이너를 AWS 상에서 실행하려고 합니다. 이 경우, 다음 중 어떤 AWS 서비스를 선택해야 할까요 ?
- A. Elastic Container Service (ECS)
- B. Elastic Container Registry (ECR)
C. AWS Fargate
- D. Elastic Kubernetes Service (EKS)
✅ AWS Fargate를 사용하면 서버를 관리할 필요 없이 AWS 상에서 컨테이너를 실행할 수 있습니다.
- Amazon Elastic Container Service (ECS)에는 두 가지의 실행 유형이 있습니다. ( )와 ( )입니다.
A. Amazon EC2 실행 유형과 Fargate 실행 유형
- B. Amazon EC2 실행 유형과 EKS 실행 유형
- C. Fargate 실행 유형과 EKS 실행 유형
- ECS 클러스터(EC2 실행 유형)상에 호스팅된 애플리케이션이 있습니다. 여러분은 ECS 태스크가 S3 버킷으로 파일을 업로드하게 하려 합니다. 이를 위해서는 다음 중 어떤 ECS 태스크용 IAM 역할을 수정해야 할까요 ?
- A. EC2 인스턴스 프로필
B. ECS 태스크 역할
✅ ECS 태스크 역할은 ECS 태스크 자체가 사용하는 IAM 역할입니다. 컨테이너가 S3, SQS 등이 다른 AWS 서비스를 호출하려 할 때 사용합니다.
- 도커 컨테이너 상에서 실행 중인 WordPress 웹사이트를 온프레미스에서 AWS로 이전하려 합니다. ECS 클러스터에서 애플리케이션을 실행하기로 했으나, 도커 컨테이너가 웹사이트 파일, 이미지, 영상을 비롯한 동일한 WordPress 웹사이트 콘텐츠에 액세스할 수 있게끔 하려 합니다. 이를 위해서는 어떤 방법이 권장될까요 ?
A. EFS 볼륨 마운트
- B. EBS 볼륨 마운트
- C. EC2 인스턴스 스토어 사용
✅ EFS 볼륨은 서로 다른 EC2 인스턴스와 서로 다른 ECS 태스크 간의 공유가 가능합니다. 컨테이너의 영구적인 다중 AZ 공유 스토리지로 사용될 수 있습니다.
- EC2 인스턴스로 구성된 ECS 클러스터 상에 애플리케이션을 배포하려 합니다. 현재, 클러스터는 DynamoDB에 대한 API 호출을 성공적으로 발행한 애플리케이션 하나를 호스팅하고 있습니다. S3로의 API 호출을 발행하는 두 번째 애플리케이션을 추가하려는데 권한 부여 관련 문제가 발생했습니다. 이 문제를 해결하고 적절한 보안을 유지하기 위해서는 어떤 방법을 사용해야 할까요 ?
- A. EC2 인스턴스 역할을 수정해 S3에 대한 권한 추가
B. 새 애플리케이션을 위한 IAM 역할 생성
- C. Fargate 모드 활성화
- D. ECS 태스크를 허용하도록 S3 버킷 정책 수정
- Application Load Balancer가 동일한 ECS 컨테이너 인스턴스에서 실행 중인 다수의 ECS 태스크로 트래픽을 리다이렉트하게 만들기 위해서는 다음 중 어떤 기능을 사용해야 할까요 ?
A. 동적 포트 매핑
- B. 자동 포트 매핑
- C. ECS 태스크 정의
- D. ECS 서비스
- 온프레미스 도커 기반 애플리케이션을 Amazon ECS로 이전하려 합니다. 여러분은 도커 허브 컨테이너 이미지 라이브러리를 컨테이너 이미지 리포지토리로 사용하고 있었습니다. 다음의 대체 AWS 서비스들 중 Amazon ECS와 완전히 통합되어 있는 서비스는 무엇인가요 ?
- A. AWS Fargate
B. Elastic Container Registry (ECR)
- C. Elastic Kubernetes Service (EKS)
- D. Amazon EC2
✅ Amazon ECR은 컨테이너 이미지를 손쉽게 저장, 관리, 공유 및 배포할 수 있도록 해주는 완전 관리형 컨테이너 레지스트리입니다. 이는 도커 기반 애플리케이션의 실행에는 도움이 되지 않을 겁니다.