AWS

[AWS] aws 강의 섹션 16 (ECS, 도커, ECS task Definitions, EKS, ECS with ALB)

대기업 가고 싶은 공돌이 2024. 10. 3. 08:46

도커란?

  • 도커는 앱 배포를 위한 플랫폼이다. 
  • 앱은 컨테이너 내부에 패키징 되는데 컨테이너는 아무 운영체제에서든지 실행될 수 있다.
  • 앱이 컨테이너에 들어가면 어느 운영체제에서든 같은 방식으로 실행된다.
    • 호환성 문제가 없어지고
    • 애플리케이션 행동 예측이 더 쉬워지며
    • 유지 보수가 더 쉬워지고
    • 언어, 운영체제 기술에 상관없이 실행이 가능하다.
  • 도커의 사용 사례로는 마이크로서비스 아키텍쳐가 있다.  

도커는 운영체제에서 어떻게 실행될까

서버 내부에 여러 도커 컨테이너를 설치할 수 있고, 각각의 컨테이너 내부는 다른 언어로 구성할 수 있다.

컨테이너 내부에 데이터베이스도 설치가 가능하여 활용성이 높다.

 

도커 이미지는 어디에 저장될까

  • 도커 이미지는 도커 리포지토리에 저장된다.
  • 도커 리포지토리는 여러 유형이 존재한다.
  • 도커 허브 
    • 아주 유명한 퍼블릭 리포지토리로 많은 기술에 적합한 이미지를 찾을 수 있다.
    • 우분투나 MySQL 같은 OS용 기본 이미지도 마찬가지다.
  • Amazon ECR
    • 프라이빗 리포지토리다. 
    • ECR public Gallery라 불리는 퍼블릭 리포지토리 옵션도 있다. 

도커와 가상머신의 차이점은 무엇일까

  • 도커 역시 가상화 기술의 일종이긴 하지만 완전히 가상화 기술은 아니다.
  • 리소스가 호스트와 공유되어 한 서버에서 다수의 컨테이너를 공유할 수 있다. 

EC2 머신은 하이퍼바이저 위에서 실행되는 가상 머신이다.

(하이퍼 바이저란 하드웨어 리소스를 가상 머신에게 적절하게 할당하며, 가상 머신을 생성하고 관리하는 인터페이스)

 

따라서 리소스가 분배되어 관리되기 때문에 EC2 끼리 리소스를 공유하지 않는다.

반면 도커 컨테이너는 Host OS의 자원을 따로 할당하여 관리하지 않고 도커 데몬을 통해 관리한다.

도커 데몬은 자원을 컨테이너 별로 따로 할당해주지 않고

API를 호출하게 하여 각각 컨테이너에게 Host OS의 자원을 공유하며 사용하는 방식으로 사용된다. 

도커 시작 방법

  • 도커를 시작하려면 우선 도커 파일을 작성해야 한다.
  • 도커 컨테이너를 구성하는 파일이다.
  • 베이스 도커 이미지에 몇 가지 파일을 추가하여 빌드하면 도커 이미지가 생성된다.
  •  도커 이미지는 푸시를해서 도커 리포지토리에 저장할 수 있다.
    •   도커 허브나 아마존ECR이 도커 리포지토리다.
  • 나중에 도커 리포지토리에서 이미지를 가져와 실행하게 되는데
    • 도커 이미지를 실행하면 도커 컨테이너가 된다.

도커 이미지를 AWS에서 어떻게 관리할까

Amazon Elasitc Container Service (ECS)

  • 도커 관리를 위한 아마존 플랫폼이다.

Amazon Elasitc Kubernetes Service (EKS)

  • 쿠버네티스를 관리하기 위한 것으로 오픈 소스 프로젝트이다.

AWS Fargate

  • 아마존의 서버리스 컨테이너 플랫폼으로
  • ECS, EKS 와 함께 작동할 수 있다.

Amazon ECR

  • 컨테이너 이미지를 저장하는데 사용된다.

