본문 바로가기

회고록

[project]ECS에 autoscaling을 적용하기 위해 alb가 필요할까?

1. 문제 상황에 대한 이해


나는 당연히 autoscaling을 적용하기 위해 alb가 필요하다 생각했다. autoscaling을 적용하면, 트래픽이 늘어났을 때 인스턴스 또는 컨테이너가 늘어날 것이고, 그에 따라 새로운 IP가 생성되어 alb가 이를 잡아줘야 한다고 생각했다. 아마 autoscaling과 alb의 개념을 확실하게 모르기 때문에 혼동한 것 같다.


2. 내가 이해한 바와 시도


2-1. ECS를 생성하자

  • 파이널 프로젝트를 진행 중이었다. 소비자가 예약정보를 담은 채 앱에 요청을 보낸다면, 그 내용이 드라이버에 전달되는 간단한 서버를 ECS로 구성했다. 이는 sqs-consumer 코드를 활용하였고, 레퍼런스에 더욱 잘 나와있다.
  • node.js로 간단히 작성된 코드를 레퍼런스를 참고하여 Dockerizing 하였다.
  • ECR 프라이빗 레포지토리를 만들어 해당 이미지를 푸시하였다.
  • ECR에서 이미지를 받아오는 작업 정의를 작성한다.
  • 작업 정의를 바탕으로 서비스를 생성하고, 작업을 실행한다.

2-2. alb를 생성하자

  • ‘/health’ 엔드포인트로 요청을 보냈을 때, 200 응답 코드가 나온다면 health 하다고 판단하게 설정하자.
  • 빈 대상그룹을 만든다.
  • 80 포트를 리스닝하고 대상그룹으로 보내준다.

2-3. ECS에 alb를 붙이자

  • ECS 컨테이너, 우리 프로젝트에서는 3000번 포트와 alb 대상 그룹의 3000번 포트에 매핑시킨다.

2-4. alb 헬스체크 실패

  • 공식문서에 따라 작업 정의에 컨테이너 헬스체크 명령을 입력해주었다.
"CMD-SHELL", "curl -f <http://localhost/> || exit 1"

3. 일단 해결?


3-1. 헬스체크 성공

2-4 방법인 헬스체크 명령어를 통한 방법은 실패했다. 헬스체크 엔드포인트를 아무리 ‘/’로 잘 설정해도 안되었다. 그러나 인위적으로 express를 실행하여 엔드포인트와 상태 코드를 작성하니 헬시가 떴다! 코드는 간단하게 다음과 같았다.

const express = require('express')
const app = express()

app.get('/health', (req, res)=>{
    res.status(200).send('health')
})

app.listen(3000, () => {
    console.log(`Example app listening on port 3000`)
  })

3-2. 근본적인 의문

자, 이제 나는 ECS에 autoscaling과 alb를 성공적으로 달았다. 이제 얻는 것이 무엇이냐?

나는 alb의 엔드포인트로 요청을 보냈을 때 ECS의 서비스에 잘 접속할 수 있을 것이다. 그런데 웬걸? 전체적인 아키텍처의 PoC(Proof of Concept)를 진행하는 과정에서 ECS의 엔드포인트에 요청을 보낼 일이 없는 것이다?

요청을 보내지 않아도, 메인 서버에서 sqs에 메시지를 쌓아주고 알림 서버에서 sqs에 쌓인 메시지를 바탕으로 작동하는 마이크로 서비스 구조이기 때문이었다!!

애초에 서비스를 나누게 된 배경이 서비스 간 느슨한 결합으로 서비스간 의존성을 낮추어 장애 대응에 유리하게 구성하고 싶기 때문이었다!!

그제야 나는 alb의 개념과 역할을 다시 보았다.


4. 로드밸런서의 개념과 역할


alb와 nlb 모두 로드밸런서이다.

4-1. 개념

둘 이상의 가용 영역에서 EC2 인스턴스, 컨테이너, IP 주소 등 여러 대상에 걸쳐 수신되는 트래픽을 자동으로 분산합니다. 등록된 대상의 상태를 모니터링하면서 상태가 양호한 대상으로만 트래픽을 라우팅 합니다. -aws-

따라서, 로드밸런서는 트래픽을 받아, 양호한 대상으로 트래픽을 전달해주는 역할을 하는 것이다.

4-2. alb와 nlb, 역할

alb는 네트워크 OSI7계층에서 애플리케이션 계층에서의 트래픽 분산을 담당한다. 따라서 HTTP 트래픽 분산은 80, HTTPS 트래픽 분산은 443 포트를 사용한다.

nlb는 전송 계층에서의 트래픽 분산을 담당한다. TCP 또는 UDP 단에서 트래픽 분산을 담당한다.

따라서, 둘의 차이는 들어오는 트래픽의 네트워크 계층에 따라 분산시켜주는 역할을 하는 것이다.

4-3. 과연 우리 서비스에 필요할까?

우리 서비스의 알림 서버는 트래픽을 직접적으로 받지 않고, 능동적으로 SQS에서 메시지를 끌어와서 실행된다. 따라서 autoscaling만 달아주면 늘어난 트래픽에 대해 높은 가용성으로 대처할 수 있다. 굳이 알림 서버의 엔드포인트로 요청을 전송하지 않으니 필요 없다!


5. Autoscaling의 개념과 역할


5-1. 개념

자동 크기 조정 은 Amazon ECS 서비스에서 원하는 작업 수를 자동으로 늘리거나 줄이는 기능입니다. -aws-

5-2. 역할

이는 대상 크기 조절 정책이나 단계 조정 정책을 활용하여 EC2나 ECS에 설정된 단계 이상의 CPU나 메모리 사용률을 보인다면, 확장되거나(scale-out) 축소되도록(scale-in) 설정할 수 있다.

 


6. 새롭게 알게 된 사실


6-1. loadbalancer와 autoscaling의 관계

막연히 알고 있던 각각의 개념과 역할을 명확하게 알게 되었다. 따라서 다음에 이를 사용한다면, 꼭 필요한 상황에 사용할 수 있을 것이다.

6-2. 철저한 검토

아무리 작은 서비스를 만들더라도 각각의 기능과 역할을 항상 생각해보고 검토하는 습관을 가져야 할 것이다. 그렇지 않으면, 이번 프로젝트처럼 필요하지 않은 기능을 구현하고 그 후에 잘못된 점을 알게 될지도 모른다. 그러나 이러한 경험도 좋은 배움이라 생각한다. 많이 경험하고 배워야겠다.