IL-0011 Skyscanner · 2019-04-23 (게시일)kubernetesnetworking
Skyscanner 는 오픈소스 HAProxy 인그레스 컨트롤러를 데몬셋으로 노드마다 띄운다. 가장 큰 클러스터에서는 인스턴스가 80개쯤이고, 앞단 ELB 가 이들에게 고르게 부하를 나눈다. 컨트롤러는 쿠버네티스 API 서버를 지켜보다가 템플릿과 Go 의 text/template 라이브러리로 HAProxy 설정을 만들고 HAProxy 를 리로드한다. 무중단 리로드가 안 되면 HAProxy 프로세스를 재시작하고, 라운드 로빈은 서버 목록의 처음부터 다시 시작한다.
v0.3 을 쓰던 때 백엔드 서버 목록이 정렬돼 있어 hot-podding 이 생겼다. 팀은 모든 서비스에 기본 어노테이션을 달아 파드 IP 대신 Service VIP 를 쓰게 하는 임시 우회책을 두었다. 부하 분산은 쿠버네티스가 맡았지만, HAProxy 는 개별 파드를 비정상으로 표시할 수 없게 됐다.
v0.5 문서에 sort-backends 플래그가 생기고 기본 동작이 무작위 섞기라고 나오자, 팀은 코드를 읽고 짧게 테스트한 뒤 v0.6 으로 올렸다. 부하 테스트는 변화가 적은 클러스터에서 해서, 운영 클러스터처럼 설정이 자주 다시 쓰이고 HAProxy 가 재시작되는 상황을 놓쳤다. Go 의 range 는 맵을 순회할 때 순서를 보장하지 않지만, text/template 은 키가 순서를 정할 수 있는 기본 타입이면 정렬된 키 순서로 방문한다. 그래서 Go 코드에서 섞어 둔 순서가 템플릿 단계에서 다시 IP 순으로 정렬됐다.
팀은 맵에 넣은 순서를 슬라이스에 따로 보관하고, 템플릿이 그 슬라이스를 순회하며 맵에서 값을 찾도록 컨트롤러를 고쳤다. 패치를 배포하자 요청 분포가 고르게 돌아왔다. 업스트림 프로젝트에 이슈와 PR 을 올렸고, 메인테이너는 다른 방식의 수정을 다음 릴리스에 넣었다.
어느 일요일, 클러스터 사용자 한 명이 지연 시간이 올라갔다며 쿠버네티스 업무 시간 외 지원 담당을 직접 호출했다. 특히 p90 과 최댓값 지연이 높았다.
함께 파고들고 몇 번 헛짚은 끝에, 일부 파드의 요청 큐가 가득 차서 요청을 더 받지 않는다는 것을 찾았다. Prometheus 쿼리를 더 돌려 보니 원인은 백엔드 목록이 정렬돼 생긴 hot-podding 이었다. hot-podding 은 일부 파드가 다른 파드보다 늘 더 많은 요청을 받는 현상을 팀이 부르는 이름이다.
실패는 연쇄로 번졌다. 큐가 찬 파드는 스스로를 unready 로 표시했고, 백엔드 서버 목록에서 빠지면서 설정 리로드가 일어났다. 그러면 목록에서 그다음 파드에 부하가 몰렸다. 인그레스 컨테이너 일부는 요청이 너무 몰려 OOMKilled 됐고, 남은 컨테이너의 부담은 더 커졌다.
신호는 그 전에도 있었다. 인그레스 컨트롤러를 v0.6 으로 올린 뒤 한 사용자가 파드 사이 요청 분포가 이상하다고 알려 왔다. 팀은 테스트와 코드 검토 결과를 믿었고, 한 개발 팀만 보고한 현상이라 우선순위를 낮게 두었다.
클러스터 사용자가 p90 과 최댓값 지연이 오른 것을 보고 업무 시간 외 쿠버네티스 지원 담당을 직접 호출했다. 그 전에도 한 사용자가 파드 사이 요청 분포가 고르지 않다고 알렸지만 팀은 우선순위를 낮게 두었다.
클러스터 컴포넌트를 바꿀 때는 특정 동작과 조건을 염두에 두고 테스트해야 한다. 팀은 백엔드 목록이 정렬되면 hot-podding 이 생긴다는 것을 이미 알았지만, 새 플래그가 기대대로 동작하는지 충분히 테스트하지 않았다. 같은 키워드라도 언어의 한 곳에서 동작하는 방식이 다른 곳에서도 같으리라고 기대하면 안 된다. Go 의 range 와 text/template 의 range 는 맵을 순회하는 순서가 달랐다. 쿠버네티스 클러스터의 작은 컴포넌트 하나만 바꿔도 클러스터 사용자와 고객에게 큰 피해를 줄 수 있다.
IL-0053 Ingress NGINX Controller의 어드미션 웹훅이 인증 없이 열려 있어, 조작한 Ingress 객체로 NGINX 설정을 주입해 원격 코드를 실행하고 클러스터의 모든 Secret을 읽을 수 있었다Wiz · 2025같은 원인 · 공통 인그레스 컨트롤러
IL-0081 ingress-nginx 의 enable-serial-reloads 옵션이 NGINX 리로드 중에 엔드포인트 동적 갱신을 막아, 배포 중 트래픽이 이미 없는 파드로 가면서 API 요청이 타임아웃됐다.Cresta · 2025같은 원인 · 공통 인그레스 컨트롤러
IL-0106 잘못된 IngressRoute 매니페스트가 Traefik v2 버그를 건드려 Traefik 파드가 모두 재시작된 뒤 Kubernetes 의 모든 서비스가 404 를 냈다DFDS · 2021같은 원인 · 공통 인그레스 컨트롤러
같은 원인 · 공통 인그레스 컨트롤러
IL-0072 etcd 쓰기 지연으로 API 서버가 오래된 데이터를 읽어 클러스터 상태가 두 가지로 번갈아 보였고, 주 운영 클러스터 전체가 약 4시간 멈췄다Nordstrom · 2017같은 원인 · 공통 인그레스 컨트롤러
https://incidentlib-mcp.benchlet.com/mcpAPI 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.