ECS - EC2 Launch Type

  • ECS = elastic Container Service
  • AWS에서 도커 파일을 실행하면 ECS 클러스터에서 ECS 태스크가 실행된다.
  • EC2 런치 타입이란 사용자가 EC2 인스턴스를 직접 관리 하면서 그 위에 컨테이너를 실행하는 방식이다.
    • 이를 통해 ECS 클러스터 내에서 실행되는 컨테이너를 EC2 인스턴스에서 제어할 수 있다.
  • 사용자는 ECS 클러스터를 구성할 때 자신이 직접 EC2 인스턴스를 선택하고 관리해야 한다.
    • 즉, 어떤 유형의 EC2 인스턴스를 사용할지 선택하고, 그 인스턴스들이 수명 주기를 관리하는 것이 사용자의 책임이다.
    • 사용자가 인스턴스의 크기와 유형을 선택할 수 있기에
      사용량에 맞게 인프라를 최적화 할 수 있다.

ECS - Fargate Launch Type

  • AWS에서 도커 컨테이너를 실행하는 것은 동일하지만
    인프라 관리는 AWS에서 한다.
  • 완전한 서버리스 상태다. (신경을 안 쓰기 때문에, 물론 기반엔 서버가 존재한다.)
  • 우리는 단지 ECS task만 정의하면 된다. 
    • AWS에서 CPU 와 RAM 요구사항을 토대로 ECS 태스크를 실행한다.
  • EC2 인스턴스를 관리하지 않기 때문에 런치타입보다 훨씬 편하다.

ECS Agent란?

  • EC2 인스턴스에서 실행되는 도커 컨테이너를 ECS 클러스터와 연결시켜주는 소프트웨어다.
  • 이 에이전트가 있어야 ECs에서 해당 EC2 인스턴스를 클러스터에 추가하고 컨테이너를 관리할 수 있다.
  • ECS 에이전트는 도커 엔진과 상호작용하며 컨테이너를 시작하거나 중지하는 작업을 관리한다. 
  • ECS에서 스케줄링된 작업을 EC2 인스턴스에서 실행하고, 그 상태를 모니터링 한다.

ECS 의 IAM Role

EC2 인스턴스 내부에 ECS Agent가 실행중이라고 가정하자

  • 이 경우 EC2 인스턴스 profile을 만들 수 있다. 
    • 오직 EC2 런치타입에서만 가능하다.
    • 해당 profile은 ECS 에이전트에서만 사용된다.
  • ECS 에이전트는 EC2 인스턴스 프로필을 사용해
    ECS 서비스에 API 호출을 보낼 수 있고
  • 클라우드 워치 로그에 컨테이너 로그를 전송할 수도 있다.
  • ECR에서 도커 이미지를 가져오는 API 호출을 보낼 수도 있다. 
  • Secret Manager나 SSM Parameter Store의 민감한 데이터도 참고할 수 있다
  • ECS Task 는 ECS Task Role을 사용한다.
    • 이 룰은 EC2런치 타입과 Fargate 모두에게 적용될 수 있다.
    • 태스크 별로 구체적인 Role을 생성할 수 있다. 
    • 여러 Role을 생성하는 이유는 각각의 Role을 통해 서로 다른 서비스에 연결할 수 있기 때문이다.
    •  Task Role은 ECS 서비스의 task definition에서 정의한다.

 

ECS - Load Balancer Intergration

  • EC2 런치 타입과 Fargate 모두에 적용가능하다.

현재 여러 ECS 태스크가 실행 중이다.

모두 ECS 클러스터에 포함돼 있고 이 태스크를 Http, Https 엔드포인트로 노출하려고 한다

 

애플리케이션 로프밸런서를 ECS 클러스터 앞단에서 실행하면 사용자들은 

ALB로 백엔드의 ECS 태스크에 직접 연결하게 된다. 

네트워크 로드밸런서는아주높은 성능을 요구할 때나 AWS PrivateLink를 사용하는 경우에만 추천한다.  

ECS - Data 볼륨 (EFS)

  • 여러가지 볼륨 타입이 있지만 주의해야 할 것은 EFS다

