본문 바로가기

AWS

[AWS] NLB, ALB, Lambda를 통한 고정 IP 사용 방법

반응형

* 주의 : 추가 기능이 생성되었으며, 본 글의 방법은 Legacy 방법임.
https://aws.amazon.com/ko/about-aws/whats-new/2021/09/application-load-balancer-aws-privatelink-static-ip-addresses-network-load-balancer/

 

1. 개요

ALB의 IP 주소는 추가되거나 변경될 수 있기 때문에 Client가 인터넷 상에서 항상 ALB의 동일한 IP로 연결할 수 없을 경우가 생길 수 있으며, 이 때문에 오래된 디바이스를 쓰고 있거나 보안에 엄격한 네트워크 관리자에겐 ALB가 까다롭게 여겨질 수 있다.

 

ALB에 고정 IP를 사용하는 방법은 총 2가지가 있음

1. AWS Global Accelerator를 사용하여 애플리케이션 엔드 포인트에 대한 고정 진입점 역할을 하는 방법

2. ALB 앞 단에 NLB를 두고, ALB의 IP 주소가 변경되는 것을 1분마다 Lambda함수가 확인, 변경 시 NLB의 타겟 그룹에 적용시켜주어 NLB의 고정 IP를 부여하는 방법

2. 구성 방법

1. NLB에 트래픽을 받아 내부 ALB로 넘기는 TCP 리스너를 만든다. ALB는 TLS 처리를 하고 HTTP 헤더를 검사한 후 Rule에 기반하여 요청을 인스턴스, 서버, 컨테이너들로 구성된 대상그룹에 라우팅한다. AWS Lambda 함수는 ALB의 IP 주소들이 바뀌는 것을 감시하고 있다가 NLB의 대상 그룹에 업데이트하여 동기화한다. 마지막으로 고정 IP로 쉽게 방화벽에 화이트리스팅하여 ALB의 장점을 모두 활용한다. 모든 트래픽은 2개의 LB를 통과한다.

 

※ 주의 사항

: 각 로드 밸런서를 통과하는 데이터 처리에 따른 비용이 발생합니다. 두 로드 밸런스의 시간당 과금 및 Lambda 함수, S3, Amazon Cloudwatch 의 비용도 이 솔루션에서 발생

 

 

 

 

 

아키텍쳐

 

  • Lambda 함수 작업 개요

 

사전 요구 사항

  • 내부 또는 외부(인터넷) NLB를 준비합니다. 클라이언트가 VPC 안에 있다면 내부 NLB를 준비하고 그 외의 경우는 외부 NLB를 준비합니다.
    • 외부 NLB를 준비할 경우 Elastic IP를 미리 2개 할당해 놓는다.
    • 내부 NLB를 준비할 경우 따로 Elasitc IP를 할당해 놓을 필요가 없다.
  • NLB의 대상 그룹은 IP 주소 기반으로 대상 그룹을 생성해둔다. 대상 그룹의 프로토콜은 TCP로 지정한다. ( 추후 AWS Lamdba 함수가 이 대상그룹에 ALB의 주소를 등록 )
  • 내부 ALB를 준비한다. ( 여기에서 HTTPS 처리 또는 라우팅 처리를 하게 된다. )
  • (내부 ALB와 NLB는 같은 가용영역에 있어야 한다! )
  • ALB의 IP주소 등의 정보가 담길 Amazon S3 버킷을 준비한다.
  • AWS Lambda가 필요한 리소스들을 만들 수 있는 IAM 정책을 가지고 있는 IAM 역할을 준비한다.

단계별 Lambda 함수 작업

  1. ALB에서 쓰이는 IP 주소들을 DNS 쿼리로 알아온 뒤 S3 버킷에 결과(NEW IP LIST)를 업로드
  2. describe-target-health API 액션으로 현재 NLB에 등록된 IP 주소들의 리스트(REGISTERED LIST)를 가져옴
  3. 이전의 IP 주소 리스트(OLD LIST)를 다운로드함. 만약에 이번이 첫 Lambda 함수의 실행이라면 IP 주소 리스트는 비어있음
  4. NEW LIST를 Lambda 함수의 CloudWatch Logs 로그스트림에 출력함. 이는 ALB에서 쓰이던 IP 주소들을 찾는데 쓰일 수 있음
  5. 첫 실행에서 만들어졌던 내부 ALB IP주소들의 갯수를 추적하는 CloudWatch 지표를 업데이트 함 이 지표는 얼마나 많은 IP주소들이 그 동안 변경되었는지 보여줌. CW_METRIC_FLAG_IP_COUNT를 ‘false’로 설정하여 비활성화 시킬 수 있음. 여기에 ALB의 IP주소가 20개에서 24개, 그 다음에는 28개로 변하는 것을 보여주는 CloudWatch 지표의 예제가 있음.
  6. OLD LIST나 REGISTERED LIST에 있는 것을 제외한 NEW LIST에 있는 IP 주소들을 NLB에 등록함.
  7. OLD LIST 중 NEW LIST에 없는 IP주소들은 등록해지함.

과정

  • CloudFormation 클릭
  • Stack을 생성하며, 'Upload a template file'을 생성한다.

  • 환경 변수를 기입해준다.

  • 각 파라미터들 설명
    • ALB_DNS_NAME : ALB의 전체 DNS이름 (FQDN)
    • ALB_LISTENER : ALB의 리스너의 통신 포트
    • S3_BUCKET : Lambda 함수의 실행 간에 변경을 추적하기 위한 버킷
    • NLB_TG_ARN : NLB의 대상그룹의 ARN
    • MAX_LOOKUP_PER_INVOCATION : 실행 시 DNS 조회 최대 횟수. 기본 값은 CloudFormation 템플릿에서 50으로 설정
    • INVOCATIONS_BEFORE_DEREGISTRATION : IP 주소가 등록해지 되기 위해 필요한 실행 횟수. 기본 값은 CloudFormation 템플릿에서3회
    • CW_METRIC_FLAG_IP_COUNT : IP주소 카운트를 위한 CloudWatch 지표 컨트롤 플래그. 기본 값은CloudFormation 템플릿에서 ‘true’
  • 클라우드포메이션 스택 생성해준다.

결과

  • Lambda 함수가 생성된 것을 확인할 수 있다.

  • CloudFormation에서 Events 메뉴

  • CloudWatch에서 LogGroups
    • 1분 주기로 Lambda 함수가 ALB의 IP 주소를 체크하는 것을 확인할 수 있다.

  • EC2 - LoadBalancer Target Group - NLB의 TargetGroup
    • ALB의 ip address가 잘 적용된 것을 확인할 수 있다.
    • ALB의 ip address가 변경되지 않는다면 계속 유지된다.

  • VPC 내부의 EC2에서 Test
  • EC2 Instance → 내부 NLB의 DNS 주소 → 내부 ALB의 DNS 주소 → Apache Web Server

 

[root@ip-10-0-3-10 extra]# curl test-nlb-929056db1b5f64d6.elb.ap-northeast-2.amazonaws.com
<html><body><h1>It works!</h1></body></html>

  • Reference

https://aws.amazon.com/ko/blogs/korea/using-static-ip-addresses-for-application-load-balancers/

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형