SRE 54

Loki 스트림 폭발로 새벽 3시에 알람 받은 날

지난주 금요일 새벽 3시, 폰이 미친 듯이 울렸다. LokiIngesterMemoryHigh 알람. 눈이 번쩍 떠졌다.솔직히 이 알람이 처음 뜬 건 아니었다. 근데 그날은 좀 달랐다. ingester 파드 12개 중 4개가 OOMKilled로 계속 재시작 중이었고, 그 사이에 유입되던 로그는 500 에러 뱉으면서 다 흘려 보내고 있었다. 팀 슬랙에 사고 채널 만들고 노트북 열었을 땐 이미 5분치 로그가 유실된 상태였다.원인은 결국 stream 카디널리티Loki 운영해본 사람은 알겠지만, "카디널리티"는 반쯤 저주 같은 단어다. 라벨 하나 잘못 붙이면 몇 시간 뒤에 클러스터가 죽는다. 우리 팀도 그걸 알고 있었고, 그래서 애초에 라벨 조합을 5~6개로 제한하는 룰이 있었다.문제는 그 룰이 깨진 게 아니었다..

IT/모니터링 15:10:42

HPA 진동 잡느라 이틀 태운 이야기

지난주 화요일 새벽 2시쯤이었나. 알림이 울렸다. 특정 서비스의 P99 레이턴시가 800ms를 넘긴다는 알람이었다. 노드 16대짜리 프로덕션 클러스터에서, 특정 결제 API 파드가 30초 간격으로 8개에서 22개, 다시 10개, 또 25개... 이런 식으로 계속 오르락내리락 하고 있었다.솔직히 처음엔 트래픽 스파이크인 줄 알았다. 근데 그라파나 대시보드를 열어보니 그건 아니었다. RPS는 완만하게 오르는 중이었다. 그런데 파드 수가 미친 듯이 진동하고 있었다. 이게 바로 HPA flapping이다. 이론으로만 알던 걸 새벽 2시에 만나게 되니 정말 반가웠다(반갑지 않았다).처음엔 임계값을 만졌다가장 먼저 시도한 건 CPU targetAverageUtilization을 60에서 75로 올린 것이었다. "임..

IT/Kubernets 2026.08.26

SLO burn rate 알림 튜닝하다가 새벽에 두 번 깨진 이야기