이 상황에서 EFS 시스템을 ECS 태스크에 올리려한다.

  • EFS는 EC2 런치타입과 Fargate 모두와 호환되고
    ECS 태스크에 파일 시스템을 바로 올릴 수 있다.
  • EFS에 연결돼 있으면 어떤 AZ에서 실행 중인 태스크든 데이터를 공유할 수 있다.
  • 최고의 조합은 Fargate를 이용해 서버리스 방식으로 ECS 태스크를 실행하고
  • EFS를 파일 시스템으로 사용하는 것이다.
    • EFS도 서버리스 방식이어서 편리하다.

사용 사례로는 다중 AZ 스토리지 시스템과 컨테이너를 같이 사용하는 것이 되겠다.

 

유의할 점은 S3를 ECS 태스크에 파일 시스템으로 올릴 수 없다는 것이다.

ECS 오토 스케일링

  • ECS 태스크 수를 자동으로 늘리거나 줄일 수 있다.
  • AWS Application 오토 스케일링을 사용하면 된다. 
    • ECS 서비스의 평균 CPU 사용률
    • ECS 서비스에서 메모리 사용량
    • 타겟당 요청 수
  • 이 세 가지를지표로 다양한 오토 스케일링을 설정할 수 있다. 
  • Target Traking -  특정 타깃을 추적하는 방식
  • Step Scaling - 클라우드 워치에서 알림이 왔을 때 스케일링하는 방식
  • schedule Scaling - 미리 ECS 서비스 확장을 설정하는 예약 스케일링 방식이 있다.4
  • EC2 런치 타입이라면 태스크 단위의 ECS 오토 스케일링이
    EC2 인스턴스 단위의 오토 스케일링과 같이 않다는 점을 잘 유의하자
  • fargate가 인스턴스 관리를 안 하기 때문에 오토 스케일링 셋업이 훨씬 쉽다.

EC2 런치 타입에서 인스턴스 자동 스케일링

  • Auto Scaling Group Scaling
    • CPU 사용률에 따라 ASG를 확장한다고 하면
      CPU 사용률이 급등할 때 EC2 인스턴스를 추가할 수 있다.
  • ECS Cluster Capacity Provider
    • 새 태스크를 실행할 용량이 부족하면 자동으로 EC2 인스턴스를 추가한다. 
    • RAM이나 CPU가 모자랄 때 EC2 인스턴스를 추가한다.
    • ASG와 연동되어 자동으로 인스턴스 수를 조절한다
  • ECS 클러스터 Capacity Provider 사용을 더 추천한다. 

 

application auto Scailing에서 태스크를 조절하고

더이상 태스크를 늘릴 자원이 없을 때 ECS Capacity Provider에서 인스턴스를 자동으로 스케일링한다.

ECS Rolling Update

  • ECS 서비스를 업데이트 하는 방법이다.
  • ECS의 모든 태스크를 업데이트 하고 싶을 때
    • 어떤 태스크가 운영되고 어떤 태스크가 중단될 지를 제어할 수 있다
  • ECS를 업데이트 할 때 두 가지 설정을 할 수 있다.
    • 최소 Health 퍼센트와
      • 최소한으로 실행돼야하는 퍼센트다.
    • 최대 퍼센트다. 
      • 최대 퍼센트는 ECS 서비스를 업데이트하는데 있어
        새로운 태스크를 얼마나 생성할 수 있는지를 나타낸다. 

최소를 50 최대를 100으로 설정한다면 다음과 같이 2개를 죽이고 2개를 생성하는 식으로 업데이트를 진행한다.

 

만약 최소가 100이고 최대가 150이라면 아무것도 종료하지 않은채로
두 개의 태스크를 새로 생성하고 이후 두 개를 죽인 후 새로 두 개의 태스크를 만들어 업데이트를 완료할 것이다.

 

ECS task Definitions

  • 제이슨 형식으로 저장된다.
  • 콘솔에 있는 UI를 통해 제이슨을 생성할 수 있다.
  • 태스크 정의는 ECS 서비스에게 ECS 상에서 도커 컨테이너를 실행하는 방법을 알려준다.
  • 태스크 정의에는 중요한 정보들이 포함돼있다.
    • 이미지 이름
    • 컨테이너에 바인딩된 포트
    • 컨테이너에 요구되는 메모리와 CPU 성
    • 환경변수
    • 네트워크 정보
    • IAM Role
    • 로깅 구성

