본문 바로가기
기술/LLM

[LLM] Kubernetes Gateway API Inference Extension 실전 적용: InferencePool로 LLM 트래픽 라우팅하기

by 한결이상 2026. 9. 19.
이 글은 Envoy Gateway, Agent Router(구 Envoy AI Gateway), 그리고 Kubernetes Gateway API Inference Extension을 다룬 스터디 내용을 정리한 것이다. HTTPRoute만으로는 왜 LLM 트래픽을 제대로 다루기 어려운지에서 출발해, InferencePool·InferenceModel CRD를 실제로 클러스터에 붙여보고 다중 모델 라우팅을 검증하는 과정, 그리고 그 밑에서 도는 실제 명령어까지 정리했다.

들어가며 - 왜 HTTPRoute만으로는 부족한가

일반적인 웹 서비스라면 K8s의 HTTPRoute와 Service만으로 트래픽 분산이 충분하다. 요청 하나하나의 처리 시간이 비교적 균일하기 때문에, 라운드로빈이나 커넥션 수 기반의 L4/L7 로드밸런싱으로도 부하가 고르게 퍼진다.

LLM 서빙은 사정이 다르다. 프롬프트 길이, 생성 토큰 수, 캐시 히트 여부에 따라 요청 하나의 처리 시간이 수십 배씩 차이 날 수 있다. 이런 환경에서 IP/Port 단위로만 트래픽을 나누는 L4 로드밸런서를 쓰면, 무거운 요청들이 우연히 같은 파드에 몰리는 핫스팟 현상이 발생한다. 파드별 실제 부하(큐 대기열, KV 캐시 상태, VRAM 여유)를 모르는 상태로 트래픽을 분산하기 때문에 생기는 문제다.

이 문제를 K8s 표준 차원에서 풀기 위해 등장한 것이 Gateway API Inference Extension이다. Kubernetes 공식 SIG 산하 서브 프로젝트로, 기존 Gateway API에 LLM 추론 워크로드에 특화된 CRD(Endpoint Picker, Body-Based Router)를 추가하는 형태로 설계됐다.

Step 1. 핵심 개념 정리: InferenceModel과 InferencePool

Gateway API Inference Extension이 도입하는 핵심 리소스는 두 가지다.

InferenceModel은 클라이언트가 요청하는 모델 이름(예: llama-3.2-1b, qwen2.5-0.5b)을 실제로 그 모델을 서빙하는 백엔드로 매핑하는 논리적 정의다. "이 모델 이름으로 요청이 오면 어디로 보낼지"를 선언하는 역할을 한다.

InferencePool은 InferenceModel이 가리키는 실제 파드 집합과, 그 파드들 간의 트래픽 가중치(traffic split)를 관리하는 리소스다. 같은 모델을 서빙하는 파드가 여러 개 있을 때, 그 파드들을 하나의 풀로 묶어서 관리한다고 이해하면 된다. 실제로 스펙을 열어보면 이렇게 생겼다.

apiVersion: inference.networking.k8s.io/v1
kind: InferencePool
metadata:
  name: llama32-1b
  namespace: default
spec:
  selector:
    matchLabels:
      app: llama32-1b
  targetPorts:
    - number: 8000
  endpointPickerRef:
    name: llama32-1b-epp
    port:
      number: 9002

selector로 이 풀에 속할 파드를 라벨 기준으로 묶고, endpointPickerRef로 이 풀의 라우팅 결정을 누가 내릴지(EPP)를 명시한다.

구조적으로 가장 중요한 변화는 HTTPRoute의 backendRefs가 가리키는 대상이다. 기존에는 HTTPRoute가 일반 K8s Service를 가리켰다면, Inference Extension을 적용하면 HTTPRoute의 backendRefs가 Service 대신 InferencePool CRD를 직접 참조하도록 바뀐다. 즉 "이 경로로 들어온 요청은 이 InferencePool이 알아서 최적의 파드로 보내라"는 위임 구조가 된다.

Step 2. Envoy AI Gateway에서 Agent Router로 - 아키텍처 이해하기

