Incident Library

IL-0493 Netlify · 2021-03-25gcpnetworking

Google Cloud TCP 로드 밸런서의 백엔드 노드가 상태 검사에 모두 실패해 Netlify 전체 트래픽의 약 5%가 처리되지 않았다

Netlify는 DNS 영역을 Netlify DNS에 두지 않았거나 DNS 사업자가 CNAME flattening을 지원하지 않는 고객에게 A 레코드용 고정 IP를 주고, 이 IP는 Google Cloud TCP 로드 밸런서로 이어진다. 이 로드 밸런서는 Direct Server Return 방식으로 응답하므로 백엔드 노드가 로드 밸런서 IP를 출발지 IP로 써서 응답할 수 있어야 한다. GCP 기본 이미지에 든 google-guest-agent가 노드마다 로드 밸런서 IP를 로컬 라우팅 테이블에 넣는다. Netlify는 OS 보안 패치를 OS의 자동 업데이트로 받고, 운영에서는 업데이트 시각을 노드마다 무작위로 흩어 둔다.

2021-03-25에 자동 업데이트가 systemd-networkd를 재시작하면서 로드 밸런서 IP 항목이 라우팅 테이블에서 지워졌다. google-guest-agent의 systemd 설정은 여러 네트워크 관리 유닛의 재시작을 감시해 IP를 다시 넣지만 systemd-networkd는 감시하지 않았다. 업데이트가 노드마다 돌면서 몇 시간에 걸쳐 백엔드가 하나씩 로드 밸런서 상태 검사에 실패했고, Netlify 자체 검사는 백엔드의 자체 IP로 붙어 정상이라고 했다. 14:39 UTC에 마지막 백엔드까지 빠지자 전체 트래픽의 약 5%가 처리되지 않았다.

같은 리전에서 동시에 난 클라우드 사업자의 L4 로드 밸런서 장애 때문에 팀은 처음에 사업자 장애를 원인으로 봤다. 사업자의 해결이 오래 걸릴 것으로 보고 Google의 global TCP proxy를 검토했지만 TCP 80번 포트를 지원하지 않아 쓰지 않았다. 대신 로드맵에 있던 로드 밸런서 분리를 앞당겨 15:30 UTC에 엔터프라이즈 고객용 IP를, 16:46 UTC에 AWS의 Global Accelerator 기반 네트워크 로드 밸런서 IP를 셀프 서비스 고객에게 내놓았다. 18:38 UTC에 Google 지원팀이 준 정보로 백엔드 노드의 가상 IP 문제를 짚었고, 18:46 UTC에 영향을 받은 모든 노드에서 GCP 네트워킹 데몬을 재시작해 Google 로드 밸런서의 남은 트래픽을 모두 되살렸다.

심각도
–
영향 범위
Sites reached through the static IP of the Google Cloud TCP load balancer used for A records: about 5% of Netlify's global traffic was not served
영향 사용자
a portion of Netlify customers, those using the static A-record IP
지역
–
감지까지
0m
복구까지
4h 7m

증상

2021-03-25 14:39 UTC에 모니터가 로드 밸런서 상태 검사 실패를 알렸다. 고정 IP로 A 레코드를 거는 고객이 쓰는 Google Cloud TCP 로드 밸런서에서 전체 트래픽의 약 5%가 처리되지 않았고, 18:46 UTC까지 이어졌다.

상태 검사는 두 종류였다. 로드 밸런서 IP로 백엔드 노드에 붙는 검사는 실패했지만, 각 백엔드에 직접 붙는 노드 단위 검사는 장애 내내 백엔드가 정상이라고 했다. GCP 콘솔에서는 백엔드 노드들이 로드 밸런서의 상태 검사에 실패하는 것이 보였지만 더 자세한 진단 정보는 없었다.

장애 몇 시간 전부터 노드마다 OS의 자동 업데이트가 돌 때마다 그 노드가 로드 밸런서의 상태 검사에 실패했고, 로드 밸런서는 그 노드로 트래픽을 보내지 않았다. 활성 노드가 하나라도 남아 용량이 충분한 동안은 트래픽이 처리됐다. 마지막 백엔드에서 systemd-networkd가 재시작되자 고객 요청이 버려지기 시작했다.

14:48 UTC에 네트워크 사업자 상태 페이지에 us-west1-c의 L4 로드 밸런서에 문제가 있다는 배너가 떴다. Netlify의 로드 밸런서는 영역이 아니라 리전 단위였지만, 다른 정보가 없어 사업자 장애가 원인이라고 보고 그 영향을 먼저 조사했다. 이 사업자 장애는 나중에 관련이 없는 것으로 밝혀졌고, 그 때문에 해결이 늦어졌다.

증상 프로브 실패오류율 상승

원인

촉발
OS의 자동 업데이트가 백엔드 노드의 systemd-networkd 유닛을 재시작해 로컬 라우팅 테이블에 넣어 둔 로드 밸런서 IP 항목을 지웠다. google-guest-agent는 systemd-networkd 재시작을 감시하지 않아 그 IP를 다시 넣지 않았다.

감지

14:39 UTC에 모니터가 로드 밸런서 상태 검사 실패를 알렸다. 백엔드에 직접 붙는 노드 단위 상태 검사는 장애 내내 정상이라고 했고, 로드 밸런서의 백엔드 상태 검사는 알림에 들어 있지 않아 노드가 하나씩 빠지던 몇 시간 동안 알림이 없었다.

조치

후속 조치

교훈

Netlify는 자사 같은 서비스를 쓸 때 IP 기반 A 레코드에 기대지 말라고 권하지만, 많은 DNS 사업자에서는 A 레코드가 유일한 방법이다. 노드 단위 상태 검사는 백엔드의 자체 IP로 붙었기 때문에 로드 밸런서 IP가 빠진 것을 잡지 못했고, 로드 밸런서의 백엔드 상태 검사를 알림으로 받았다면 장애 전에 진단할 시간을 더 벌었을 것이다.

출처

관련 사례

내 클러스터에도 있는지 확인하기

kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이 사례와 같은 상태를 점검합니다. 이 사례의 구성 요소: 클라우드 로드 밸런서, systemd-networkd. 점검 항목의 근거는 이 사례 같은 공개 보고서입니다.

AI 도구와 스크립트용

API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.