현재 EC2 인스턴스가 하나 존재하는데 ECS 클러스터 내부에 있어서

ECS Agent를 실행해야 한다.

여기서 도커 컨테이너를 실행할 것인데

아파치 서버를 올릴 것이다.

 

해당 서버를 인터넷 상으로 노출시켜야 하기 때문에 컨테이너 포트를 80으로 설정할 것이다.

그리고 EC2 인스턴스 내부에 컨테이너가 존재하기 때문에
EC2의 호스트 포트와 컨테이너의 80 포트를 매핑해줘야 한다.

 

그러면 호스트 포트 덕분에 인터넷, 혹은 외부 네트워크 통신이 가능해진다.

  • 한 개의 Task Definition당 최대 10개의 컨테이너를 정의할 수 있다.

ECS - 로드 밸런싱 (EC2 런치 타입)

  • 로드 밸런싱이 있으며, EC2 런치타입을 사용하고 있다면
    태스크 정의 내에 컨테이너 포트만을 정의한 경우
    동적 호스트 포트 매핑을 해야한다.

예를 들어 ECS 클러스터 내부에 두 개의 EC2 인스턴스가 존재하고

이들 모두의 컨테이너 포트가 80으로 설정돼있다고 하자 

하지만 호스트 포트는 아무것도 지정이 돼있지 않은 상황이다.

 

그러면 호스트 포트는 무작위로 지정돼 컨테이너와 매핑될 것이다.

ECS 태스크들은 다양한 포트로부터 액세스가 된다. 

만약 ALB를 사용중이라면 포트가 계속해서 변하기 때문에 ALB가 태스크로 연결되는 것이 
어렵지 않을까 하는 생각이 들 수도 있다.

 

하지만 ALB가 ECS 태스크와 연결돼 있을 경우엔 

올바른 포트를 찾을 수 있다.

 

  • 보안 관점에서는 좋지 않다. 
    EC2 인스턴스 시큐리티 그룹에서는 ALB에서 들어오는 모든 포트를 허용해야하기 때문이다.

ECS - 로드 밸런싱 (Fargate)

  • ECS 태스크가 고유한 프라이빗 ip를 가지게 된다.
  • fargate에는 호스트가 없기 때문에 컨테이너 포트만을 정의하면 된다.

  • 각각의 task는 동일한 포트를 보유하지만 ENI를 통해 다 다른 ip 주소를 갖게된다.
  • ALB는 모두 포트 80과 연결된다.

따라서 ENI의 시큐리티 그룹은 ALB에서 오는 80포트만을 허용하면 되고

ALB는 80 포트와 443 포트만을 허용하면 된다.

 

IAM Role per Task Definition

  • 각 태스크 정의 마다 IAM 룰이 부여된다.
  • 만약 태스크 정의를 상속받은 ECS 서비스가 생성될 경우
    • 해당 서비스(task)는 ECS task definition의 IAM룰을 그대로 상속하게 된다.
    • Role은 서비스 레벨이 아닌 task definition 단위에서 생성된다는 것을 잊지 말자.
    • 따라서 서비스 내부의 모든 태스크들이 해당 IAM룰을 전부 동일하게 상속한다.

ECS 태스크에 대한 IAM 룰은 ECS Definition에서 정의한다.

 

Environment Variables

  • 태스크 정의는 환경변수를 가질 수 있는데 이는 여러 가지 방식으로 가능하다.
    • 하드코딩: 태스크 정의 내에 직접 설정을 하여 고정된 URL을 가질 수 있다.
    • SSM Parameter Store: API 키, 민감한 변수들을 관리한다.
    • Sceret Manager: 민감 변수
      • ECS 태스크를 시작할 때 ECS 태스크 정의 내부에서 민감한 변수들을 참조할 수 있다.
    • Environment Files - S3: 환경 변수들을 S3에서 직접 로드하는 방법이 있다.
      • 파일을 통한 벌크 환경변수 로딩이라 불린다.

