쿠버네티스를 도입하면 컨테이너 배포가 쉬워질 것이라 기대하지만, 실제 운영에서는 파드가 갑자기 재시작되거나 노드가 압박을 받아 워크로드가 쫓겨나는 일이 빈번하게 발생합니다. 운영의 본질은 ‘배포’가 아니라 ‘안정적으로 계속 굴리는 것’입니다. 이 글에서는 처음 클러스터를 책임지는 입장에서 반드시 이해해야 할 구조와 설정을 다룹니다.
운영 문제: 왜 파드는 예고 없이 죽는가
가장 흔한 장애는 리소스 미설정에서 비롯됩니다. requests와 limits를 지정하지 않으면 스케줄러는 노드 용량을 가늠하지 못하고, 한 파드가 메모리를 폭주시키면 OOMKilled가 연쇄적으로 발생합니다. 실제로 노드당 평균 메모리 사용률이 85%를 넘어가면 eviction 위험이 급격히 올라갑니다.
아키텍처: 컨트롤 플레인과 워커의 역할
컨트롤 플레인은 클러스터의 두뇌입니다. kube-apiserver가 모든 요청의 관문이 되고, etcd가 상태를 저장하며, scheduler와 controller-manager가 원하는 상태(desired state)와 실제 상태를 끊임없이 비교해 수렴시킵니다. 워커 노드의 kubelet은 이 명령을 받아 컨테이너를 실제로 띄웁니다. 운영자는 이 reconciliation loop를 이해해야 장애 원인을 추적할 수 있습니다.
구성: 리소스와 헬스체크 기본 세팅
최소한의 안정성을 확보하려면 모든 워크로드에 리소스 경계와 프로브를 설정해야 합니다. 아래는 권장 출발점입니다.
resources:
requests: { cpu: "250m", memory: "256Mi" }
limits: { cpu: "500m", memory: "512Mi" }
livenessProbe:
httpGet: { path: /healthz, port: 8080 }
initialDelaySeconds: 15
readinessProbe:
httpGet: { path: /ready, port: 8080 }
periodSeconds: 5livenessProbe는 ‘죽었으면 재시작’, readinessProbe는 ‘준비 안 됐으면 트래픽 차단’이라는 서로 다른 목적을 가집니다. 둘을 혼동해 livenessProbe를 너무 공격적으로 잡으면 부팅 중인 파드가 계속 재시작되는 죽음의 루프에 빠집니다.
모니터링과 비용: 무엇을 봐야 하는가
- 노드별 CPU/메모리 사용률과 allocatable 대비 점유율
- 파드 재시작 횟수(restartCount)와 OOMKilled 빈도
- 스케줄 실패(Pending) 파드 수와 그 원인 이벤트
- PVC 스토리지 잔여 용량
비용 관점에서는 노드 활용률이 핵심입니다. requests를 실제 사용량보다 과하게 잡으면 노드는 한가한데도 새 노드가 늘어 비용이 새어 나갑니다. 2주간 실측 데이터를 기준으로 requests를 재조정하면 흔히 20~30% 노드 비용을 절감할 수 있습니다.
정리
쿠버네티스 운영의 기본은 화려한 기능이 아니라 리소스 경계, 헬스체크, 관측 지표라는 세 가지 토대입니다. 이 토대를 먼저 다진 뒤에야 오토스케일링이나 멀티클러스터 같은 고급 주제로 나아갈 수 있습니다. 작게 시작하되, 측정 가능한 상태에서 시작하십시오.