지난달 얘기다. 우리 팀 결제 API에 SLO를 새로 걸었고, burn rate 알림도 같이 설정했다. Google SRE 워크북에 나온 그 유명한 멀티 윈도우, 멀티 burn rate 알림 말이다. 문서 그대로 따라 붙였으니 잘 돌 줄 알았는데, 첫 주에만 새벽에 두 번 깨졌다. 둘 다 진짜 장애는 아니었다.처음 걸었던 설정우리 SLO는 30일 창(window) 기준 가용성 99.9%다. 워크북에서 권장하는 대로 두 개 알림을 걸었다.- alert: HighErrorBudgetBurnFast expr: | ( job:slo_errors_ratio:rate1h{job="payment-api"} > (14.4 * 0.001) and job:slo_errors_ratio:r..

IT/SRE 2026.08.24

CronJob startingDeadlineSeconds 잘못 만졌다가 새벽 배치가 3일간 안 돌던 이야기

지난주 화요일 오전 10시쯤, 데이터팀 슬랙에 핑이 왔다. "혹시 정산 배치 어제도 안 돈 것 같은데, 뭐 바뀐 거 있어요?" 처음엔 별 생각 없이 로그부터 봤다. 어제, 그저께, 그그저께. 세 번 다 스케줄 시각에 Job이 아예 생성되지 않은 상태였다. Pod가 실패한 게 아니라 Job 자체가 없었다. 이거 뭐지, 하는 마음으로 CronJob describe를 걸었다.문제 상황문제의 CronJob은 매일 새벽 3시에 도는 정산 집계 배치였다. schedule은 0 3 * * *, concurrencyPolicy는 Forbid. 원래 잘 돌던 놈이었는데, 일주일쯤 전에 내가 매니페스트를 손댔다. 이유는 이랬다.기존 설정은 startingDeadlineSeconds가 없었다. 배치가 오래 걸리는 날에 다음..

IT/Kubernets 2026.08.23

kube-scheduler Preemption 내부 동작, 왜 내 PriorityClass는 예상대로 안 미나

작년쯤부터 팀 클러스터에 PriorityClass를 슬금슬금 붙이기 시작했다. 배치 잡이 야간 스케줄러를 물고 늘어져서 온라인 워크로드가 스케줄이 안 되는 일이 종종 생겼고, 그때마다 "그냥 우선순위 붙이면 되지 않나?" 하는 이야기가 나왔다. 문서 그대로 priority: 1000000 짜리 클래스를 만들고 붙였는데, 실제로 클러스터가 밀릴 만한 상황이 왔을 때 예상대로 안 밀린 경우가 몇 번 있었다. 그래서 kube-scheduler의 preemption 코드를 찬찬히 뜯어봤고, 그 과정에서 "아, 이래서 이게 안 됐구나" 싶은 지점이 몇 개 나왔다. 오늘은 그 내용을 정리해보려고 한다.이 글은 사용법이 아니라 안쪽 이야기다. Preemption이 어떤 순서로, 어떤 기준으로 pod들을 죽일 후보로 ..

IT/Kubernets 2026.08.19

CoreDNS NXDOMAIN 캐시가 만든 30초 지옥, ndots:5의 그림자

CoreDNS NXDOMAIN 캐시가 만든 30초 지옥, ndots:5의 그림자지난주 화요일 새벽 4시쯤, 온콜 알림이 울렸다. checkout-service 의 외부 결제사 API 콜 P99 레이턴시가 갑자기 5초, 10초를 찍고 있었다. 눈이 번쩍 떠졌다. 결제 흐름이라 반쯤 정신이 나간 채로 노트북을 열었다.결론부터 말하면 범인은 CoreDNS의 NXDOMAIN 네거티브 캐시였다. 그런데 이게 그냥 캐시 문제가 아니라, ndots:5랑 얽혀서 아주 재미없게 터졌다. 몇 시간 동안 헤맨 이야기를 정리해둔다.처음엔 결제사 문제인 줄 알았다첫 반응은 당연히 "결제사 쪽에서 뭐 하나" 였다. 상태 페이지 열어봤다. 정상. 결제사 담당자한테 슬랙 DM 날렸다. "저희 쪽 아무 이슈 없는데요."그럼 우리 클러..

IT/기타 2026.08.19

PDB 잘못 걸어놓고 새벽 3시에 노드 드레인이 멈춘 이야기

지난주 화요일 새벽이었다. EKS 컨트롤 플레인 마이너 버전 업그레이드에 맞춰 노드 그룹 rolling 교체를 걸어놨는데, 새벽 3시쯤 슬랙에 "노드 3대가 30분째 SchedulingDisabled 상태로 안 빠진다"는 알림이 떴다. 새벽에 눈이 번쩍 떠졌다.원인은 결국 우리가 반년 전쯤 붙여둔 PodDisruptionBudget 이었다. 그런데 이게 왜 하필 이번 업그레이드에서 터졌는지, 어디서 계산이 어긋났는지를 정리해두려고 이 글을 쓴다.뭐가 문제였나우리 팀은 결제 관련 워크로드 몇 개에 minAvailable: 2 로 PDB를 걸어뒀다. 처음 붙일 때 replica가 4~5개였고, "최소 2개는 살아있어야 한다"는 서비스 팀 요구를 반영한 값이었다.문제는 그 사이에 트래픽 특성이 바뀌면서 몇몇 ..

IT/SRE 2026.08.16

In-place Pod Resize, GA는 됐지만 우리 팀은 아직 조심스럽게 쓴다 — 내부 동작과 함정

작년 12월 1.35에서 In-place Pod Resize가 드디어 GA로 승격됐다. KEP-1287, alpha가 1.27에서 붙었으니 거의 3년을 굴러 온 셈이다. 사내에서도 "이제 VPA를 Recreate 없이 돌릴 수 있는 거냐"는 얘기가 나왔고, 실제로 몇 개 워크로드에는 붙여봤다. 근데 붙여보고 나서 든 생각은, 스펙 문서만 보고 판단하기엔 내부 동작이 좀 미묘하다는 거였다.이 글은 우리 팀이 실제로 어떤 지점에서 걸렸고, 왜 GA인데도 아직 전 클러스터 롤아웃을 안 했는지에 대한 이야기다. 스펙 요약이 아니라 kubelet과 컨테이너 런타임 경계에서 실제로 무슨 일이 벌어지는지를 파고들어 본다.리사이즈 요청이 실제로 통과하는 경로kubectl로 파드 리소스를 patch하면, 그 요청은 po..

IT/Kubernets 2026.08.16

burn rate alert 튜닝하다 3주 삽질한 이야기

지난달 얘기다. SLO 도입한 지 반 년쯤 지났고, 이제 대시보드에 error budget 남은 % 뜨는 것도 익숙해질 무렵이었다. 그런데 정작 알림이 이상하게 울렸다. 새벽 2시에 페이지 오는데 실제로 보면 이미 회복돼 있고, 반대로 며칠에 걸쳐 조금씩 새는 장애는 누구도 눈치를 못 챘다. 팀 회고 때 한 명이 "우리 burn rate alert가 알림 역할을 못 하고 있는 것 같다"고 얘기했고, 그때부터 3주 동안 정말 여러 번 갈아엎었다.처음엔 그냥 5분 창이었다부끄러운 얘기지만, 처음 세팅한 알림은 "최근 5분 error rate가 SLO 임계값의 10배 넘으면 페이지" 정도였다. 이게 왜 문제인지는 세팅한 사람도 알고 있었을 텐데, 그냥 다들 바빠서 방치돼 있었다.문제는 두 가지였다.첫째, 트래..

IT/SRE 2026.08.14

cgroup v2 memory.high — Pod가 OOM 없이 느려지는 진짜 이유

프로덕션에서 이상한 장애 하나를 잡으려고 며칠을 썼다. Pod는 살아있고, kubelet 이벤트에도 OOMKilled가 없다. 근데 P99 응답시간이 300ms에서 갑자기 2초를 찍는다. HPA는 CPU 기반이라 안 뜨고, memory usage 그래프는 limit 근처에서 톱니처럼 움직인다. 뭔가 죽지는 않는데 계속 밀린다.원인은 cgroup v2의 memory.high였다. K8s 1.36에서 Memory QoS 기능이 안정화되면서 kubelet이 이걸 자동으로 세팅하는 노드가 늘었는데, 그 동작을 모르면 지금 우리 클러스터에서 겪는 이런 "OOM 없는 느려짐"의 원인을 짚기 어렵다. 사실 내부적으로 커널이 어떻게 스로틀링하는지 이해하고 나면 튜닝 포인트가 명확해진다.memory.max와 memory..

IT/Kubernets 2026.08.13