[AWS] 로드밸런서 health check failed 해결

OhJiwoo·2024년 2월 11일
0

AWS

목록 보기
2/2
post-thumbnail

AWS 로드밸런서의 상태체크 원리에 대해 알아보겠습니다.

로드밸런서는 여러 대의 서버에 네트워크 트래픽을 분산해주는 장치입니다. 이때 트래픽이 전달된 서버가 제대로 동작하지 않으면, 해당 트래픽은 처리되지 못한 채로 사라져버릴 것입니다. 사용자의 요청을 적절히 처리하기 위해서는 현재 정상적으로 운영 중인 서버에만 트래픽을 전달해야 합니다.

그래서 로드밸런서는 상태 확인 기능을 제공합니다. 서버의 상태를 확인하여 동작 중인 서버에만 트래픽을 전달합니다. 그러면 실제로 어떻게 상태 확인을 진행하는지 알아봅시다.

실습을 위한 아키텍처 구축

서버 및 로드밸런서 구성

로드밸런서가 트래픽을 전달할 서버를 생성합니다.

실습을 간단하게 진행하기 위해 2대의 서버로 진행하였고, 모든 서버는 퍼블릭 IP를 가지고 있습니다.

앞서 생성한 2대의 EC2 인스턴스로 대상 그룹 test를 생성합니다. 여기서 대상 그룹이란 로드밸런서가 트래픽을 전달하는 대상을 그룹으로 묶어놓은 것을 의미합니다. 이때 대상은 인스턴스, Lambda 함수, IP 주소 등이 포함될 수 있습니다.

EC2 인스턴스를 생성한 VPC에 로드밸런서를 생성한 뒤, 앞서 만들었던 대상 그룹을 지정합니다. 그러면 이제 해당 로드밸런서는 들어온 트래픽을 test 대상 그룹에 전달할 것입니다.

보안 그룹 설정

로드밸런서의 보안 그룹

로드 밸런서의 경우 HTTP 80 포트를 허용해주어야 합니다. 사용자는 로드밸런서로 HTTP 요청을 보낼 것이기 때문에 80 포트로 오는 모든 요청을 허용해줍니다. 만약 로드밸런서로 요청을 보내도 로딩만 걸린다면, 이는 로드밸런서의 보안 그룹에서 요청을 차단하고 있는 것이기 때문에 보안 그룹을 변경해줄 필요가 있습니다.

보안 그룹의 경우 상태를 저장하기 때문에 인바운드 규칙으로 허용한 트래픽은 아웃바운드 규칙에 상관없이 허용된다는 특징을 가지고 있습니다. 그래서 인바운드 규칙만 설정해주었습니다.

서버의 보안 그룹

서버는 로드밸런서로부터 오는 HTTP 상태 확인 요청을 허용해야 하기 때문에 인바운드 규칙으로 로드밸런서의 보안 그룹 (sg-0ff1b43cfb6b5da7d)을 설정해줍니다. 이렇게 되면 서버는 로드밸런서에서 오는 모든 HTTP 요청만을 허용하게 됩니다. 해당 실습에서는 서버에 접속하여 설정을 진행해야 하기 때문에 SSH를 위한 22번 포트도 허용해주었습니다.

단순히 모든 HTTP 요청을 허용하게 되면 아무나 서버에 접속할 수 있기 때문에 보안상 추천하지 않는 방법입니다. 서버는 로드밸런서를 통해 전달되는 요청만을 허용하는 것이 좋습니다.

만약 위와 같이 Request timed out 이라고 표시되면, 아예 서버에 트래픽이 전달되지 못했다는 것이므로 서버의 보안 그룹을 확인해보는 것이 좋습니다.

time out 의 경우 트래픽이 전달되지 못한 경우에 발생하고, fail 은 트래픽이 전달되기는 하였지만 처리하지는 못했을 경우에 발생합니다. 오류 메시지를 잘 살펴보면 문제의 원인을 파악하는 데에 도움이 될 수 있습니다.

상태 검사 실패 원인

생성한 로드밸런서의 DNS 이름으로 접속하면 트래픽이 대상 그룹에 전달되어야 하는데, 실제로 해보면 다음과 같이 연결할 수 없다고 표시됩니다. 왜 그런 것일까요?

대상 그룹을 확인해보면, 상태 확인 결과가 모두 Unhealthy입니다. 로드밸런서에서 서버가 정상적으로 동작하지 않는다고 판단한 것입니다. EC2 인스턴스는 정상적으로 실행되고 있는데 왜 이렇게 판단했을까요?

해답은 바로 상태 확인의 원리에 있습니다.

