Pods as Workers, Not Agents: Rethinking the Deployment Unit for AI Agents on Kubernetes

InfoQ · 2026.08.08

Pod-per-Task 모델의 함정

Kubernetes 환경에서 워커 태스크를 처리할 때 가장 직관적인 설계는 "태스크 하나에 Pod 하나"를 할당하는 방식이다. 하지만 이 모델은 실무에서 생각보다 큰 비용을 유발한다. 태스크가 순간적으로 몰리는 burst 상황에서는 수십~수백 개의 Pod가 동시에 생성되고, 각각의 Pod는 컨테이너 이미지 풀링, 초기화, 스케줄링 지연이라는 오버헤드를 동반한다. 태스크 수명이 수초~수분에 불과하다면 이 비용은 실제 처리 시간보다 커질 수 있다.

더 큰 문제는 서브태스크 생성 패턴이다. 하나의 태스크가 실행 중에 동적으로 하위 태스크를 생성하는 경우, Pod 기반 1:1 모델에서는 각 서브태스크마다 새로운 Pod 스케줄링이 발생하고, 클러스터 리소스 한계에 금방 도달한다. 또한 사람의 승인을 기다리는(human-in-the-loop) 대기 상태에서도 Pod는 리소스를 점유한 채 유휴 상태로 남는다.

장기 실행 워커 Pod + 논리적 Actor 모델

kagent 프로젝트의 agent-substrate는 이 문제를 해결하기 위해 컨트롤 플레인 계층을 추가한다. 핵심 아이디어는 수명이 긴(long-lived) 워커 Pod를 미리 띄워두고, 논리적 실행 단위인 "Actor"를 동적으로 해당 Pod 위에 스케줄링하는 것이다.

[Control Plane: agent-substrate]
        |
        v
[Worker Pod A]  [Worker Pod B]  [Worker Pod C]
  Actor 1,2       Actor 3         Actor 4,5,6

이 구조에서 Pod는 더 이상 1:1 실행 단위가 아니다. 워커 Pod는 프로세스 풀처럼 상시 대기하고, 컨트롤 플레인이 태스크(Actor)를 적절한 워커에 배치한다. 태스크가 대기 상태에 들어가면 해당 Actor만 일시 중단되고 워커 Pod는 다른 Actor를 처리할 수 있다. 이는 Go의 goroutine이나 JVM의 가상 스레드(Virtual Thread)가 OS 스레드를 효율적으로 공유하는 원리와 유사하다.

// 기존 방식 (개념적 비유): 태스크마다 새 스레드 생성
new Thread(() -> processTask(task)).start();

// 개선된 방식: 스레드 풀 위에 논리 단위 스케줄링
executorService.submit(() -> processTask(task));

Java 백엔드 관점에서 보면, 이미 우리가 Tomcat 스레드 풀, HikariCP 커넥션 풀 등에서 익숙하게 사용해온 패턴을 Kubernetes Pod 레벨로 끌어올린 것이다.

실무 설계에 주는 시사점

이 모델이 중요한 이유는 Kubernetes를 "컨테이너 런타임"이 아닌 "분산 실행 환경"으로 바라보는 시각 전환을 요구하기 때문이다. 실제로 Job, CronJob, Deployment를 조합해 태스크를 처리하는 백엔드 시스템에서는 다음 상황을 점검해볼 필요가 있다.

  • 태스크 수명이 짧고 burst가 잦은가? → Pod-per-task 모델은 스케줄링 지연이 병목이 된다
  • 태스크가 동적으로 서브태스크를 생성하는가? → Pod 수가 예측 불가능하게 증가한다
  • 대기(idle) 구간이 긴 태스크가 존재하는가? → 리소스 점유 대비 실제 처리량이 낮다

이러한 패턴이 존재한다면, 워커 Pod를 고정 수로 유지하면서 내부에서 논리적 실행 단위를 스케줄링하는 구조를 검토할 가치가 있다. 특히 Spring Batch나 자체 구현 워커 서버를 Kubernetes 위에서 운영 중이라면, Pod 수를 무한정 늘리는 대신 워커 Pod 내부의 동시성 모델을 정교하게 설계하는 방향이 더 효율적일 수 있다.

정리

  • Pod-per-task 모델은 burst, 단명 태스크, 서브태스크 생성 시 스케줄링 오버헤드와 리소스 낭비를 유발한다
  • kagent의 agent-substrate는 장기 실행 워커 Pod 위에 논리적 Actor를 동적 스케줄링하여 Pod 수를 안정적으로 유지한다
  • Java 백엔드에서 익숙한 스레드 풀·커넥션 풀 패턴을 Kubernetes Pod 레벨에 적용하는 관점으로 이해하면 설계 전환이 수월하다
Source
InfoQ
원문 보기 →
← 목록으로 돌아가기