실습 자료를 찾다 보면 "Envoy AI Gateway"라는 이름과 "Agent Router"라는 이름이 섞여서 나오는데, 둘은 같은 프로젝트다. Envoy AI Gateway는 원래 CNCF 산하 Envoy 하위 프로젝트로 출발했고, 2025년 8월 25일 Linux Foundation에 벤더 중립 거버넌스로 기증됐다. 이후 에이전틱 AI 인프라 표준화를 목표로 하는 **AAIF(Agentic AI Foundation)**가 출범하면서, 이 프로젝트의 장기적인 홈으로 AAIF가 적합하다고 판단돼 이름도 Agent Router로 바뀌어 합류했다. 기능이 바뀐 게 아니라 거버넌스 소속과 이름이 바뀐 것이라고 이해하면 된다.

아키텍처는 Control Plane과 Data Plane으로 나뉜다.

  • Control Plane: Agent Router Controller(AI 특화 설정 담당)와 Envoy Gateway Controller(코어 프록시 인프라 설정 담당)로 이뤄진다. 설정 흐름은 다음과 같다. ① Agent Router Controller가 AIGatewayRoute 같은 AI Gateway CR 변경을 감시한다. ② 이에 대응하는 Envoy Gateway 설정과 HTTPRoute 리소스를 생성한다. ③ Envoy Gateway가 이를 xDS 설정으로 변환한다. ④ Agent Router Controller가 Extension Server 프로토콜을 통해 이 xDS 설정을 다시 미세 조정한다. ⑤ Envoy Proxy가 최종 설정을 받아 트래픽에 적용한다.
  • Data Plane: Envoy Proxy(트래픽 핸들러), AI Gateway External Processor(모델 선택·검증, 토큰 사용량 추적, 프로바이더 간 포맷 변환), Rate Limit Service(토큰 기반 레이트리밋)로 구성된다.

리소스 차원에서는 3개의 핵심 CRD가 계층 구조를 이룬다.

Client Request
     ↓
AIGatewayRoute (통합 진입점 - 라우팅/변환/비용 모니터링)
     ↓
AIServiceBackend (개별 백엔드 - 출력 스키마 정의)
     ↓ (선택적으로 참조)
BackendSecurityPolicy (인증 - API Key / AWS credentials)

AIGatewayRoute가 클라이언트 요청을 받아 적절한 AIServiceBackend로 트래픽을 분배하는 중앙 오케스트레이터 역할을 하고, 각 백엔드는 필요하면 BackendSecurityPolicy를 통해 자격증명을 얻는 구조다.

Step 3. 두 가지 통합 경로: HTTPRoute+InferencePool vs AIGatewayRoute+InferencePool

InferencePool을 실제 트래픽 경로에 연결하는 방법은 두 가지다. 둘 다 실습에서는 GPU 없이 CPU만으로 가능한데, llama.cpp가 GGUF 포맷 경량 모델을 서빙하기 때문이다.

HTTPRoute + InferencePool은 표준 Gateway API HTTPRoute로 InferencePool을 직접 참조하는, 단순한 추론 라우팅 시나리오용 경로다. 요청 처리 흐름은 이렇다.

클라이언트(curl) → ① Gateway → ② HTTPRoute(경로 매칭)
   → ③ Envoy Gateway가 backendRefs의 kind: InferencePool 인식
   → ④ EPP에게 gRPC(ext_proc)로 "어느 파드로 보낼까" 질의
   → ⑤ EPP가 선택한 파드로 전달 → ⑥ 클라이언트에게 응답 반환

실제로 배포하고 호출해보면 다음과 같다.

# 배포 확인
kubectl describe deployments.apps llama32-1b-epp
#   Args: --pool-name llama32-1b --pool-namespace default
#         --grpc-port 9002 --grpc-health-port 9003
#         --config-file /config/default-plugins.yaml

# GatewayClass/Gateway/HTTPRoute 배포
kubectl apply -f inferencepool-httproute.yaml
kubectl wait --for=condition=Programmed gateway/inference-pool-with-httproute -n default --timeout=60s

# 호출 테스트
GW_IP=$(kubectl get gateway inference-pool-with-httproute -n default -o jsonpath='{.status.addresses[0].value}')
curl -X POST "http://${GW_IP}/v1/chat/completions" \
  -H "Content-Type: application/json" \
  -d '{"messages":[{"role":"user","content":"Say this is a test"}],"model":"llama-3.2-1b"}' | jq

# EPP 스케줄링 정상 동작 확인 (llama.cpp는 vLLM 전용 메트릭을 구현하지 않아 dispatch failed 로그가 찍히지만
# 스케줄링 신호 품질만 낮아질 뿐 라우팅 자체는 문제없다)
kubectl logs -n default -l app=llama32-1b-epp | grep "Completed running scheduler profile"