생성한 대상 그룹을 다시 확인해보면 상태 확인 프로토콜로 HTTP, 경로는 /, 간격은 10초로 설정했습니다. 즉 로드밸런서는 대상 그룹 내의 서버의 / 경로로 10초에 한 번씩 HTTP 요청을 보낸 뒤, 응답 코드 200이 반환되면 해당 서버가 정상적으로 동작하고 있다고 판단하는 것입니다. 서버가 실행 중이더라도 요청에 대한 응답을 설정해주지 않으면 로드밸런서에서는 해당 서버가 동작 중이라고 인식할 수 없습니다.

현재 서버에는 / 경로에 대해 어떻게 응답을 보내야 하는지를 전혀 지정해주지 않았기 때문에 상태 확인이 실패했다고 나올 수밖에 없는 것입니다.

오류 해결

그러면 제대로 상태 확인이 가능하도록 변경해보겠습니다.

웹 서버 설치

EC2 인스턴스에 아파치 웹서버인 httpd를 설치하기 위해 EC2 인스턴스에 접속한 뒤 아래의 명령어를 입력해줍니다.

sudo yum install -y httpd
sudo systemctl start httpd
sudo systemctl enable httpd
sudo systemctl status httpd

웹 서버가 정상적으로 실행되었습니다.

index.html이 있는 경우

웹 서버는 /(루트)로 요청이 들어오면 자동으로 /var/www/html에서 index.html 파일을 검색합니다. 해당 파일이 있을 경우 200 코드와 함께 파일을 리턴해줍니다. 다시 대상 그룹을 확인해봅시다.

웹 서버는 실행되었지만, index.html이 없기 때문에 여전히 상태 확인에 실패하였습니다. index.html 파일을 생성해봅시다.

2대의 서버 중 1대에 다음과 같이 index.html 파일을 생성해보겠습니다.

다시 확인해보면 elb_test1 인스턴스가 Healthy 상태로 변경되었습니다. 로드밸런서에서 해당 서버로부터 정상적인 응답을 받았다는 의미일 것입니다. 나머지 서버에도 동일한 작업을 수행해주겠습니다.

2대의 서버 모두 정상 상태가 되었습니다! 이제 로드밸런서로 요청을 보내면 앞서 작성했던 index.html이 화면에 표시될 것입니다.

로드밸런서에 의해 요청이 2대의 서버로 분산되기 때문에 instance 1과 instance 2가 번갈아가며 표시되는 것을 확인할 수 있습니다.

index.html이 없는 경우

만약 index.html이 아니라 다른 파일이 있다면 어떻게 될까요?

index.html 파일을 삭제하고 a.html 이라는 새로운 파일을 생성해줍니다.

다시 상태 확인에 실패하였습니다. 이를 해결하기 위해서는 로드밸런서가 루트 위치에 있는 a.html로 상태 확인 요청을 보내도록 설정해야 합니다.

대상 그룹에서 상태 확인 경로를 /a.html 로 변경해줍니다. 그러면 웹 서버는 /var/www/html 위치에서 a.html 파일을 찾아서 반환해줄 것입니다.

다시 정상적으로 돌아왔습니다.

하지만 웹사이트를 확인해보면 a.html 내용이 표시되지 않습니다. 이는 로드밸런서의 요청이 /(루트)로 전달되기 때문에 웹 서버에서 제공해주는 index.html 파일이 표시되는 것입니다. a.html을 확인하고 싶으면 url 뒤에 /a.html을 추가해주어야 합니다.

이제 2대의 서버에서 번갈아가며 a.html이 화면에 보여집니다.

여기서 알 수 있는 것은 로드밸런서 요청과 상태 확인이 별개라는 것입니다. 상태 검사를 a.html의 응답으로 확인한 것일 뿐이고, 요청을 보낼 때는 url을 따로 설정해주어야 합니다.

결론

  1. 상태 확인은 특정 url로 요청을 보냈을 때 정상적인 200 응답이 돌아오는 것을 체크하는 것이다.
  2. 상태 확인과 실제 로드밸런서의 요청을 별개의 내용이다.

처음 로드밸런서를 실습할 때 해당 내용이 많이 헷갈렸습니다. 분명히 EC2 인스턴스가 실행 중인데 상태 검사는 왜 계속 실패하는지, 상태 검사 url과 로드밸런서의 리스너 url은 왜 따로 있는지 등을 이해하는 데에 많은 시간을 소요하였습니다. 계속 상태 검사 url을 변경해보고, 다양한 방식으로 구성을 변경하다 보니 비로소 작동 원리를 이해할 수 있었습니다.

저처럼 로드밸런서를 구축할 때 헤매는 분이 계시다면 이 글이 도움이 되었으면 좋겠습니다 😄

profile
클라우드에 대해 공부하고 있습니다👩‍🎓

0개의 댓글