ALB의 포트설정 이슈 해결 : 동적 vs 명시적의 차이점
기존의 ECS 서비스에서는 호스트 포트를 0(동적 포트 할당을 위함)으로 설정하고 컨테이너 포트는 8081로 연결시키는 "태스크 정의"를 만들고 ALB를 적용시켰다.
이렇게 적용시켰을때 퍼블릭 IPv4주소(DNS)로 웹 url로 접근했을 때는 접속이 불가능했다.
그런데 새롭게 태스크 정의를 만들었는데 이때는 호스트의 포트를 0이 아닌 8081로 정해(동적 포트매핑)서 만들었더니 웹 url에 퍼블릭 IPv4 DNS주소로 접속이 가능했다.
이에 이것들이 대체 무슨 차이가 있어서 이런 결과가 발생한 것인지 것인지 궁금해서 알아봤다.
1. 차이점 파악하기
1-1. 기존 ECS 태스크 정의 "컨테이너 포트 매핑" 확인
- 기존의 정의에서는 호스트 포트를 0으로 설정했었다.
1-2. 새로운 ECS 태스크 정의 "컨테이너 포트 매핑"
- 새로운 정의에는 호스트 포트를 8081로 설정했다.
1-3. 차이점 파악하기
- 두 "태스크 정의"의 차이점은 호스트 포트이다. 기존의 0번은 동적 포트 매핑을 적용시키기 위함이었고 두 번째 8081은 그냥 고정 포트를 사용한 것이다.
2. 기존 ECS와 새로운 ECS의 IPv4 DNS 주소로 API 요청 시도
기존 ECS는 0번 포트로 자동 포트 할당을 적용시켰기에 로드 밸런서에 들어가서 어떤 포트로 매핑이 되어있는지 확인하는 작업이 선행되어야 한다.
2-1. 로드 밸런서 확인하기
- EC2 대시보드로 이동해서 "리소스"에서 "로드 밸런서"를 클릭한다.
2-2. 사용중인 로드 밸런서 상세정보 확인
- 하단 리스트에 나온 ALB 중에서 사용 중인 ALB의 이름을 클릭한다.
2-3. 대상 그룹정보로 들어가기
- 이동된 창에서 하단의 "리스너 및 규칙"에서 기본 작업 아래에 있는 적용된 "대상 그룹(recipia-target-instance)"을 클릭한다.
2-4. 대상 그룹정보 확인하기
- 하단의 이미지처럼 대상 그룹의 "세부 정보" 화면으로 이동할 텐데 맨 하단의 "대상" 목록을 본다.
- 기존의 ECS에서는 호스트 포트를0으로 해줬기에 포트 자동할당이 적용되어 32772번 포트로 할당되었다. 아래에 있는 8081 포트는 새롭게 태스크 정의를 만들 때 8081로 호스트 포트를 고정으로 지정해서 만들었기 때문에 8081로 되어있는 것이다.
2-5. 호스트를 0번 포트로 설정해서 만든 기존ECS의 EC2로 들어가서 DNS 주소로 요청 보내기
- 아래는 기존의 ECS 서비스 인스턴스의 DNS 주소이다. 이곳으로 접속을 시도했다.
- 계속 로딩바가 회전하면서 들어가지지 않았다.
2-6. 호스트를 8081로 고정한 새로운 ECS의 EC2로 들어가서 DNS 주소로 요청 보내기
- 아래는 새로운 ECS 서비스 인스턴스의 DNS 주소이다. 이번에는 이 DNS 주소에 요청을 보내봤다.
- 새로운 ECS는 고정 포트인 8081로 접속하니 잘 들어가졌다.
3. 기존 ECS는 왜 포트를 지정해도 안들어가질까?
기존의 ECS는 동적 포트 매핑이라 "로드 밸런서"에 들어가서 직접 health check를 통과한 포트인 32772번을 가지고 왔다. 근데 왜 접속이 안되는 걸까?
3-1. 그냥 내가 해본 생각
- 내가 생각하기엔 AWS내부적으로 ECS와 ALB는 연결을 시켜줬었다(서비스 생성할 때). 이때 호스트를 0번으로 지정하면 랜덤으로 포트가 지정되는데 ALB내부에서는 알아서 ECS의 랜덤 포트에 매핑하면서 인바운드 규칙을 허용하면서 접속하는 과정이 있는 게 아닐까? 그래서 인바운드 규칙을 따로 "보안 그룹"에 지정하지 않아도 알아서 연결되어서 접속을 해주는 게 아닐까?라는 생각이 들었다.
3-2. 인바운드 그룹 열어줘서 확인해 보기
- "보안 그룹"으로 이동해서 설정해 준 default 보안 그룹을 선택해서 세부 정보로 들어왔다.
- 하단의 인바운드 규칙을 보면 32772 포트에 대한 규칙은 없다.
3-3. 인바운드 규칙에 포트 추가하기
- 우측의 "인바운드 규칙 편집" 버튼을 클릭해서 32772 포트를 추가해 준다.
- 추가를 완료하면 아래와 같이 추가된 포트가 보인다.
3-4. 다시 dns 주소로 접속 시도
- 성공했다! 인바운드로 32772번 포트를 열어주니 일반적인 EC2의 퍼블릭 DNS 주소로도 접속에 성공했다.
4. 고민 해결
AWS의 ALB (Application Load Balancer)와 ECS (Elastic Container Service)를 사용할 때 포트 매핑과 호스트 설정은 다음과 같이 작동한다.
4-1. ALB의 Listener 포트
- ALB에서 들어오는 트래픽을 어떤 포트로 받을지 설정한다. 일반적으로 HTTP는 80, HTTPS는 443을 사용한다.
4-2. ECS의 포트 매핑
- 컨테이너가 호스트의 어떤 포트와 연결될지 설정한다. 예를 들어, `8081:8081`은 호스트의 8081 포트와 컨테이너의 8081 포트를 연결한다. `0:8081`은 호스트의 랜덤 포트와 컨테이너의 8081 포트를 연결한다.
4-3. ALB의 Target Group
- 여기서 ECS 서비스의 EC2 인스턴스와 연결된다. Target Group에 등록되는 것은 일반적으로 ECS 서비스에 속한 EC2 인스턴스이다. 그러나 이 EC2 인스턴스는 ECS 서비스에 의해 관리되며, 각 EC2 인스턴스에서 실행되는 컨테이너의 호스트 포트 정보를 알고 있다.
- ECS에서 "0:8081"과 같이 포트 매핑을 설정하면, ECS는 랜덤 한 호스트 포트를 선택하고 이를 컨테이너의 8081 포트와 연결한다. 그리고 이 정보는 ECS와 ALB 사이에서 공유된다.
- Target Group 설정에서는 이 호스트 포트를 지정할 수 있다. 따라서 ALB는 Target Group 설정을 통해 어떤 호스트 포트로 트래픽을 전달해야 하는지 알게 된다.
- 간단히 말해서, 타깃 그룹은 ECS 서비스의 EC2 인스턴스를 대상으로 하지만, 실제로는 그 안에서 실행되는 컨테이너의 호스트 포트 정보까지 알고 있어서, 올바르게 트래픽을 라우팅 할 수 있는 것이다.
4-4. 내부 동작 원리
- 호스트 포트가 0인 경우:
- ECS는 랜덤한 호스트 포트를 선택하고, 이 정보를 ALB에 알려준다. ALB는 이 랜덤 포트로 트래픽을 전달한다. 따라서 인바운드 규칙을 수동으로 설정할 필요가 없다.
- 호스트 포트가 8081인 경우:
- ECS와 ALB 모두 8081 포트로 설정되어 있으므로 명시적으로 트래픽이 전달된다.
즉, 호스트 포트가 0으로 설정되어 있더라도 ALB와 ECS 사이에는 동적으로 포트 정보가 공유되므로, 트래픽은 올바르게 라우팅 된다. 이는 AWS의 서비스 디스커버리 메커니즘 덕분이다.
따라서 ALB의 DNS/api 주소로 접근할 때 호스트 포트가 0이든 8081이든 상관없이 성공하는 것은 이러한 내부 메커니즘 때문이다.
4-5. 왜 내가 보안그룹을 열어줘야만 DNS에 접속이 가능한가?
- ECS와 ALB 사이에서는 동적 포트 매핑이 이루어져서 ALB가 자동으로 ECS의 랜덤 호스트 포트에 트래픽을 라우팅 해주지만, 이는 ALB와 ECS 사이의 내부 동작이다. 만약 직접 EC2 인스턴스의 퍼블릭 IPv4 DNS 주소와 랜덤으로 할당된 포트로 접속하려면, 해당 EC2 인스턴스의 보안 그룹에서 그 랜덤 포트를 명시적으로 열어주어야 한다. 그렇지 않으면, 보안 그룹 규칙에 의해 접속이 차단될 것이다.
- 즉, ALB를 거치지 않고 직접 EC2 인스턴스에 접속하려면, 해당 랜덤 포트에 대한 인바운드 규칙을 EC2의 보안 그룹에 추가해야 한다. 이렇게 하면 EC2 인스턴스의 퍼블릭 IPv4 DNS 주소와 랜덤 포트로의 접속이 가능해진다.
4-6. 결론 (고민사항 해결)
- ALB를 통한 접속
- ALB의 DNS 주소를 통해 접속하는 경우, ALB가 EC2 인스턴스의 "8081 포트 or 동적 랜덤 포트"로 트래픽을 라우팅 한다. 이 경우, EC2 인스턴스의 보안 그룹에서 "8081, 동적 랜덤 포트"를 별도로 열어주지 않아도 된다. 왜냐하면 ALB와 EC2 인스턴스 사이의 통신은 ALB의 설정에 따라 자동으로 이루어지기 때문이다.
- 직접 EC2 인스턴스에 접속
- 만약 ALB를 거치지 않고 EC2 인스턴스의 퍼블릭 IPv4 DNS 주소로 직접 접속하려면, EC2 인스턴스의 보안 그룹에서 "8081, 동적 랜덤 포트"를 열어주어야 접속이 가능하다.
- 만약 ALB를 거치지 않고 EC2 인스턴스의 퍼블릭 IPv4 DNS 주소로 직접 접속하려면, EC2 인스턴스의 보안 그룹에서 "8081, 동적 랜덤 포트"를 열어주어야 접속이 가능하다.
- 즉, ALB의 DNS 주소로는 보안 그룹 설정 없이도 접속이 가능하지만, EC2 인스턴스의 퍼블릭 IPv4 DNS 주소로 직접 접속하려면 해당 포트(여기서는 "8081, 동적 랜덤 포트")를 EC2 인스턴스의 보안 그룹에서 열어주어야 한다.
4-7. 마지막 테스트 (기존의 8081 포트도 인바운드에 있었어서 제거하고 검증)
- 8081도 인바운드에서 제거하고 접속을 시도해 봤다. (무한 로딩을 했다)
이 궁금증에 대한 대답은 랜덤 포트 할당에 따라서 생긴 문제가 아니었다는 것이었다.
내가 ALB의 동작 원리를 제대로 이해하지 못했던 것이 문제였던 것 같다.
ALB를 사용할 때 직접적으로 EC2를 통해 API요청을 보내거나 EC2에 접속하려면 "인바운드 그룹"에서 내가 직접 ALB에 연결시킨 포트를 열어줬어야 했다. 이전에는 포트가 동적으로 랜덤으로 부여되니 포트가 뭔지 몰라서 인바운드를 안 열었을 뿐이지 기존에 8081은 수많은 테스트를 하던 도중 내가 언젠가 한번 열어줬던 것을 잊고 있었던 것이었다. 그래서 2가지의 클러스터에서 다른 결과가 나온 것이다. 결국에는 8081 포트로 인바운드에 허용을 안 해줬으면 같은 결과로 둘 다 접속하지 못했을 것이다.
2023.10.30 - [AWS] - AWS - ALB를 적용시킨 ECS의 동적 포트 할당관계 동작원리
AWS - ALB를 적용시킨 ECS의 동적 포트 할당관계 동작원리
ALB를 적용시킨 ECS의 동작원리 이전 포스트에서 배포를 완료하고 실행했는데 ALB의 DNS주소 뒤에 8081포트를 입력하고 접속하니 접속이 불가능했는데 아무런 포트를 입력하지 않고 접속하니 잘 동
curiousjinan.tistory.com
2023.10.28 - [AWS] - AWS - ALB(로드 밸런서)없이 ECS 생성하기
AWS - ALB(로드 밸런서)없이 ECS 생성하기
이번 포스트에서는 ALB(로드 밸런서)를 사용하지 않고 AWS의 ECS를 생성하고 SpringBoot의 jar 파일를 dockerfile로 이미지 변환하고 배포해 보도록 하자 이 글을 따라하기 전에 ECR을 먼저 만들고 오는것
curiousjinan.tistory.com
'AWS > ECS, ECR' 카테고리의 다른 글
AWS Secrets & ECS SpringBoot 설정 (2): ECS 연동 (0) | 2023.11.03 |
---|---|
AWS Secrets & ECS SpringBoot 설정 (1): Secret 생성 (0) | 2023.11.03 |
AWS - ALB를 적용시킨 ECS의 동적 포트 할당관계 동작원리 (1) | 2023.10.30 |
AWS - ALB(로드 밸런서)없이 ECS 생성하기 (1) | 2023.10.28 |
AWS EC2를 사용하는 ECS 클러스터 생성 및 사용 (1) | 2023.10.28 |