Where the four minutes go when a cluster adds a node
클러스터에 노드를 추가할 때 사라지는 4분
DigitalOcean Kubernetes에서 부하가 급증한 뒤 새 파드가 요청을 처리하기까지 걸리는 시간을 단계별로 측정했습니다. 노드 여유 공간이 있으면 중앙값 46초, 새 노드가 필요하면 249초가 걸렸으며, 예비 노드를 두면 대기 시간을 1분 미만으로 줄였습니다.
- 주제
AI 요약
오토스케일링은 켜고 나면 부하를 알아서 처리하는 기능처럼 설명되곤 합니다. 하지만 새 파드나 노드가 실제 요청을 맡기까지 어디서 시간이 걸리는지는 잘 드러나지 않습니다. 글쓴이는 DigitalOcean Kubernetes 1.36.3에서 CPU 부하를 받는 파드 하나를 띄우고, 부하 시작부터 추가 파드가 요청을 처리할 때까지 단계별 시간을 기록했습니다. 노드 풀은 2~5개 노드로 설정했고, 측정은 여덟 차례 반복했습니다.
노드에 여유 공간이 있을 때
첫 번째 오토스케일러 판단까지 중앙값 28초, 첫 추가 파드가 준비되기까지 30초가 걸렸습니다. 파드 생성 후 준비 완료까지는 1~3초였고, 스케줄링도 즉시 끝났습니다. 따라서 대기 시간 대부분은 파드 시작이 아니라 CPU 지표를 수집하고 오토스케일러가 판단하기까지의 지연입니다. kubelet이 CPU를 측정하고, metrics-server가 kubelet에서 지표를 가져오며, 오토스케일러가 다시 metrics-server를 확인하는 과정이 각자 주기로 반복됩니다.
첫 판단만으로 필요한 파드 수를 채우지도 못했습니다. 여덟 차례 모두 오토스케일러가 두 번 판단했습니다. 첫 지표는 측정 창에 얼마나 부하가 쌓였는지에 따라 CPU 사용률 55~249%로 달랐습니다. 처음에는 파드를 3~4개로 늘린 뒤, 다음 주기에 부하가 여전히 높다고 확인하고 나머지를 추가했습니다. 다섯 파드가 모두 준비되기까지 중앙값 46초가 걸렸습니다.
새 노드가 필요할 때
노드 두 개를 테스트용 파드로 채워 여유 CPU를 거의 없앤 뒤 네 차례 측정했습니다. 새 파드 생성부터 첫 파드가 요청을 처리하기까지 중앙값은 249초, 약 4분 9초였습니다. 이 중 오토스케일러가 노드를 요청한 뒤 노드가 클러스터에 등록되기까지 120초가 걸렸습니다. 네 번의 측정 범위가 117~123초로 좁았습니다.
나머지 시간도 여러 단계에 나뉘었습니다. 파드가 Pending 상태가 된 뒤 노드 요청까지 17초, 노드 등록 뒤 Ready 상태까지 36초, 노드가 Ready가 된 뒤 파드가 스케줄링되기까지 29초가 걸렸습니다. 새 노드에는 이미지가 캐시되어 있지 않아 164MB 이미지를 내려받는 데도 18~22초가 들었습니다. 글쓴이는 Ready 상태 이후 스케줄링까지 걸린 약 29초의 이유를 확인하지 못했지만, 측정마다 비슷하게 나타났다고 설명합니다.
예비 노드로 대기 줄이기
글쓴이는 노드 한 대 분량의 CPU를 요청하는 낮은 우선순위 파드를 미리 띄우는 오버프로비저닝(overprovisioning)도 시험했습니다. 실제 파드가 도착하면 예비 파드가 축출되고, 예비 파드는 새 노드 증설을 유도합니다. 세 차례 시험에서 첫 새 파드는 부하 시작 뒤 47초, 49초, 75초에 준비됐습니다. 애플리케이션 파드가 모두 예비 노드에 올라 새 노드를 기다릴 필요가 없었습니다. 대신 예비 공간을 복구할 새 노드는 239~383초 뒤에 준비됐습니다. 대기 시간은 4분에서 1분 미만으로 줄었지만, 상시 유휴 노드 한 대를 유지하는 비용이 듭니다.
측정에서 확인한 함정
초기에는 부하가 없는데도 애플리케이션 CPU 사용률이 92%로 나타나 오토스케일러가 파드를 다섯 개까지 늘렸습니다. 초당 한 번 실행하는 HTTP 준비 상태 검사(readiness probe)가 부하 테스트와 같은 페이지를 호출하면서 CPU를 소모한 탓입니다. 글쓴이는 검사를 TCP 방식으로 바꿨습니다. 또 이전 부하의 지표가 metrics-server 측정 창에 남아 다음 시험을 오염시키는 문제를 확인해, 측정 창이 지나간 뒤 오토스케일러를 만들고 파드가 하나일 때만 시험을 시작하도록 수정했습니다.
부하 생성 도구 fortio도 예열 요청이 3초 넘게 걸리면 조용히 종료했습니다. 과부하 상태에서 실제 부하가 발생하지 않았는데도 스크립트가 시간을 기록한 시험은 무효였습니다. 글쓴이는 노드가 이미 있고 이미지가 캐시된 경우에도 약 30초가 기본 대기 시간이며, 새 노드가 필요하면 분 단위 지연을 예상해야 한다고 정리합니다. 다만 시험은 노드 네 대 증설 조건에서 네 차례, 예비 노드 조건에서 세 차례뿐입니다. 한 이미지와 노드 사양, 한 지역에서 기본 설정으로 진행했으므로 각자의 클러스터에서 직접 측정해야 한다고 덧붙입니다.
dev.to 반응
- @max_quimby — “대충 1분”이라고 되풀이하는 대신 실제로 시간을 쟀다는 점이 좋습니다. 처음 30초 중 약 28초가 파드 시작이 아니라 폴링 루프(kubelet 측정 → metrics-server 수집 → 오토스케일러 확인) 지연이라는 결과는 많은 사람이 거꾸로 생각하는 부분입니다. 파드 부팅 시간을 조정하면서도 훨씬 큰 비중을 차지하는 감지 과정을 놓치곤 합니다. 계산량이 많은 작업에서 새 노드를 쓰는 4분짜리 경우가 흥미롭습니다. hpa-example 이미지는 노드에 이미 있어서 이미지 다운로드가 거의 공짜였지만, 수 GB짜리 CUDA 기반 이미지나 모델 가중치를 포함한 이미지라면 새 노드에서 다운로드가 가장 오래 걸릴 수 있습니다. 그 경우에는 미리 이미지 풀을 받아 두거나 웜 풀을 운영하는 방법이 성급한 최적화가 아닙니다. 감지와 노드 증설 지연을 줄이는 전형적인 방법은 우선순위가 낮은 pause 파드로 노드 여유 공간을 확보하는 오버프로비저닝입니다. 실제 작업이 오면 이 파드가 즉시 축출되므로, 가장 필요한 순간에 느린 경로를 기다리는 대신 평소에 그 비용을 냅니다. 오토스케일러가 두 차례에 걸쳐 파드를 늘리는 현상은 매번 재현됐나요, 아니면 부하가 지표 측정 창의 어느 시점에 시작됐는지에 따라 달라졌나요?”
원문: dev.to / 번역·요약: Trawling