ECS - Data Volumes (Bind Mount)

  • 동일 ECS 태스크내부에서 다른 컨테이너와  데이터를 공유하는 법을 살펴보겠다.
  • ECS 태스크는 하나 또는 여러 개의 컨테이너를 정의할 수 있다.

Bind Mount는 EC2 런치타입과 Fragate 모두에 사용이 가능하다.

  • 바인드 마운트는 task 단위로 설정되는 볼륨이다.
  • 따라서 동일 task내의 모든 컨테이너가 동일한 볼륨을 참조할 수 있다.
  • 바인드 마운트는 EC2 인스턴스 스토리지기 때문에
  • EC2 수명 동안만 연결돼 있다. 
  • Fargate 태스크의 경우에는 임시 스토리지를 사용해
    데이터는 컨테이너의 수명과 연결된다.
    • 따라서 fargate task가 사라질 떼 스토리지가 사라진다. 
    • fargate에서는 20~200GB의 스토리지가 제공된다.

ECS task 배치

  • EC2 유형의 태스크를 생성하게 되면
    ECS는 대상 EC2 인스턴스의 사용 가능한 메모리와 CPU , 포트를 확인할 수 있어야 한다.

만약 위와 같은 상황에서 새로운 컨테이너, 새로운 태스크가 생겼을 때 이를 어디에 배치해야 할까?

삭제할 때도 마찬가지다 어떤 태스크를 삭제해야 할까?

 

  • 이를 위해서 태스크 배치 전략과 태스크 배치 제한이라는 기능이 존재한다.
  • 위의 두 기능을 통해 어디에 추가하고 어느걸 삭제할지 정할 수 있다.

이 두 기능은 ECS with EC2 에서만 가능하고 Fargate에서는 사용할 수 없다.

 

fargate에서는 aws에서 알아서 다 관리해준다.

 

ECS Task 배치 Process

  • ECS가 태스크를 배치할 때 다음의 과정을 거쳐 배치를 하게 된다.
    • 태스크 definition 내의 CPU 메모리, 포트 조건을 만족하는 인스턴스를 식별한다.
    • 이후 태스크 배치 제한을 확인한다. 
    • 마지막으로 태스크 배치 전략에 최대한 적합한 인스턴스를 판별한다.
    • 태스크 배치를 위한 인스턴스를 선택해 해당 인스턴스에 태스크를 배치한다.

ECS Task 배치 전략이란?

  • Binpack
    • 빈팩이란 가장 많은 CPU와 메모리를 사용중인 인스턴스에 태스크를 배치하는 것이다.
    • 이를 통해 사용 중인 인스턴스 수를 최소화 할 수 있다.
    • 특정 인스턴스에 더 이상 컨테이너를 배치할 수 없을 때가 되어야 다른 인스턴스를 생성한다.
    • 인스턴스를 가장 적게 사용하기에 가장 큰 비용 절감 효과를 누릴 수 있다.
  • Random
    • 무작위로 태스크를 배치하는 것이다.
  • Spread
    • 특정 값을 기반으로 분산되어 태스크가 배치된다.
    • 특정 값은 인스턴스 아이디나 가용 영역이 될 수 있다.
    • 만약 가용영역을 기반으로 한 분산 전략을 사용하면
      • 가용 영역 별로 태스크가 하나씩 분산된다.
    • ECS 인스턴스의 고가용성을 확보할 수 있다.

위의 전략들을 섞어서 사용할 수도 있다.

위와 같이 가용 영역에는 분산 전략을 메모리에는 빈팩을 사용할 수도 있다.

 

ECS Task 배치 제한

  • DistinctInstance: ECS 서비스 전반에 걸쳐 태스크들이 각각 다른 컨테이너 인스턴스에
    배치되게 하는 전략이다. 
  • memberOf: 클러스터 쿼리 언어를 사용해 표현식을 만족하는 인스턴스 상에 태스크를 배치하는 것이다.

이렇게 인스턴스 타입이 t2인 경우에만 태스크를 배치하게 하는 것이 예다

