IL-0049 Preply · 2020-02-28kubernetesnetworking
2020년 2월 28일 Preply 의 쿠버네티스 클러스터에서 일부 서비스의 DNS 가 26분 동안 부분적으로 멈췄다. 서비스 A, B, C 에서 이벤트 15000건이 유실됐다.
클러스터 부하가 낮아지자 CoreDNS-autoscaler 가 CoreDNS 파드를 3개에서 2개로 줄였다. 이때 kube-proxy 가 conntrack 테이블에서 사라진 CoreDNS 파드로 가는 옛 항목을 지우지 못했다. conntrack 은 리눅스 커널이 NAT 기록을 테이블에 담아 두는 기능이다. 커널은 같은 출발지 파드에서 같은 목적지로 가는 다음 패킷을 CPU 를 아끼려고 다시 변환하지 않고, 이 테이블에서 목적지 주소를 가져온다. 그래서 일부 서비스의 DNS 요청이 이미 없어진 파드로 계속 갔다.
당직 엔지니어들은 22시 39분에 서비스의 최신 릴리스를 되돌렸고, 22시 40분에 5xx 오류가 사라졌다. 포스트모템은 해결 경위를 이렇게 적었다. 클러스터의 정기 배포가 새 노드를 만들었고, CoreDNS-autoscaler 가 다시 파드를 늘리면서 conntrack 테이블이 자동으로 새로 쓰였다. 감지까지 4분, 대응 착수까지 21분, 해결까지 1분이 걸렸다.
팀은 진짜 근본 원인을 아직 모른다고 밝혔다. conntrack 의 특정 버그로 보인다고 했다. 운이 좋았던 점도 두 가지 적었다. 다른 배포가 우연히 CoreDNS-autoscaler 를 움직여 conntrack 테이블이 새로 쓰인 것, 그리고 장애가 모든 서비스로 번지지 않은 것이다.
Prometheus 모니터링이 서비스 A, B, C 에서 5xx 비율이 높아진 것을 잡아 당직자를 호출했다. 당직 엔지니어들은 22시 18분부터 VictorOps 호출을 받기 시작했다. Kibana 에서도 5xx 비율이 올라간 것이 보였다.
그보다 5분 앞선 22시 13분에 CoreDNS-autoscaler 가 CoreDNS 파드를 3개에서 2개로 줄였다. CoreDNS 로그에는 다음 줄이 남았다. I0228 20:13:53.507780 1 event.go:221] Event(v1.ObjectReference{Kind:"Deployment", Namespace:"kube-system", Name:"coredns", UID:"2493eb55-3dc0-11ea-b3a2-02bb48f8c230", APIVersion:"apps/v1", ResourceVersion:"132690686", FieldPath:""}): type: 'Normal' reason: 'ScalingReplicaSet' Scaled down replica set coredns-6cbb6646c9 to 2
같은 시각 kube-proxy 는 conntrack 항목을 지우지 못했다는 오류를 남겼다. E0228 20:13:53.795782 1 proxier.go:610] Failed to delete kube-system/kube-dns:dns endpoint connections, error: error deleting conntrack entries for UDP peer {100.64.0.10, 100.110.33.231}, error: conntrack command returned: ...
당직 엔지니어들은 22시 21분에 원인 조사를 시작했다. 22시 39분에 해당 서비스의 최신 릴리스를 되돌렸고, 22시 40분에 5xx 오류가 사라지며 상황이 안정됐다. 장애는 모든 서비스가 아니라 일부 서비스에만 나타났다.
원인 DNS·네트워크 장애
Prometheus 모니터링이 서비스 A, B, C 에서 5xx 비율이 높아진 것을 잡아 VictorOps 로 당직자를 호출했다. 포스트모템이 적은 감지 시간은 4분이다.
모니터링은 장애를 빨리 잡았고 대응도 빠르고 체계적이었다. 노드는 어떤 한도에도 닿지 않았다.
진짜 근본 원인은 아직 모른다. conntrack 의 특정 버그로 보인다. 팀이 정한 후속 조치는 모두 장애가 낳는 결과를 막는 것이지 근본 원인을 고치는 것이 아니다.
팀은 DNS 에서 문제가 날 수 있다는 것을 알고 있었지만 이 일을 우선해서 다루지 않았다.
IL-0178 EKS 에서 HPA 가 파드를 줄일 때 엔드포인트 제거보다 컨테이너 종료가 먼저 끝나 502 가 났고, 블루/그린 전환 뒤에는 conntrack 에 남은 연결이 삭제된 파드로 가서 클라이언트가 타임아웃을 받았다.Lotte E-commerce · 2022같은 원인 · 공통 conntrack 테이블, kube-proxy
IL-0083 멀티 테넌트 쿠버네티스 클러스터에서 노드 로컬 dnsmasq 가 동시 질의 한도에 걸리고 cluster.local 응답을 캐시하지 못한 데다 ndots 검색 도메인 질의가 CoreDNS 로 몰려, 서비스 간 호출이 간헐적인 5xx 를 냈다.Adevinta · 2023같은 원인 · 공통 CoreDNS
IL-0057 EKS 노드의 SNAT 과정에서 conntrack 경합으로 바깥으로 나가는 TCP 연결이 1초나 3초씩 늦어져, 서비스 간 호출이 많은 서비스의 p99 지연이 늘었다.Prezi · 2019같은 원인 · 공통 conntrack 테이블
같은 원인 · 공통 conntrack 테이블
https://incidentlib-mcp.benchlet.com/mcpAPI 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.