AIGatewayRoute + InferencePool은 AI Gateway의 커스텀 라우트 타입을 통해 고급 AI 특화 기능(다중 모델, 비용 모니터링 등)까지 다루는 경로다. 두 개의 모델(Llama 3.2 1B, Qwen2.5 0.5B)을 각각 InferencePool로 등록하고, 요청 헤더 값에 따라 분기시켰다.

apiVersion: aigateway.envoyproxy.io/v1beta1
kind: AIGatewayRoute
metadata: { name: inference-pool-with-aigwroute, namespace: default }
spec:
  parentRefs:
    - { name: inference-pool-with-aigwroute, kind: Gateway, group: gateway.networking.k8s.io }
  rules:
    - matches: [{ headers: [{ type: Exact, name: x-ai-eg-model, value: llama-3.2-1b }] }]
      backendRefs: [{ name: llama32-1b, group: inference.networking.k8s.io, kind: InferencePool }]
    - matches: [{ headers: [{ type: Exact, name: x-ai-eg-model, value: qwen2.5-0.5b }] }]
      backendRefs: [{ name: qwen25-05b, group: inference.networking.k8s.io, kind: InferencePool }]
GATEWAY_IP=$(kubectl get gateway inference-pool-with-aigwroute -n default -o jsonpath='{.status.addresses[0].value}')

# Llama 3.2 1B로 라우팅
curl -H "Content-Type: application/json" -H "x-ai-eg-model: llama-3.2-1b" \
  -d '{"model":"llama-3.2-1b","messages":[{"role":"user","content":"Hi. Say this is a test"}]}' \
  http://$GATEWAY_IP/v1/chat/completions | jq
# → "model": "bartowski/Llama-3.2-1B-Instruct-GGUF" 응답 확인

# Qwen2.5 0.5B로 라우팅
curl -H "Content-Type: application/json" -H "x-ai-eg-model: qwen2.5-0.5b" \
  -d '{"model":"qwen2.5-0.5b","messages":[{"role":"user","content":"Hi. Say this is a test"}]}' \
  http://$GATEWAY_IP/v1/chat/completions | jq
# → "model": "Qwen/Qwen2.5-0.5B-Instruct-GGUF" 응답 확인

여기서 짚어볼 만한 함정이 하나 있다. OpenAI 호환 API 규격에서는 어떤 모델을 쓸지가 요청 본문의 body.model 필드에 담겨 온다. 그런데 Gateway API의 HTTPRoute/AIGatewayRoute 매치 규칙은 헤더 값만 검사한다. 이 실습에서는 그래서 body.model과는 별개로 x-ai-eg-model이라는 헤더를 클라이언트가 직접 명시적으로 붙여서 라우팅에 사용했다. 본문의 모델명만 믿고 헤더 없이 호출하면 라우팅 규칙에 걸리지 않아 분기가 안 되는 상황을 겪기 쉬운 지점이다. (Gateway API Inference Extension 표준에는 본문을 파싱해 헤더로 변환해주는 Body-Based Router(BBR) 컴포넌트가 별도로 정의돼 있는데, 이 실습에서는 클라이언트가 헤더를 직접 명시하는 방식으로 단순화해서 검증했다.)

Step 4. 클러스터에 Envoy Gateway + Agent Router 설치하기

실습은 Kind 클러스터 기준으로 진행했다. macOS라면 Rosetta 활성화 후 VM에서 K3s/Kind를 올리는 편이 낫다.

# Kind 클러스터 생성
kind create cluster --name agentrouter
kubectl get node -owide   # v1.37.0 (요구사항 1.32+ 충족)

로컬/온프렘 환경에서는 LoadBalancer 타입 서비스의 외부 IP가 클라우드처럼 자동 할당되지 않기 때문에 MetalLB를 먼저 올린다. Kind의 도커 네트워크 대역(docker network inspect kind로 확인한 172.18.0.0/16) 중 노드가 쓰지 않는 상단 대역을 IPAddressPool로 지정했다.

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.16.1/config/manifests/metallb-native.yaml
kubectl wait --for=condition=available -n metallb-system deployment/controller --timeout=90s
kubectl rollout status -n metallb-system daemonset/speaker --timeout=90s
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata: { name: kind-pool, namespace: metallb-system }
spec:
  addresses:
    - 172.18.255.200-172.18.255.250
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata: { name: kind-l2, namespace: metallb-system }
spec:
  ipAddressPools: [kind-pool]

