IL-0517 Gitpod · 2022-01-25kubernetesgcpnetworking
Gitpod 워크스페이스 클러스터의 CoreDNS 가 상위 DNS 서버에 닿지 못해 워크스페이스가 시작되지 않고 일부 데이터가 사라졌다
2022년 1월 25일 Gitpod 에 전 세계 장애가 났다. 5.44pm UTC 쯤 Google Container Registry 에서 이미지를 받을 때 cannot get manifest 오류가 많이 났고, 약 10분 뒤 사용자들이 워크스페이스를 시작할 수 없다고 보고해 당번 팀이 장애 대응을 시작했다. 원인은 워크스페이스 클러스터 안의 DNS 장애였다. 클러스터는 공개 주소를 Google 의 기본 DNS 서버 8.8.8.8 로 풀었는데, 이 서버와 통신하지 못했고 UDP 53 트래픽이 통과하지 못해 타임아웃이 났다. CoreDNS 파드 로그에는 8.8.8.8:53 으로 가는 요청의 i/o timeout 이 쌓였다.
워크스페이스 내용의 백업은 비공개 Google Cloud Storage 버킷에 올라간다. 백업 서비스가 DNS 장애로 GCS 주소를 풀지 못해 백업이 실패했고, 이미 돌던 워크스페이스의 데이터가 사라졌다. 사용자 데이터인 /workspace 는 워크스페이스 클러스터의 각 노드에 저장되므로, 백업이 끝나기 전에 노드나 클러스터가 실패하면 데이터를 잃는다.
조사하는 동안 팀은 예방 조치로 werft 작업을 돌려 EU 와 US 에 새 워크스페이스 클러스터를 만들었다. 약 20분 걸려 준비된 새 클러스터에는 문제가 없었고, 트래픽을 새 클러스터로 돌리자 곧 워크스페이스가 시작됐다. 장애는 한 시간 남짓 이어졌다. 트래픽이 빠진 옛 클러스터는 곧 회복해 어떤 부하 문제로 보였지만, ARP 테이블과 conntrack 테이블은 정상이었다. 팀은 나중에 시간 압박 없이 재현해 보려 했으나 재현하지 못했다. Gitpod 는 유료 사용자에게 지난 석 달 치 환불을, 무료 사용자에게 unleashed 요금제 3개월 쿠폰을 제공했다.
- 심각도
- –
- 영향 범위
- Workspaces could not be started, and running workspaces lost data
- 영향 사용자
- –
- 지역
- global
- 감지까지
- –
- 복구까지
- 1h
증상
5.44pm UTC 쯤 Google Container Registry 에서 이미지를 받을 때 cannot get manifest 오류가 많이 났다. 약 10분 뒤 사용자들이 워크스페이스를 시작할 수 없다고 보고했고, 이미 돌던 워크스페이스는 데이터를 잃었다.
로그에는 이미지를 받으려다 난 dial tcp: i/o timeout failed to do request 오류도 있어서 GCR 과의 연결 문제로 보였다. 그 뒤 CoreDNS 파드에서 [ERROR] plugin/errors: 2 storage.googleapis.com. A: read udp 192.168.60.206:55169->8.8.8.8:53: i/o timeout 같은 DNS 오류가 많이 나온 것을 찾았다. UDP 53 포트로 가는 트래픽이 아예 통과하지 못하는 것처럼 보였다.
팀은 먼저 Google 서비스 장애를 의심해 Google 상태 페이지를 봤다. 올라와 있던 것은 Service Usage API 가 "available services" 나 "disabled services" 목록 조회에서 오류율이 높다는 알림 하나뿐이었고, GCR 과 관계없어 보여 문제가 Gitpod 쪽에 있다고 판단했다. 다시 DNS 와 상태 페이지를 확인했지만 오류는 없었고, 클러스터에 최근 바꾼 것도 없었다.
ARP 테이블이 넘쳤는지 확인했지만 장애 전, 중, 후 모두 정상 범위였다. conntrack 테이블도 확인했지만 사용률은 약 10% 였다.
원인
원인 DNS·네트워크 장애
- 촉발
- –
감지
5.44pm UTC 쯤 팀이 GCR 에서 이미지를 받을 때 cannot get manifest 오류율이 높아진 것을 알아챘다. 약 10분 뒤 사용자들이 워크스페이스를 시작할 수 없다고 보고했고, 당번 팀이 장애 대응을 시작했다.
조치
- GCR 연결 문제를 조사하는 동안 예방 조치로 werft 작업을 돌려 EU 와 US 에 새 워크스페이스 클러스터를 만들기 시작했다. 만드는 데 약 20분 걸렸다.
- 새 클러스터에 문제가 없음을 확인하고 트래픽을 새 클러스터로 돌렸다. 곧 워크스페이스가 시작됐고 사용자들이 Discord 에서 시작된다고 알려 왔다.
후속 조치
- 노드와 클러스터가 실패해도 남는 클라우드 사업자의 영구 볼륨에 사용자 데이터를 저장한다.
- 워크스페이스가 시작할 수 없는 상태가 되어도 사용자가 파일을 내려받을 수 있게 한다. 지금은 워크스페이스가 멈춰 있을 때만 내려받을 수 있다.
- 백업 절차 개선을 우선으로 진행한다.
- DNS 서버 하나에 기대지 않고 GCP 내부 DNS, Google 의 공개 DNS 8.8.8.8, Cloudflare 의 1.1.1.1 세 곳을 쓰도록 바꿨다. 하나에 문제가 나도 나머지에 연결할 수 있다.
- DNS 복원력을 높이는 작업을 더 진행한다.
- 여러 리전의 클러스터 지원을 늘린다. 지금은 US 와 EU 두 곳뿐이고, 나중에는 여러 클라우드를 쓰는 것도 계획한다.
교훈
–
출처
관련 사례
IL-0083멀티 테넌트 쿠버네티스 클러스터에서 노드 로컬 dnsmasq 가 동시 질의 한도에 걸리고 cluster.local 응답을 캐시하지 못한 데다 ndots 검색 도메인 질의가 CoreDNS 로 몰려, 서비스 간 호출이 간헐적인 5xx 를 냈다.Adevinta · 2023같은 원인 · 공통 CoreDNS
IL-0199운영에 꼭 필요하지 않은 컨테이너가 메모리 한도를 넘어 파드가 사용 불가로 표시됐고, DNS 작업 탓에 레지스트리에 접속하지 못해 파드가 다시 뜨지 못하면서 GitHub.com 이 4시간 넘게 멈췄다.GitHub · 2020같은 원인 · 공통 컨테이너 레지스트리와 자격 증명
IL-0049CoreDNS 파드가 줄어든 뒤 kube-proxy 가 conntrack 항목을 지우지 못해 일부 서비스의 DNS 요청이 없어진 파드로 가면서 5xx 가 쏟아졌다Preply · 2020같은 원인 · 공통 CoreDNS
내 클러스터에도 있는지 확인하기
AI 도구와 스크립트용
- 이 사례의 JSON: https://incidentlib-api.benchlet.com/cases/IL-0517
- 가장 비슷한 사례들: https://incidentlib-api.benchlet.com/cases/IL-0517/similar
- MCP 서버(Streamable HTTP, 키 없음):
https://incidentlib-mcp.benchlet.com/mcp
API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.