넣고, 전부 걷어내고, 다시 넣었다

2026/08/12클라우드 인프라 구축·전환Kubernetes · Traefik · Sablier · ArgoCD

개발·스테이징 환경은 하루 대부분 아무도 안 씁니다. 그런데 파드는 계속 떠 있고, 계속 과금됩니다.

요청이 올 때 깨우고 안 오면 재우는 방식을 넣었습니다. 한 번 실패해서 전부 걷어냈고, 다시 넣었습니다.

첫 시도와 철회

동작은 이렇습니다. 라우팅 계층에 미들웨어를 두고, 요청이 오면 워크로드를 깨우고 준비될 때까지 붙들었다가 넘깁니다. 일정 시간 요청이 없으면 다시 0 으로 줄입니다.

넣었더니 되긴 되는데 동작이 일관되지 않았습니다. 어떤 요청은 통과하고 어떤 요청은 이상한 응답을 받았습니다. 원인을 좁히지 못한 채로 두면 개발 환경 전체가 못 미더워지므로, 일단 전부 걷어냈습니다.

되돌린 다음에 원인을 찾았습니다.

왜 안 됐나

깨우는 쪽과 보내는 쪽이 서로 다른 기준을 보고 있었습니다.

깨우기 담당은 "파드가 준비됐는가"를 워크로드 상태로 판단했습니다. 라우팅 담당은 실제 엔드포인트 목록을 봅니다. 이 둘은 같은 순간에 참이 되지 않습니다. 파드가 준비 상태가 된 직후에도 라우팅 쪽 목록에는 아직 안 올라와 있는 구간이 있습니다.

그 구간에 들어온 요청은 갈 곳이 없습니다. 그런데 미들웨어가 그 실패를 삼키고 자기 대기 화면을 정상 응답으로 돌려주고 있었습니다. 그래서 오류로 보이지 않고 그냥 이상하게 보였습니다.

경합을 없애고, 실패했을 때 재시도가 돌게 하니 안정됐습니다.

두 번째 실수 — 기본값

다시 넣고 나서도 느렸습니다. 파드가 이미 떠 있는데도 첫 요청이 5 초 넘게 걸렸습니다.

원인은 대기 전략의 확인 주기 기본값이었습니다. 준비됐는지를 5 초마다 다시 봅니다. 세션이 없는 상태에서 온 첫 요청은 파드가 멀쩡히 살아 있어도 다음 확인 시각까지 붙들려 있습니다.

실측했더니 다섯 개 앱 전부 첫 요청이 5.2 초, 두 번째 요청이 0.09 초였습니다. 그 차이가 통째로 기본값이었습니다. 주기를 짧게 바꾸니 사라졌습니다.

기본값이 나쁜 게 아니라, 우리 용도와 안 맞았을 뿐입니다. 그런데 이런 건 문서를 읽어서 아는 게 아니라 재 봐야 압니다.

세션 시간도 두 번 고쳤다

몇 분 동안 요청이 없으면 재울지도 조정이 필요했습니다.

처음엔 30 분으로 뒀는데, 그러면 아침에 한 번 깨운 환경이 하루 종일 안 잡니다. 절감이 거의 없었습니다. 2 분으로 줄였더니 이번엔 반대로, 잠깐 자리를 비우면 재워져서 돌아올 때마다 콜드스타트를 겪었습니다.

10 분으로 정착했습니다. 두 번 틀리고 나서 맞춘 값입니다.

배포 도구와의 충돌

한 가지 더 있었습니다. 워크로드를 0 으로 줄이면 배포 도구가 그것을 의도치 않은 변경으로 보고 되살립니다. 자동 복구를 꺼도 소용없었습니다 — 다른 이유로 동기화가 돌 때마다 원래 개수로 돌아왔습니다.

복제본 수를 비교 대상에서 제외하도록 명시하고, 그 제외를 동기화가 존중하도록 설정해야 합니다. 둘 다 있어야 합니다. 하나만으로는 안 됩니다.

무엇을 배웠나

이 작업에서 실제로 배운 건 scale-to-zero 그 자체가 아닙니다.

여러 구성 요소가 각자 다른 "준비됨"을 보고 있으면, 평소엔 멀쩡하다가 전환 순간에만 깨집니다. 그리고 그런 결함은 오류가 아니라 "가끔 이상함" 으로 나타나서, 재현이 안 되고 원인 추적이 오래 걸립니다.

되돌린 게 잘한 선택이었습니다. 고쳐 보겠다고 붙들고 있었으면 그동안 개발 환경 전체가 불안정했을 겁니다. 원인을 모를 때는 일단 원상복구하고, 안전한 상태에서 조사하는 편이 빠릅니다.