이제 Envoy Gateway를 Helm으로 설치한다. envoy-gateway-values.yaml에는 Agent Router가 xDS 설정을 후처리할 수 있도록 extensionManager.hooks.xdsTranslator 훅을 열어주는 설정이 들어간다.

helm upgrade -i eg oci://docker.io/envoyproxy/gateway-helm \
  --version v1.8.1 \
  --namespace envoy-gateway-system \
  --create-namespace \
  -f envoy-gateway-values.yaml
kubectl wait --timeout=2m -n envoy-gateway-system deployment/envoy-gateway --for=condition=Available

# 설치 확인
helm list -A
# eg   envoy-gateway-system   deployed   gateway-helm-v1.8.1   v1.8.1

이 시점에는 아직 Envoy Gateway 컨트롤러만 설치된 상태이고, Agent Router 본체(AI Gateway Controller)와 실제 트래픽을 처리하는 Envoy Proxy 데이터플레인은 없다. Agent Router는 CRD와 컨트롤러를 별도로 설치해야 한다.

# 1) Agent Router CRD 설치
helm upgrade -i aieg-crd oci://docker.io/envoyproxy/ai-gateway-crds-helm \
  --version v1.1.0 --namespace envoy-ai-gateway-system --create-namespace

# 2) Agent Router 컨트롤러 설치
helm upgrade -i aieg oci://docker.io/envoyproxy/ai-gateway-helm \
  --version v1.1.0 --namespace envoy-ai-gateway-system --create-namespace
kubectl wait --timeout=2m -n envoy-ai-gateway-system deployment/ai-gateway-controller --for=condition=Available

설치가 끝나면 컨트롤 플레인은 envoy-gateway(순수 Gateway API 컨트롤러)와 ai-gateway-controller(Agent Router 본체) 두 개가 뜬 상태가 된다. 실제 Envoy Proxy 데이터플레인 파드는 사용자가 GatewayClass/Gateway 리소스를 만들어야 그때 비로소 생성된다.

Step 5. InferencePool 붙여서 다중 모델 라우팅 실습하기

기본 설치가 끝나면 Step 1~3에서 정리한 InferencePool·InferenceModel·AIGatewayRoute CRD를 실제로 적용해 다중 모델 라우팅을 검증한다. EPP는 라우팅 결정을 어떤 기준으로 내릴지를 EndpointPickerConfig 플러그인 설정으로 조정할 수 있다.

apiVersion: v1
kind: ConfigMap
metadata: { name: llama32-1b-plugins-config, namespace: default }
data:
  default-plugins.yaml: |
    apiVersion: llm-d.ai/v1alpha1
    kind: EndpointPickerConfig
    plugins:
      - type: queue-scorer
      - type: kv-cache-utilization-scorer
      - type: prefix-cache-scorer
    schedulingProfiles:
      - name: default
        plugins:
          - pluginRef: queue-scorer
          - pluginRef: kv-cache-utilization-scorer
          - pluginRef: prefix-cache-scorer

queue-scorer(큐 대기열 길이), kv-cache-utilization-scorer(KV 캐시 사용률), prefix-cache-scorer(프리픽스 캐시 적중 여부) 세 가지 플러그인을 조합해 점수를 매기고, 그 점수를 기준으로 최종 파드를 고르는 구조다. Step 3에서 본 것처럼 실제로 서로 다른 x-ai-eg-model 헤더 값을 넣어 호출하면 Llama 3.2 1B와 Qwen 2.5 0.5B가 각각 다른 InferencePool/파드로 정확히 분기되는 걸 응답에 찍힌 model 필드로 확인할 수 있다.

Step 6. EPP(Endpoint Picker)는 내부적으로 어떻게 동작하나

EPP는 Envoy 프록시와는 별개의 프로세스로 동작하며, gRPC(ExtProc 프로토콜)로 통신한다. 배포 스펙을 보면 실체가 명확해진다.

containers:
  - name: epp
    image: ghcr.io/llm-d/llm-d-router-endpoint-picker:main
    args:
      - --pool-name
      - llama32-1b
      - --pool-namespace
      - default
      - --grpc-port
      - "9002"
      - --grpc-health-port
      - "9003"
      - --config-file
      - /config/default-plugins.yaml

