GCP

GCP Load Balancer + Instance Group 을 운영하며 발생한 오류 트러블슈팅

Seungwoo Lee 2020. 7. 29. 23:03

1. 시작

본 글에서 외부 트래픽을 받는 HTTP Load balancer와 Server가 될 Instance group들로 이루어진 단순한 아키텍쳐를 다루고자 한다.

 

 

자격증을 준비하며 이론으로만 배웠던 아키텍쳐를 실제로 운영해보고 구성해보며 많은 것을 느꼈지만, 가장 먼저 와닿는 것은 역시 실전과 이론은 다르다는 것이었다.

 

이번에 작은 테스트 서버 하나를 구성해보며 이것저것 만져볼 기회가 있었다.

 

이 경험을 통해 Traffic을 분산해 여러개의 VM Instance들에게 나누어 뿌리는 단순한 아키텍쳐를 구성하는 데에도 수 많은 오류와 삽질이 존재함을 느꼈다.

 

본 글에서는 GCP HTTP(S) Load Balancer와 Managed Instance Group 으로 구성된 단순한 서버 아키텍쳐를 구성하며 일어났던 오류들과 그에 따른 트러블슈팅 경험을 나누고자 한다.

 

 

 

2. 발단

아키텍쳐에서 사용한 구성은 Layer 7을 지원하는 HTTP(S) Load balancer 와 Debian 기반 Apache2 http Server이고 8080 Port로 통신하기를 원하고 있다.

 

모든 아키텍쳐를 구성하고 난 뒤, 8080포트를 통해 통신을 시도했지만 502 에러가 나타났다.

 

이것을 염두하고 원인을 살펴보자. 

 

 

 

 

 

트러블슈팅을 시도할 떄 무엇보다 가장 먼저 해야 할 일은 로그 분석이다.

 

다행히도 GCP는 Operations Logging이라는 쿼리 기반의 로그 분석 서비스를 제공한다.

 

502 Error를 띄우고 난 뒤  Operations Logging으로 Load balancer에 찍힌 로그를 분석해보니 위와 같은 status가 발견되었다.

 

"faild_to_pick_backend" 로그를 보니 더 혼란해진다. 대체 왜 멀쩡한 backend를 두고 fail한다는 말인가?

 

502 error는 load balancer가 backend에 request를 보냈지만, backend로부터 정상적인 response를 받지 못했을 때 발생한다.

 

이 정보들을 종합해보면 현재 Load balancer와 Instance들이 서로 통신하고 있지 못하고 있음을 알 수 있다.

 

 

3. 분석

 

backend와의 통신을 키워드로 GCP Documentation을 뒤져보니 HTTP Load balancer는 Health check를 통과한 Instance에게만 트래픽을 보내는 방식을 사용하고 있음을 알 수 있었다.

 

즉, Instance들이 health check를 통과해야만 정상적인 연결이 된다는 것. 

 

그리고 Console 상에서 Health check를 보니 한 개의 Instance도 Healch check를 통과하지 못하고 있었다.

 

Load Balancer 입장에서는 단 한개의 Healthy한 Instance도 없기 때문에 트래픽을 주지 못했던 것이다.

 

"faild_to_pick_backend" Status가 이해가 되는 순간이다. 

 

어떻게 Instance들이 healthy 하다는 것을 보여줄 수 있는지 고민해야 한다.

 

이제 health check 를 키워드로 다시 Documentation을 찾아보면 Load balancer가 어떻게 health check를 진행하는지 쉽게 알 수 있었다. 

 

Load balancer는 특정한 IP Address로 backend에 Prove들을 보내 202 response에 따라 health check 통과 여부를 결정하는 방식을 사용한다.

 

본 글에 사용된 External HTTP(S) Load balancer는 • 35.191.0.0/16 • 130.211.0.0/22 IP ADDRESS를 사용한다.

 

 

즉 Firewall rule에서 위의 IP Address들을 Allow하지 않았기 때문에, Default로 모든 Ingress를 Deny하는 firewall의 rule에 막혀 health check prove들이 backend로 들어오지 못했기 때문에 문제가 생긴 것이다.

 

 

 

 

4. 해결

 

문제를 파악하고 원인을 분석했으니 이제 해결할 차례다. 

 

앞서 Firewall rule로 인한 health check 가 문제임을 알았으니 firewall rule을 설정해야 한다.

 

VPC network -> Firewall로 진입해 새로운 firewall rule을 생성하자.

backend가 될 instance의 Tag를 지정하는 Target Tag, 앞서 말했던 health check prove의 IP Address를 지정하는 Source IP ranges, port를 넣자.

 

실제로 instance가 load balancer와 통신하고 있는지 알아보기 위해 Instance에 직접 접속해 보았다.

 

서버 상에서 포트를 열기위해 8080 port를 listen하도록 설정하고

 

VirtualHost의 Port도 바꿔 8080 port로 접속할 수 있도록 설정한다.

 

 

 

 

 

access.log 파일을 열어보니 정말 prove가 위에서 설정한 IP address로 GET request를 보내고 있었다. 

 

200 code를 띄운 것을 보면 Load balancer와 backend가 이제 정상적으로 통신하고 있다는 것을 알 수 있다.

 

console 상에서도 모든 Instance들이 health check를 통과했음을 보여주고 있다. 

 

이제 server 주소의 8080포트로 접속을 시도해 정상적으로 구동이 되는지 알아보자.

 

 

 

 

 

접속을 시도하자 welcome page가 나와 정상적으로 접속할 수 있었다..

 

 

access.log 상에서는 내 Local pc의 IP Addess로 접속을 시도한 기록이 남아있었다. 

 

내가 접속을 시도한 log도 health check prove와 동일한 CIDR block이 찍혀있는 것이 보인다.

 

이로써 load balancer는 Instance의 health check를 시도하는 IP Address와 실제로 트래픽을 보내는 IP Address가 같음을 알 수 있다.

 

 

 

5. 결론

 

지금까지 단순한 Load balancer + Instance group 구성에서 일어났던 502 Error 트러블 슈팅의 경험을 나누어봤다.

 

502 Error의 모든 원인이 위와 같지는 않겠지만 본 글에서 찾은 원인이 가장 기본적이고 흔한 것이라고 생각한다.

 

이 글은 나와 같은 증상을 겪고 해결방법을 찾고 있으리라 생각하는 많은 이들을 위한 글이다.

 

항상 로그를 분석하고 원인을 찾는 습관을 들이자.