IL-0037 Datadog · 2019-05-23 (게시일)kubernetesgcpnetworking
Datadog 컴퓨트 팀이 "10 Ways to Shoot Yourself in the Foot with Kubernetes" 발표에서 소개한 장애다. Datadog은 수천 대 노드를 쿠버네티스로 운영했고, 가장 큰 클러스터는 약 2,000대, 보통 클러스터는 1,000대에서 1,500대였다. 버킷 권한을 바꾼 뒤 약 1,000대 노드에서 도는 DaemonSet이 크래시 루프에 빠졌다. imagePullPolicy가 Always로 설정돼 있어서 재시작할 때마다 이미지 풀이 일어났다.
이 리전의 이미지 레지스트리 트래픽은 모두 NAT 인스턴스 세 대를 거쳐 나갔다. 레지스트리는 IP 세 개에서 몰려오는 요청을 받아들일 수 없는 양으로 보고 속도 제한을 걸었다. 그 결과 리전의 모든 노드가 이미지를 받지 못했고, 새 파드와 작업이 시작되지 못했다.
팀은 문제의 NAT 인스턴스를 교체해 새 출발지 IP를 얻었고 레지스트리 트래픽은 정상으로 돌아왔다. 그런데 당시 Cloud SQL 데이터베이스는 프라이빗 VPC로 접근할 수 없어서 인터넷으로 접속하고 있었다. 출발지 IP가 바뀌자 이 핵심 데이터베이스를 쓰는 애플리케이션들의 연결이 끊겼다. 고정 IP를 관리하는 곳을 찾아 방화벽 규칙을 다시 설정하기까지 몇 시간이 걸렸다. 후속 조치로 latest 같은 유동 태그를 막는 어드미션 웹훅을 Deployment, StatefulSet, DaemonSet, Job, 파드에 걸었다. 하지만 파드는 사용자가 아니라 클러스터 안의 컨트롤 루프가 만든다. 그래서 노드가 죽어 파드를 재스케줄하거나 스케일 아웃할 때 새로 생기는 파드가 거부됐다. 팀은 웹훅을 워크로드 객체에만 걸도록 바꿨다. 모든 것이 정상으로 돌아온 것은 레지스트리 문제가 시작된 지 약 일주일 뒤였다.
사용자들이 작업이 시작되지 않는다고 알려 왔다. 평소에는 모니터링이 먼저 잡아내는 편이었지만 이번에는 사용자 보고가 먼저였다. 처음부터 이미지 풀과 관련된 흔적이 보였다.
클러스터 전체 파드 상태를 보니 이미지 풀 때문에 오류 상태에 있는 파드가 많았다. 이미 돌고 있던 애플리케이션은 영향을 받지 않았다. 이미지 풀 지표에서는 풀 횟수가 갑자기 크게 뛴 뒤 한동안 그 수준을 유지하다가 다시 한 번 크게 뛰는 모양이 보였다.
이미지 레지스트리의 응답을 확인하니 429가 많이 나오고 있었다. 레지스트리가 속도 제한을 걸었다는 뜻이었다. 이 시점에 팀은 이 리전의 어떤 노드도 레지스트리에서 이미지를 받지 못한다는 것을 알았다.
장애는 조치 과정에서 두 번 더 번졌다. NAT 인스턴스를 교체하자 인터넷으로 Cloud SQL 데이터베이스에 붙던 애플리케이션들의 연결이 끊겼다. 후속 조치로 넣은 어드미션 웹훅은 클러스터가 스스로 만드는 파드까지 거부해서, 클러스터에 새 파드를 하나도 스케줄할 수 없게 됐다.
사용자들이 작업이 시작되지 않는다고 알려 와서 알았다. 모니터링보다 사용자 보고가 먼저였다. 팀은 파드 상태, 이미지 풀 지표, 레지스트리 응답 코드를 차례로 확인해 429 속도 제한을 찾았다.
imagePullPolicy가 Always인 DaemonSet이 크래시 루프에 빠지면 노드 수만큼 이미지 풀이 반복된다. 레지스트리 트래픽이 NAT 몇 대로 모이면 출발지 IP 몇 개가 속도 제한에 걸려 리전 전체가 이미지를 받지 못한다. NAT를 바꾸면 그 IP를 허용해 둔 외부 서비스 연결도 함께 끊긴다. 파드에 거는 어드미션 웹훅은 사용자가 아니라 컨트롤러가 만드는 파드까지 막는다. 발표자들은 대규모 클러스터에서는 DaemonSet을 특히 조심하라고 했다. DaemonSet이 기대는 DNS, Vault, 이미지 저장소도 모두 망가뜨려 본 적이 있다고 했다. 수천 대 단위로 무언가를 다루면 그만큼 망가뜨리기 쉽다는 것이다. kubelet 아래에도 인프라가 있다는 것을 잊지 말라고도 했다.
같은 원인 · 공통 애플리케이션 데이터베이스
IL-0110 Grafana Agent 파드가 메모리를 많이 쓰던 노드에 Hangfire 파드가 함께 올라가 시스템 OOM 으로 CrashLoopBackOff 를 반복했고, 노드가 응답을 멈추고 NotReady 가 됐다.DFDS · 2024같은 원인 · 공통 애플리케이션 데이터베이스
IL-0202 갑자기 몰린 쿼리와 데이터베이스 쓰기로 Honeycomb 수집 호스트가 메모리 부족으로 죽었고, 쿠버네티스 CrashLoopBackOff 가 용량 회복을 막아 US1 이벤트 수집이 한 시간 넘게 불안정했다Honeycomb · 2023 · sev1같은 원인 · 공통 애플리케이션 데이터베이스
IL-0206 GKE 파드 안의 Consul 에이전트가 메모리 급증으로 거듭 OOM kill 되어 Rails 파드가 데이터베이스 복제본을 찾지 못했고, 모든 쿼리가 primary 로 몰려 GitLab.com 이 느려졌다.GitLab · 2022같은 원인 · 공통 애플리케이션 데이터베이스
IL-0064 CPU 를 많이 쓰는 파드가 Google Cloud 노드 하나에 몰려 노드가 커널 패닉으로 죽었고, 다시 배치된 파드가 다음 노드를 또 죽이며 웹사이트와 API 가 멈췄다.Moonlight · 2019같은 원인 · 공통 애플리케이션 데이터베이스
https://incidentlib-mcp.benchlet.com/mcpAPI 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.