ECR 간단 소개

  • elastic Container Registy의 줄임말이다.
  • AWS에 도커 이미지를 저장하고 관리하는데 사용된다. 
  • ECR에는 두 가지 옵션이 있다.
    • 비공개로 저장하는 것
    • 퍼블릭 저장소를 활용하는 것
      • 프라이빗과 퍼블릭의 차이점은 다음과 같다.
        프라이빗은 IAM 권한이 있는 사용자만 이미지를 가져갈 수 있거
        퍼블릭은 아무나 도커 이미지를 다 가져갈 수 있다.
  • ECR은 ECS와 완전히 통합되어 있고 
    이미지는 백그라운드에서 S3에 저장된다. 
  • ECR에 대한 모든 접근은 IAM이 보호하고 있다. 
  • ECS가 ECR에서 이미지를 가져온 이후에는 컨테이너가 만들어진다. 
  • 이미지의 취약점 스캐닝, 버전관리, 태그, 및 수명 주기 확인을 지원한다. 

AWS Copilot

  • AWS에서 컨테이너 기반 애플리케이션을 쉽고 빠르게 배포하고 관리할 수 있게 도와주는 CLI다
  • Apprunner, CEs, Fargate에서 앱을 실행할 때의 어려움을 없애기 위해 사용한다.
  • 인프라를 설정하는 대신 앱을 빌드하는 데 집중할 수 있다.
    • 인프라 설정을 코파일럿에서 자동으로 해주기 때문
  • codepipeline과 통합하여 명렁어 하나만으로 컨테이너를 자동 배포할 수 있다.

Cli를 통해 아키텍쳐 파일을 만들고 코파일럿을 통해 

사전 작업이 다 완료된다 이후 ECS나 Fargate를 통해 배포할 수 있다.

 

Amazon EKS

  • EKS를 통해 컨테이너를 다룰 수 있다.
  • 쿠버네티스 클러스터를 AWS에서 사용하기 위한 서비스다.
  • EKS는 두 개의 시작 모드를 지원한다.
    • 워커 모드를 선택하면 EC2 인스턴스를 선택할 수 있다.
    • EKS 클러스터에 서버리스 컨테이너를 배포하고 싶으면 Fargate 모드를 선택할 수 있다. 
  • 회사에서 쿠버네티스를 사용하거나 쿠버네티스 API를 사용하고 싶을 때 EKS를 사용한다.
  • 쿠버네티스는 어느 클라우드에서든 사용할 수 있다.
    • 따라서 클라우드 또는 컨테이너를 마이그레이션 하려는 경우에 EKS 사용은 좋은 해결책이다.

EKS node = ECS task

 

EKS Pods = ECS Container와 같다.

 

EKS Pods를 외부 네트워크와 연결하고 싶다면 ELB를 사용하면 된다.

 

EKS 노드 타입

  • 관리형 노드 그룹
    • 관리되는 노드(EC2 인스턴스)를 생성하고 관리해준다. 
    • 노드는 AGS의 일부이다.
    • 온디맨드와 스팟 인스턴스를 지원한다. 
  • 자체 관리형 노드
    • 더 많은 통제를 원하는 경우에 사용한다. 
    • 노드를 직접 생성한 다음에 EKS에 등록해야 한다.
    • 노드를 ASG의 일부로서 관리해야 한다.
    • 사전 정의된 AMI를 사용하여 빌드 시간을 줄일 수 있다.
    • 온디맨드 및 스팟 인스턴스를 지원한다.
  • aws Fargate
    • 아무런 노드를 관리하지 않아도 된다. 
    • EKS에서 컨테이너를 실행하기만 하면된다.

EKS - Data Volumes

  • EKS에서 볼륨을 사용하려면 EKS 클러스터에 StorageClass 메니페스트를 지정해야 한다.
  • 이 때 CSI 호환 드라이버 라는 것을 사용한다.
  • EBS
  • EFS (fargate와 함께 작동한다)
  • FSx for Luster 
  • FSx for NetApp ONTAP
  • 의 볼륨 유형을 지원한다.