내부 구조는 크게 네 컴포넌트로 나뉜다. Request Handler가 들어온 요청을 EPP 내부 처리 구조로 변환하고, Flow Control이 과부하를 방지하며 우선순위 큐잉을 담당하고, Request Scheduler가 실제로 어느 파드를 선택할지 결정하며, Data Layer가 이 판단의 근거가 되는 파드별 상태 데이터를 수집·저장한다.

라우팅 결정은 Filter → Score → Pick 3단계로 이뤄진다. 먼저 조건에 안 맞는 후보를 걸러내고(Filter), 남은 후보들에 Step 5에서 본 스코어러들로 점수를 매기고(Score), 최종적으로 가장 높은 점수의 파드를 선택한다(Pick). 과부하 상태를 판단하는 SaturationDetector가 게이트키퍼 역할을 하면서, 특정 파드가 포화 상태면 아예 후보에서 제외하는 방식으로 필터 단계에 개입한다.

여기서 흥미로운 설계 포인트 하나가 있다. 일반적인 모니터링이라면 Prometheus로 지표를 수집하면 될 것 같지만, Prometheus의 pull 방식 폴링은 수 초에서 수십 초 단위의 지연이 있다. LLM 서빙처럼 밀리초 단위로 파드 상태가 급격히 바뀌는 환경에서는 이 지연이 라우팅 결정을 무의미하게 만들 수 있다. 그래서 EPP는 Prometheus 지표에만 의존하지 않고, 파드(또는 사이드카)와 직접 gRPC 통신을 맺어 밀리초 단위로 상태를 수집하도록 설계돼 있다.

Step 7. 데이터 플레인 내부 들여다보기 - 실제로 무엇이 트래픽을 처리하나

라우팅이 잘 동작하는 것을 확인했다면, 그 밑에서 무슨 일이 일어나는지도 짚어볼 필요가 있다. Agent Router 데이터플레인 파드를 들여다보면 하나의 컨테이너가 아니라 세 개의 컨테이너로 구성돼 있다.

  • Init Container(ai-gateway-extproc): 이름은 Init 컨테이너지만 실제로는 계속 살아있는 프로세스다. K8s의 native sidecar 기능(restartPolicy: Always가 암묵적으로 적용된 initContainer)으로 envoy 컨테이너와 함께 상시 구동되며, Unix Domain Socket으로 envoy와 통신한다.
  • 메인 컨테이너(envoy): 정적 부트스트랩 설정만 갖고 있고, 나머지 라우팅/클러스터 설정은 xDS(ADS, DELTA_GRPC)로 Envoy Gateway 컨트롤 플레인에서 실시간으로 수신한다.
  • shutdown-manager: 파드 종료 시점에 Envoy가 새 연결을 거부하고 기존 연결을 다 처리할 때까지 기다리게 하는 graceful shutdown 헬퍼다.

설정 변경이 반영되는 방식도 눈여겨볼 지점이다. 일반적인 프록시(nginx 등)는 설정이 바뀌면 프로세스를 재시작하거나 워커를 새로 띄워야 하지만, Envoy는 xDS 기반 동적 리로드를 사용한다. 컨트롤 플레인이 xDS API를 통해 새 설정을 흘려보내면, Envoy는 프로세스를 재시작하지 않고도 내부 라우팅 규칙을 갱신한다. 실제로 Admin API로 이 상태를 확인할 수 있다.

# Envoy 데이터플레인 파드의 admin 포트로 포트포워딩
MYPOD=$(kubectl get pod -n envoy-gateway-system -l app.kubernetes.io/component=proxy -o json | jq -r '.items[0].metadata.name')
kubectl port-forward -n envoy-gateway-system pod/$MYPOD --address 0.0.0.0 19000:19000 &

ADMIN=http://127.0.0.1:19000

# 컨트롤 플레인과의 xDS gRPC 연결 상태 확인 (connected_state: 1이면 정상)
curl -s "$ADMIN/stats?filter=control_plane"

# 실제 적용된 클러스터/리스너 목록 확인
curl -s "$ADMIN/config_dump" | jq '.configs[].dynamic_listeners'
curl -s "$ADMIN/clusters" | grep -A1 "^xds_cluster"

라우팅이 예상과 다르게 동작할 때 가장 먼저 확인해볼 만한 지점이 바로 이 /config_dump와 control_plane 통계다.

Step 8. 실제 라우팅 경로 검증하기 - HTTPRoute부터 EPP까지

마지막으로 지금까지 만든 리소스들이 실제로 어떻게 연결돼 있는지 kubectl로 직접 확인해본다. 전체 흐름은 이렇다.

