간단한 트러블슈팅 경험 공유를 위해 작성하였다.
문제 발생
출근 길 버스에서 고객사의 전화 한 통을 받았다. 고객사는 서비스 확장을 위해 스테이징 환경에서 텐센트클라우드의 CVM과 TencentDB로 작은 웹 서비스 아키텍쳐를 구성했는데 DB접속이 안 되는 현상이 발생했다고 했다. 구체적인 이슈는 이러했다.
아키텍처를 들여다보면 고객사의 텐센트클라우드 계정에는 특정 VPC 内 1개의 가용영역에 Public IP를 할당받은 CVM 그룹이 위치한 서브넷이 있고 TencentDB가 속한 Private 서브넷이 구성되어 있다. 고객사는 현재 상태에서 추가 아키텍처 설계를 하기 전 CVM 인스턴스에서 DB로 연결 테스트를 진행했는데 타임아웃 에러가 계속해서 뜬다고 했다.
가장 먼저 내 머릿속을 스친건 보안그룹 설정이었는데 고객사는 마치 내 답변을 예상하리라도 한 듯 관련된 포트의 오픈여부는 다 확인했다고 했다. 그런데 문제는 생각보다 조금 더 희한했다.
고객사는 퍼블릭 서브넷 역할을 하는 서브넷에 위치한 인스턴스들 중 특정 한 개의 인스턴스에서만 이런 현상이 발생한다고 했다. 다른 인스턴스들에서는 DB로의 연결이 정상적으로 잡힌다고 했다. 사실 이 말을 듣고 처음든 생각은 텐센트클라우드 제품문제는 아닐 것이라는 확신이었다. 제품 문제라면 해결 절차가 조금 복잡하겠지만 보통 이런 경우는 고객사 운영상 문제에 가까운 경우가 많다.
문제 해결 시도
수사의 기본은 사건 현장에서 가까운 것 부터 하나씩 짚어보는 것이라고 하지 않았는가
1) 기본 아키텍처 점검
CAM설정, CVM, VPC, 서브넷 구성 모두 정상이었다.
2) 보안그룹 및 라우팅테이블 점검
고객사 CAM계정을 통해 콘솔에 접속해서 우선 보안그룹부터 확인했다. 문제의 CVM이 속한 보안그룹의 아웃바운드는 TencentDB가 속한 서브넷의 보안그룹에 대해 열려있었고 그 반대로의 TencentDB 서브넷의 인바운드도 오픈되어있었다. 포트도 이상이 없고 보안그룹 문제는 확실히 아니었다. VPC 내부 라우팅 테이블 설정도 크게 문제가 없었고 가능성이 낮긴 하지만 ACL 설정도 모두 기본값이라 역시 영향을 주지 않았다.
3) TencentDB
다음은 TencentDB for PostgreSQL의 자체설정을 살펴봤다. 그러나 파라미터 그룹, 엔드포인트 등을 모두 확인했지만 특별한 혐의점이 발견되지 않았다. 일단 다른 CVM에서는 접근이 정상적으로 되는 것으로 보아 이쪽은 가능성이 가장 낮았고 특히 한 개의 인스턴스에서만 접속이 안되는 것으로 보아 제품의 문제와는 더욱 관련이 없어보였다.
상황 정리
여기서 잠깐 짚고 넘어가면, 필자의 업무 특성 상 고객사의 트러블슈팅 상황을 자주 겪게 된다. 이럴땐 물론 문제해결이 가장 우선순위 이겠지만 고객사의 규모가 그렇게 크지 않은 경우 고객사의 비즈니스팀에게 현재 상황을 어떻게 설명해야 할지 동시에 고려해야할 필요가 있게 된다. 비개발직군에게 장애 상황을 그들의 언어로 적절히 치환해서 유연하게 설명해야 장애의 원인이 제품에 있지 않고 고객사의 운영방식에서 기인한 것이라는 점을 확실하게 전달할 수 있기 때문이다.
아무리 고가용성이 보장된 시스템이라도 장애는 피할 수 없으나 이것이 제품의 문제인지 사용자의 문제인지를 구분하는 것은 매우 중요하다. 사실 이 부분을 그들에게 명확히 짚고 넘어가지 않으면 나중에 원치않는 누명(?)을 쓰게 될 수도 있다.
그들의 언어로 최대한 풀어보면 이렇지 않을까. 고객사를 내 건물 303호에 입주한 세입자라 가정하고, 어느 날 303호에서 수도를 틀었는데 물이 나오지 않았다. 그런데 옆 304호에서는 물이 잘 나온다. 305호, 205호 105호 ... 건물 전체 모든 집을 돌아다니면서 수도꼭지를 돌려봐도 다른 집은 정상이다. 303호만 물이 안 나오는 상황. 수도관과 물탱크를 모두 점검해봤는데도 이상이 없는 상황이라고 할 수 있겠다.
패킷 분석
다시 상황으로 돌아와서, 이쯤되니 문제의 인스턴스에서 무슨 일이 일어나고 있는지 궁금해졌다.
tcpdump -i eth0 -n host <TDB IP>
먼저 일단 인스턴스에 접속해서 패킷을 들여다보았다.
$ tcpdump -i eth0 -n host 10.0.2.100
10:21:00.686502 IP 10.0.1.10.ssh > <TDB IP>.5432: Flags [S], seq 4839923, win 29200, length 0
SYN패킷 요청은 있으나 응답 패킷이 없었다.
이번엔 문제의 인스턴스가 아닌 다른 인스턴스에서 패킷 모니터링을 해보니 응답이 정상적으로 오는 것을 확인했다. 해당 인스턴스내 에서 누군가 패킷을 가로채는 느낌이 들어 시스템 내부 라우팅 테이블을 확인해보니 의심가는 부분이 있었다.
$ route -n
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.1.1 0.0.0.0 UG 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 docker0
10.0.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
10.0.1.1 0.0.0.0 255.255.255.0 U 0 0 0 eth0
10.0.1.2 0.0.0.0 255.255.255.0 U 0 0 0 eth0
10.0.2.0 0.0.0.0 255.255.192.0 U 0 0 0 br-3887aidc
시스템 라우팅 테이블에서 도커 브릿지가 보였다. 잡았다 요놈..
문제 해결
원인은 머신에 설치된 도커의 도커 브릿지 네트워크가 10.0.2.0/18로 향하는 트래픽을 중간에서 가로채고 있었다. DB의 IP대역도 이 안에 속해있어서 정상적으로 라우팅이 되지 않는 것이었다. 고객사는 분명 도커 이야기를 한 적은 없고 새로 생성한 서버라고 했었는데 알고보니 잘 돌아가던 다른 서버에서 뜬 이미지로 생성한 머신이었던 것이다. 사전에 도커 세팅을 했다는 것을 알려줬다면 좀 더 쉽게 갈 수 있었을텐데.. 이래서 병원에 가면 의사에게 증상을 제대로 설명해야 병이 빨리 낫는 법이다.
DB로 라우팅 되어야할 트래픽이 도커브릿지로 새고 있다는 점을 짚어주자 고객사는 원인을 인지하고 곧바로 도커데몬 설정 파일을 수정하여 문제의 브릿지 네트워크 대역을 변경했다. 테스트 결과 문제의 인스턴스에서 TencentDB로 라우팅이 정상적으로 되는 것을 확인하였다. 프로덕션 환경에서 일어난 문제는 아니었고 간단한 해프닝에 가까웠지만 또 하나의 문제해결 방법을 체득한 경험이었다.
고객사의 비즈니스 팀에게는 위에서 들었던 건물 비유를 다시 들어 303호에서 집주인 몰래 중고로 구입한 세탁기가 있었는데 그 세탁기가 배관으로 들어오는 물을 다 잡아먹고 있어서 수도에서 물이 안 나왔던 것이라고 설명드렸다.
끝.