Dev.to AI 🤖 Ai 👁 0 📖 4 min read

Deploying LLM Models on a Kubernetes Cluster: Best Practices and Examples

Introduction We are building a support ticket triage agent that runs as a containerized service on Kubernetes. It accepts a customer message, classifies urgency and category, drafts a reply, and returns structured JSON.

Introduction

We are building a support ticket triage agent that runs as a containerized service on Kubernetes. It accepts a customer message, classifies urgency and category, drafts a reply, and returns structured JSON. Because Oxlo.ai uses flat per-request pricing instead of token-based billing, feeding the model long logs or full conversation histories does not inflate costs, which makes it a natural fit for a stateless microservice that scales with demand.

What you'll need

Before starting, make sure you have the following ready.

  • Python 3.10 or newer
  • Docker and a local or cloud Kubernetes cluster
  • kubectl configured to talk to your cluster
  • The OpenAI SDK installed: pip install openai fastapi uvicorn pydantic
  • An Oxlo.ai API key from https://portal.oxlo.ai

Step 1: Define the agent behavior

First, we will write the system prompt that tells the model how to classify tickets and draft replies. Keeping this in a separate constant makes it easy to iterate without touching the application code.

SYSTEM_PROMPT = """You are a support ticket triage agent. Your job is to analyze incoming customer messages and produce a JSON object with exactly three keys:
- "urgency": one of "low", "medium", "high", or "critical"
- "category": one of "billing", "technical", "account", or "general"
- "draft_reply": a polite, concise response that acknowledges the issue and sets expectations

Rules:
- Respond ONLY with the JSON object. No markdown, no explanation.
- If the user mentions downtime, data loss, or security, set urgency to "critical".
- Keep draft_reply under 150 words."""

Step 2: Build the FastAPI service

Next, we will write a small FastAPI application that receives a ticket, calls Oxlo.ai, and returns structured JSON. I am using the OpenAI SDK because Oxlo.ai is fully compatible, so the only change is the base URL. I picked Llama 3.3 70B because it handles tool-like instructions reliably, but you can swap in Qwen 3 32B or Kimi K2.6 without changing any other code.

import os
import json
from fastapi import FastAPI
from pydantic import BaseModel
from openai import OpenAI

app = FastAPI()

client = OpenAI(
    base_url="https://api.oxlo.ai/v1",
    api_key=os.environ.get("OXLO_API_KEY"),
)

SYSTEM_PROMPT = """You are a support ticket triage agent. Your job is to analyze incoming customer messages and produce a JSON object with exactly three keys:
- "urgency": one of "low", "medium", "high", or "critical"
- "category": one of "billing", "technical", "account", or "general"
- "draft_reply": a polite, concise response that acknowledges the issue and sets expectations

Rules:
- Respond ONLY with the JSON object. No markdown, no explanation.
- If the user mentions downtime, data loss, or security, set urgency to "critical".
- Keep draft_reply under 150 words."""

class TicketRequest(BaseModel):
    message: str

class TriageResponse(BaseModel):
    urgency: str
    category: str
    draft_reply: str

@app.post("/triage", response_model=TriageResponse)
async def triage_ticket(req: TicketRequest):
    response = client.chat.completions.create(
        model="llama-3.3-70b",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": req.message},
        ],
        temperature=0.2,
    )
    content = response.choices[0].message.content
    data = json.loads(content)
    return TriageResponse(**data)

Step 3: Containerize the application

Create a requirements file and a Dockerfile so Kubernetes can run the service uniformly anywhere.

Save this as requirements.txt:

openai
fastapi
uvicorn
pydantic

Save this as Dockerfile:

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY main.py .

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Step 4: Write the Kubernetes manifests

We need a Deployment to run the pods, a Service to route traffic, and a Secret to hold the Oxlo.ai API key. Keeping the key in a native Kubernetes Secret keeps it out of the image and out of source control.

apiVersion: v1
kind: Secret
metadata:
  name: oxlo.ai-secret
type: Opaque
stringData:
  api-key: YOUR_OXLO_API_KEY
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: triage-agent
spec:
  replicas: 2
  selector:
    matchLabels:
      app: triage-agent
  template:
    metadata:
      labels:
        app: triage-agent
    spec:
      containers:
        - name: agent
          image: triage-agent:latest
          ports:
            - containerPort: 8000
          env:
            - name: OXLO_API_KEY
              valueFrom:
                secretKeyRef:
                  name: oxlo.ai-secret
                  key: api-key
          resources:
            requests:
              memory: "256Mi"
              cpu: "250m"
            limits:
              memory: "512Mi"
              cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
  name: triage-agent-service
spec:
  selector:
    app: triage-agent
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8000
  type: ClusterIP

Step 5: Deploy to the cluster

Build the image, load it into your cluster if you are running locally, then apply the manifests. I am using minikube image load here, but if you are pushing to a registry, replace that step with docker push.

# Build the image
docker build -t triage-agent:latest .

# Load into minikube (skip if you use a remote registry)
minikube image load triage-agent:latest

# Apply manifests
kubectl apply -f deployment.yaml

# Wait for pods
kubectl rollout status deployment/triage-agent

Run it

Forward the service port locally and send a test ticket. The agent should return structured JSON with a drafted reply.

# Port forward in one terminal
kubectl port-forward service/triage-agent-service 8080:80

# Send a test request in another terminal
curl -X POST http://localhost:8080/triage \
  -H "Content-Type: application/json" \
  -d '{"message": "Our production database is down and we cannot process orders. This is urgent."}'

Example output:

{
  "urgency": "critical",
  "category": "technical",
  "draft_reply": "We have escalated this to our infrastructure team immediately. A senior engineer is investigating the database outage now. We will update you within 15 minutes with an ETA for restoration."
}

Wrap-up

From here, you can add a HorizontalPodAutoscaler to scale the deployment based on CPU or custom metrics as ticket volume grows. You can also experiment with other models on Oxlo.ai, such as DeepSeek V3.2 for coding-heavy tickets or Kimi K2.6 for advanced reasoning, without touching your cluster infrastructure.

📰 Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.