왜 스타트업에서 Day 1부터 쿠버네티스를 선택했을까


Intro
“초기 스타트업에서 쿠버네티스까지 필요한가?”
제목을 보고 가장 먼저 드는 생각일 겁니다. 여러 개발자 커뮤니티에서 계속 오가고 있는 주제기도 합니다.
프로토타이핑으로 유저 반응부터 보려는 제품이라면 쿠버네티스 말고도 선택지가 많습니다.
진짜로 쿠버네티스가 필요하다구요?
저는 모든 초기 스타트업에서 쿠버네티스가 필요하다고 생각하지 않습니다. 대부분의 경우에는 필요하지 않다고 생각하는 쪽에 가깝습니다.
이 논쟁이 매번 평행선을 그리는 건 서로 다른 상황에 있는 사람들이 같은 단어로 이야기하기 때문입니다.
“초기 스타트업”이라는 말 안에는 아직 무엇을 만들지 모르는 팀도 있고, 무엇을 만들지는 알지만 사람 손으로 돌리는 팀도 있습니다. 두 팀에게 같은 답이 나올 리가 없습니다.
그래서, 이 글은 쿠버네티스를 쓰세요에 대한 글이 아닙니다. 우리 팀이 어떤 조건에 있었고, 중요하게 생각했던 게 무엇인지, 그리고 그 조건에서 왜 쿠버네티스가 가장 싼 선택이었는지를 적었습니다. 조건이 다르다면 결론도 달라집니다.
1. 프로토타이핑이 이미 끝나 있었습니다
“초기 스타트업에 쿠버네티스는 오버엔지니어링”이라는 말은 버려질 확률이 높은 코드에 인프라 비용을 쓰지 말라는 뜻으로 읽습니다.
맞는 말입니다. 내일 당장 갈아엎을 서비스에 클러스터를 세우는 건 낭비입니다.
저희는 그 단계를 이미 지나 있었습니다. 홈코는 집수리 서비스이고, 프로토타이핑은 구글 시트로 끝나 있었습니다. 고객이 요청을 넣고, 저희가 견적서를 보내고, 기사님을 배정하고, 시공이 끝나면 정산까지 하는 흐름 전체가 시트와 사람 손, 약간의 자동화 SaaS 위에서 돌아가고 있었습니다.
제가 만들어야 할 것은 이미 되고 있는 일을 풀어내는 인프라였습니다. “이게 될까?“는 확인이 끝난 상태였습니다. 도메인은 확정되어 있었고 필요한 화면과 배치, 상태 전이가 무엇인지 대략 알고 있었습니다.
제목을 Day 0 가 아니라 Day 1 으로 쓴 이유이기도 합니다.
저희에게 Day 1 은 앞으로 몇 년을 갈 인프라의 첫날이었습니다. 그렇게 잡고 나면 기준이 달라집니다.
2. 배치가 필연적입니다
시트로 돌아가는 운영을 옆에서 보고 있으면 앞으로 무엇이 필요해질지가 선명하게 보입니다.
집수리 서비스의 운영은 요청-응답만으로 돌아가지 않습니다. 시공 전날 고객에게 나가는 리마인드, 기사님께 보내는 시공 전 알림, 자재 재고 확인, 아직 작성되지 않은 견적서 알림까지, 눈에 보이는 배치성 작업이 이미 많았습니다.
집수리 데이터가 쌓이고 나면 데이터 적재나 분석을 위한 배치도 당연히 따라옵니다.
배치는 하나 만들기 시작하면 요구사항이 붙습니다. 실패하면 재시도해야 하고, 겹쳐 돌면 안 되고, 실패했다는 사실을 누군가 알아야 하고, 지난 실행이 언제 어떻게 끝났는지 남아야 합니다. 서버에 crontab 을 걸어두는 방식으로 시작하면 이 요구사항들을 결국 하나씩 직접 만들게 됩니다.
쿠버네티스에서는 CronJob 하나에 스케줄, 동시 실행 정책, 재시도 횟수, 실행 이력 보관 개수가 전부 필드로 들어 있습니다. 배치가 늘어나도 관리하는 방식은 같습니다. 배치가 필연이라는 걸 알고 있었으니 배치를 잘 다루는 런타임에서 시작하는 편이 쌌습니다.
3. 형상화하지 않으면 아무도 이유를 모릅니다
개인적으로 중요하게 생각하는 부분입니다.
손으로 만든 인프라는 만든 사람의 기억에만 남습니다. 이 서버에 왜 이 프로세스가 떠 있는지, 저 포트가 왜 열려 있는지, 저 환경변수는 어디서 온 건지. 6개월 뒤에는 만든 본인도 기억하지 못하고 새로 합류한 사람은 알 방법이 없습니다.
쿠버네티스에서 가장 크게 얻은 건 컨테이너 오케스트레이션보다도 모든 것이 표준으로, 선언적으로 남는다는 점이었습니다. 어떤 서비스가 몇 개 떠 있는지, 어떤 환경변수를 받는지, 어떤 리소스를 쓰는지, 어떤 배치가 언제 도는지를 전부 형상으로 남길 수 있습니다.
그래서 인프라 변경을 코드 리뷰에 올릴 수 있고, 되돌릴 수 있고, “언제 누가 왜 바꿨는지”가 히스토리로 남습니다. 사람이 적은 팀일수록 여기서 얻는 게 큽니다. 한 사람의 머릿속에만 있는 “표준이 아닌 도메인 지식“은 그대로 단일 장애점이 되니까요.
4. Observability 가 자연스럽습니다
“일단 만들고 나중에 모니터링 붙이자”고 해두면, 피처 개발에 밀려 있다가 장애가 한 번 나야 붙입니다. 그리고 그 장애의 원인은 로그도 메트릭도 없어서 끝내 모른 채 넘어갑니다.
운영의 흐름이 확정된 상태에서는 이 비용이 특히 컸습니다. “어제 오후에 예약이 안 잡혔다”는 문의가 들어왔을 때 그 시점의 로그와 메트릭, 트레이스가 없으면 답할 방법이 없습니다.
쿠버네티스에서 관측성은 나중에 얹는 레이어라기보다 이미 바닥에 깔려 있는 쪽에 가깝습니다. 파드가 stdout 으로 뱉은 로그는 런타임이 노드의 정해진 경로에 쌓아두고, kubelet 과 컨트롤 플레인은 처음부터 프로메테우스 포맷으로 메트릭을 노출합니다. 파드가 몇 번 재시작했는지, 왜 죽었는지가 OOMKilled 인지 프로브 실패인지도 리소스 상태에 그대로 들어 있습니다. 데이터는 이미 나오고 있고, 남는 일은 그걸 어디로 보낼지 정하는 것뿐입니다.
헬름 차트 하나로 메트릭과 알럿의 기본이 서고, opentelemetry collector 를 DaemonSet 으로 띄우면 그 노드 위의 모든 파드 로그가 따라 들어옵니다.
쿠버네티스 API 를 그대로 서비스 디스커버리로 쓰기 때문에, 워크로드에 라벨만 맞춰두면 새로 뜬 파드가 알아서 수집 대상이 됩니다. 네임스페이스, 파드, 컨테이너 같은 키가 로그와 메트릭과 트레이스에 똑같이 붙어 나오는 것도 따로 설계한 게 아니라 기본값입니다. 셋을 같은 축으로 이어 보는 데 드는 비용이 처음부터 0에 가까웠습니다.
서비스마다 Observability 를 따로 챙겨야 하면 결국 안 챙기게 됩니다. 플랫폼 레이어에서 기본으로 딸려오게 만들 수 있다는 점이 초기에 쿠버네티스로 간 이유 중 하나입니다.
5. 오픈소스를 “올리는” 비용이 거의 사라집니다
여기까지의 이유는 쿠버네티스가 아니어도 됩니다. 형상화는 Terraform 과 태스크 정의로 똑같이 남고, 배치와 관측성도 ECS Fargate 위에서 상당 부분 따라옵니다. 운영할 것이 우리 서비스와 배치뿐이었다면 관리형 서비스가 더 싼 선택이었을 겁니다.
결정을 가른 건 이번 섹션입니다.
우리가 맞닥뜨린 문제들의 해결을 위한 오픈소스가 넘쳐납니다. 바퀴를 재발명하지 않기 위해서 손쉽게 가져다 쓸 수 있어야 합니다. 쿠버네티스 환경에서는 “이 오픈소스 한번 써볼까?“라는 생각이 들면 그날 바로 올려볼 수 있습니다.
저희 클러스터에는 자동화 도구 n8n, BI 도구 metabase, Knowledge Base 가 되는 onyx, SEO 분석을 위한 open-seo 등이 올라가 있습니다. 공통점은 올리는 데 전부 30분이 채 안 걸렸다는 것입니다.
쿠버네티스 안에서는 오픈소스의 배포 방식이 사실상 표준화되어 있습니다. 요즘 웬만한 설치형 오픈소스 프로젝트의 README 에는 이 두 줄이 있습니다.
helm repo add ...
helm install ...
프로젝트 입장에서도 쿠버네티스가 배포 타깃의 공통 분모라서 그렇습니다. 사용자가 AWS 를 쓰든 GCP 를 쓰든 온프레미스이든, 차트 하나만 잘 만들어두면 다 커버가 됩니다.
덕분에 무엇이 필요해질지 몰라도, 그때 필요한 건 대체로 이미 차트로 있습니다. 데이터 파이프라인이 필요해지면 Airflow 가, LLM 호출을 추적해야 하면 Langfuse 가, 사내 도구들의 계정을 한 곳에서 관리해야 하면 Keycloak 이 있습니다. Postgres 나 Redis 처럼 원래 운영이 까다로운 것들도 Operator 형태로 나와 있어서, 백업과 페일오버까지 포함된 상태로 올라옵니다. (물론 실제 운영은 지옥입니다)
같은 일을 다른 환경에서 하려고 하면 매번 달라집니다. 어떤 프로젝트는 docker compose 로, 어떤 건 소스를 직접 빌드해야 하고, 어떤 건 systemd 유닛을 직접 짜야 합니다. 의존성으로 붙는 Postgres 와 Redis 는 또 따로 준비해야 합니다.
쿠버네티스에서는 서버 리소스만 남아 있으면 운영까지 생각하지 않고 일단 올려서 테스트해보는 데 드는 품이 거의 없습니다.
그러면 판단하는 방식이 달라집니다. “한번 써볼까?“를 스프린트에 올리지 않고 오후 시간에 해봅니다. 써보고 안 맞으면 helm uninstall 로 흔적 없이 지웁니다. 되돌리는 비용이 낮으니 시도하는 횟수가 늘어납니다.
라이선스가 허락하면 한 걸음 더 갈 수도 있습니다. 포크해서 필요한 부분만 고치고, 이미지를 우리 레지스트리에 올리고, 차트의 이미지만 바꿔 끼우면 됩니다. 배포도 운영도 원래 차트 그대로 굴러갑니다. 예전에는 이 선택지가 비쌌지만, AI 로 이 비용이 많이 낮아졌고, 고칠 지점을 찾는 데 걸리던 며칠이 몇 시간이 되었습니다.
물론 helm 차트가 만능은 아닙니다.
차트는 설치를 쉽게 해줄 뿐 운영을 쉽게 해주지는 않습니다. 다만 그 비용이 도구 개수만큼 곱해지지는 않습니다. 도구를 늘려도 운영하는 방식이 크게 늘어나지 않는 구조에 가깝습니다.
6. 그리고 솔직한 이유
위의 이유들이 그럴듯해도, 이 두 가지가 없었다면 다른 선택을 했을 겁니다.
이미 익숙한 도구였습니다
“쿠버네티스는 러닝커브가 높다”는 말은 사실입니다. 다만 러닝커브는 도구의 속성이라기보다 팀과 도구 사이의 거리에서 나옵니다. 저는 커리어 내내 쿠버네티스 환경을 운영해왔고, 이제는 쿠버네티스 없으면 어떻게 배포하지 (…) 라는 생각이 듭니다. 그래서 도구를 선택하면서 치른 학습 비용이 0에 가까웠습니다.
같은 이유로, 팀에 쿠버네티스 경험이 없다면 저도 위의 이야기들과 무관하게 다른 선택을 했을 것 같습니다. 팀이 새벽 3시에 디버깅할 수 없는 도구는 좋은 도구가 아닙니다.
AWS 크레딧이 있었습니다
비용 이야기의 상당 부분을 여기서 건너뛸 수 있었습니다. 컨트롤 플레인 비용, 아주 살짝 여유 있는 노드 구성, observability 스택이 먹는 리소스가 초기에 부담이 되지 않았습니다.
크레딧은 언젠가 소진됩니다. 공짜라서 고른 건 아니고, 제대로 된 기반을 까는 데 드는 초기 비용을 크레딧이 대신 내줬습니다. 크레딧이 없었다면 더 검소한 구성으로 시작했겠지만, 선택 자체를 바꾸지는 않았을 겁니다.
7. 결국 피한 건 이관 비용입니다
나중에 옮기는 비용이 처음에 까는 비용보다 큽니다. 특히나 서비스의 척추가 되는 인프라에 대해서, 한번 결정한 이후에는 마이그레이션이 쉽지 않습니다.
Day 1 에 쿠버네티스를 올리는 건 며칠짜리 일입니다. 서비스가 몇 개 없고, 트래픽이 없고, 데이터가 없고, 무중단으로 옮겨야 할 이유도 없습니다. 실수해도 지우고 다시 만들면 됩니다.
같은 일을 2년 뒤에 하면 분기 단위 프로젝트가 됩니다. 옮겨야 할 서비스가 많아지고, 각각 조금씩 다른 방식으로 배포되고 있고, 무중단으로 옮겨야 하고, 그 사이에도 제품은 계속 나가야 합니다. 그리고 그 분기 동안 팀은 고객에게 아무것도 주지 못합니다.
같은 결과물을 얻는 데 드는 비용이 시간이 갈수록 비싸진다면 그 일은 가능한 한 앞에서 해야 합니다. 특히 저희처럼 도메인이 이미 확정되어 있어서 “안 하게 될 가능성”이 낮은 경우에는요.
마치며
“초기 스타트업에 쿠버네티스가 필요한가”라는 질문에는, 조건을 빼고 물어보면 답이 없습니다.
저는 이렇게 바꿔서 스스로에게 묻는 편입니다.
우리 팀이 3개월 뒤에 반드시 필요해질 것이 무엇이고, 그걸 그때 만드는 비용과 지금 만드는 비용의 차이는 얼마일까? 그리고 우리 팀은 그걸 감당할 수 있을까?
저희의 경우, 프로토타이핑이 이미 끝나 있었고, 배치가 필연이었고, 관측성이 필요했고, 그 도구가 익숙했습니다. 그리고 활용해야 할 많은 오픈소스들이 눈에 보였습니다. 그래서 쿠버네티스를 선택했습니다.
조건이 다른 팀의 답은 다를 수 있고, 달라야 합니다. “우리 조건에서 무엇이 가장 싼 선택인가”를 직접 계산해 보는 것, 쿠버네티스든 아니든, 선택의 근거를 확실히 말해볼 수 있다면 그게 맞는 (맞아야 하는) 정답이 아닐까요.