Gateway(inference-gateway) → HTTPRoute(backendRef → InferencePool)
   → InferencePool(endpointPickerRef → EPP Service:9002)
   → EPP가 스코어링 후 최종 파드 선택
# HTTPRoute가 InferencePool을 가리키는지 확인
kubectl get httproute -n default inference-pool-with-httproute -oyaml
# spec.rules[].backendRefs에 kind: InferencePool 인지가 핵심 -
# kind: Service였다면 그냥 k8s 기본 로드밸런싱이지만, InferencePool이라서
# Envoy가 EPP ext-proc 스코어링 경로를 타게 된다.

# InferencePool 리소스 확인
kubectl get inferencepool -n default llama32-1b -o yaml
# endpointPickerRef가 어떤 EPP Service를 가리키는지 확인

# 트래픽 순서: 클라이언트 → Envoy(별도 파드) → EPP(별도 파드, gRPC 호출) → Envoy → 백엔드 파드

이렇게 리소스 단위로 하나씩 따라가 보면, InferencePool이라는 CRD 하나가 "일반 로드밸런싱이 아니라 EPP한테 라우팅을 물어보라"는 신호로 작동한다는 게 명확해진다.

마무리 - 지금까지 다룬 내용 정리

이 글은 LLM 트래픽에서 기존 HTTPRoute·L4 로드밸런싱이 부딪히는 한계(요청별 처리 시간 편차로 인한 핫스팟)에서 출발해, Kubernetes Gateway API Inference Extension이 이를 어떻게 풀어내는지 정리했다. 핵심 내용을 정리하면 다음과 같다.

  • 핵심 CRD 구조: InferenceModel이 "어떤 모델 요청을 어디로 매핑할지"를 정의하고, InferencePool이 그 모델을 서빙하는 실제 파드 집합과 가중치를 관리한다. HTTPRoute(또는 AIGatewayRoute)의 backendRefs가 Service 대신 InferencePool을 직접 참조하도록 바뀌는 게 핵심 변화다.
  • Agent Router 아키텍처: Envoy AI Gateway가 AAIF 산하 Agent Router로 이름을 바꾸며 정리된 Control Plane(Agent Router Ctrl + Envoy GW Ctrl)/Data Plane(Envoy Proxy + Ext Proc + Rate Limit Service) 구조를 확인했다.
  • EPP 내부 동작: 실제로 "어느 파드로 보낼지"를 결정하는 EPP는 Request Handler·Flow Control·Scheduler·Data Layer 구조로 이뤄지며, Filter→Score→Pick 3단계 스코어링으로 최종 파드를 고른다.
  • 설치·검증 실습: Kind 클러스터에 MetalLB로 LoadBalancer IP를 확보하고 Envoy Gateway·Agent Router 컨트롤러를 Helm으로 올린 뒤, HTTPRoute+InferencePool(단순 경로)과 AIGatewayRoute+InferencePool(다중 모델 경로) 두 가지 통합 방식을 실제 curl 호출로 검증했다.
  • 놓치기 쉬운 함정: OpenAI 호환 API는 요청 본문의 model 필드에 모델명을 담아 보내지만, Gateway API의 매치 규칙은 본문이 아니라 헤더만 검사한다. 본문에 모델명을 넣었다고 안심하지 말고 x-ai-eg-model 같은 헤더를 별도로 붙여야 라우팅이 실제로 동작한다.
  • 데이터 플레인 검증: Agent Router 데이터플레인이 세 개의 컨테이너로 구성돼 xDS 기반 무중단 설정 갱신을 지원한다는 내부 구조와, HTTPRoute → InferencePool → EPP로 이어지는 실제 연결을 kubectl로 직접 따라가며 검증하는 방법까지 다뤘다.

정리하고 보면, Gateway API Inference Extension의 핵심은 결국 "라우팅 결정에 필요한 정보를 얼마나 빠르고 정확하게 모으는가"의 문제로 수렴한다. InferencePool과 InferenceModel이 선언적인 뼈대를 제공한다면, 그 뼈대를 실제로 채우는 것은 EPP가 실시간으로 수집하는 파드 상태 정보이고, 그걸 검증하는 것은 결국 kubectl로 리소스 하나하나를 직접 따라가 보는 손에 잡히는 작업이라는 점이 이번 스터디에서 가장 눈여겨볼 지점이었다.