목차
1.Overview
고객사 요청으로 ALB의 리스너 설정을 변경하여 사설포트 사용 및 리다이렉트 규칙을 만들어야 했다. 그 과정에서 여러가지 테스트를 거쳐 '이 정도 했으면 더 이상 예외 케이스는 없겠지?' 라고 생각하는 순간. 팀원이 맡고 있는 다른 고객사에서 '하나의 서버에서 포트별로 서비스를 동작시키고, 이걸 도메인 기반으로 라우팅하고 싶다' 라는 요청이 들어왔다.(역시 서비스를 상세하게 살펴보지 않고 HOL에 나온 내용만 반복해서는 턱 없이 부족함...) 리스너 규칙들을 살펴보면서 테스트해 본 경험을 이 글을 통해서 공유하고자 한다.
2.Prerequisite
Todo
필수는 아니지만 기왕이면 테스트를 위한 도메인 확보.(ex : isnt.world)
→ Route53에 도메인레코드 등록 및 도메인 발급 기관에 네임 서버 업데이트
EC2에 웹 서버가 설치되고 동작중이어야 함.(이 글에서는 apache 기준)
웹 서버의 configuration 파일을 수정하여 가상 호스트를 설정할 수 있다면 더 다양한 테스트가 가능
Expected Readers
- AWS의 VPC, EC2, ALB와 Target Group을 사용해 본 사람
- HTTP 프로토콜에 대하여 기본적인 이해를 가지고 있는 사람
- ALB 리스너 규칙에 따른 동작의 차이를 살펴보고자 하는 사람
3.AWS ALB Listener Rule(IF)
AWS ELB의 Application Load Balancer에서는 리스너에 대하여 다음과 같이 다양한 유형의 룰을 적용할 수 있다. 이 글에서는 이들 리스너 규칙에 대하여 케이스별로 살펴보고자 한다.
Case 1. Host header
Host header는 HTTP 프로토콜의 Host 헤더에 따라 다른 경로로 라우팅 할 수 있는 규칙이다. HTTP 의 Host 헤더에 대한 내용을 Mozlia 재단의 공식 문서에서 살펴보면 다음과 같이 정의되어 있다.(https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/Host)
서버(가상 호스팅용)의 도메인명과 (선택적으로) 서버가 리스닝중인 TCP 포트 번호를 명시합니다.
즉, 그냥 우리가 일반적으로 알고 있는 Domain name이라는 의미로 받아들이면 되겠다. 사용자가 입력하는 도메인에 따라 일치하는 규칙을 찾아서 라우팅한다. 구체적인 예시를 들자면 도메인에 따라 개발용 페이지/운영용 페이지의 구분, 모바일접속/PC접속시 페이지 구분과 같은 경우를 생각해볼 수 있다.
마찬가지로 다음과 같이 개발과 운영 인스턴스를 분리하는 시나리오를 생각해보면
로드밸런서의 리스너는 80번 포트에서 요청을 확인하고, HTTP 패킷의 Host 헤더값을 분석한다. Host header 값(사용자가 주소창에 입력한 값)이 dev.isnt.world이면 20000번 포트로, ops.isnt.world이면 30000번 포트로 포워딩하도록 설정할 수 있다.
이와 같이 타겟 그룹을 설정한다. 그림과 같이 서로 다른 인스턴스로 구성하였으나, 다음과 같이 동일 인스턴스에서 다른 포트에 동작중인 경우도 구성 가능하다.
이와 같이 리스너 규칙을 설정해주면 Target Group에 해당하는 인스턴스에 대하여 Health Check가 시작된다. Target Group의 Health Check는 HTTP status code 기반으로 동작하기 때문에, Target Group을 생성한 후 ALB에 리스너 규칙을 설정하여 연결해 주지 않으면 Health Check가 이루어지지 않는다.
서브도메인을 달리함에 따라 각기 다른 페이지가 호출됨을 확인할 수 있다. 실제 HTTP 패킷을 캡처해서 헤더값을 살펴보면
요청하는 URL에 따라 Host 헤더의 값이 변경됨 역시 확인할 수 있다.
Case 2. Path
웹 서버 내 경로를 기반으로 라우팅한다. 기입한 경로 규칙에 해당하는 경로에만 접근 권한을 갖게 되며, 대상 서버는 연결된 타겟 그룹의 서버이다.
웹서버 설정에서 20000번 포트로 요청이 들어오는 경우의 디폴트 디렉토리를 /var/www/html20000 으로 설정해두었고, test1 디렉토리와 test2 디렉토리에는 각각 index.html 파일이 있으며 각각의 내용은 다르다.
이에 따라 isnt.world/test1 으로 요청을 보냈을 때는 test1 디렉토리의 index.html이, inst.world/test2 로 요청을 보냈을 때는 test2 디렉토리의 index.html이 브라우저에 나타나기를 원한다.
위와 같이 리스너를 설정한다. 타겟 그룹 isnt-dev-tg는 웹서버 인스턴스의 20000번 포트로 요청을 보내고 있다.
ALB 리스너 규칙의 path 기반으로 정상적으로 라우팅 됨을 확인할 수 있다.
Case 3. Source IP
나의 Source IP를 입력하고 특정 타겟 그룹으로 라우팅되도록 설정한다. 디폴트 규칙에 의한 라우팅과 구분을 위해 서로 다른 타겟 그룹으로 흐르도록 했다.
페이지가 정상적으로 호출되었음을 확인할 수 있다.
다른 공인 아이피에서 접근하면 위와 같이 디폴트 라우트 규칙에 따라 isnt-ops-tg 타겟 그룹에 연결된 경로에서 웹 페이지가 호출됨을 확인할 수 있다.
Case 4. Query string
Query string은 URL 파라미터에 따라 다른 타겟 그룹으로 라우팅 시켜준다. 이번에도 마찬가지로 특정 쿼리스트링이 덧붙여진 URL로 요청이 들어오는 경우 외에는 모두 디폴트 규칙에 따르도록 ALB의 리스너 규칙을 설정했다.
리스너 규칙에서 지정한 key와 value에 따라 ?isnt=true를 붙여주면 지정된 페이지가 호출되고, 그 외에는 디폴트 페이지가 호출된다.
Case 5. http header
http 프로토콜의 헤더 필드에는 사용자가 임의로 생성한 새로운 필드값을 삽입하거나, 기존 헤더 값을 변경할 수도 있다. 이를 바탕으로 특정 http header 필드값을 포함한 요청에 대해서 특정 경로로 라우팅되도록 하는 규칙이 ALB의 http header rule이다.
이번에도 마찬가지로 특정 http 헤더값을 포함하는 경우를 제외하면 모두 디폴트 페이지가 출력되도록 ALB 리스너 규칙을 설정했다.
HTTP request 헤더에 ALB 리스너 규칙에 설정한 isnt: the best SA 를 넣어주면 미리 설정해둔 경로의 페이지가 호출된다.
그 외 일반적인 경로(isnt.world)로 들어오는 요청은 디폴트 페이지가 호출된다.
Case 6. http request method
ALB 리스너 규칙을 이용하면 HTTP method에 따른 라우팅도 가능하다. 기본적으로 GET 방식으로 동작하고 있는데, POST method를 이용한 요청인 경우로 프로토콜 헤더를 변조해서 요청해보면 지정한 타겟그룹에 연결된 웹 페이지가 호출된다. 반면 나머지 메소드를 이용한 요청은 모두 디폴트 페이지로 넘어가도록 설정했다.
번거롭게 툴을 사용하지 않고, 간단히 curl 커맨드 이용해서 테스트 해 볼 수도 있다.
4.AWS ALB Listener Rule(THEN)
Case 1. Forward to
들어오는 요청을 지정한 타겟 그룹으로 라우팅한다.
Case 2. Redirect to
HTTP status code 301 또는 302를 반환하는데, 가장 많이 쓰이는 경우는 HTTPS로 요청을 리다이렉트 시킬 때이다.
Case 3. Return fixed response
특정 HTTP status code를 반환하도록 지정한다.
Case 4. Authenticate
공식적으로는 AWS Cognito나 OIDC를 이용한 인증을 거치도록 지정하는 것으로 안내하는데, OICD는 OpenID Connect를 의미하므로 OAuth2.0을 생각하면 되겠다.
참고 문서
[AWS 한국 블로그] (https://aws.amazon.com/ko/blogs/korea/new-advanced-request-routing-for-aws-application-load-balancers/)
'AWS > AWS 서비스 정리' 카테고리의 다른 글
[AWS] ECS(1) - CPU Units(vCPU) limit 테스트 (1) | 2021.07.19 |
---|