Overview
vLLM is a high-throughput inference server for open-weight large language models. This template serves one Hugging Face model through vLLM’s OpenAI-compatible API (/v1/chat/completions, /v1/completions, /v1/models) on an NVIDIA GPU: either one of Control Plane’s built-in A10G or T4 cards, or your own GPU cluster registered as a BYOK location. The API is protected by an API key you create before installing, and the downloaded model is cached on a persistent volume so restarts do not download it again.
What Gets Created
Prerequisites
Create the API key secret
apiKey.secretName to this name.Make a GPU available
gpu.type: builtin, the default). Your org needs GPU quota in a location that offers it — by default one NVIDIA A10G with 6 vCPU and 16 GiB of memory. Ask Control Plane support to enable it. A T4 is the other built-in choice (gpu.model: t4).Your own GPU cluster (gpu.type: byok). Any Kubernetes cluster registered as a Control Plane BYOK location works: an MK8s cluster with the BYOK add-on enabled, or a cluster you already run (EKS, GKE, AKS, on-premises). A cluster that is not registered as a location cannot run this template. See GPU Cluster Setup (BYOK) for what each cluster type needs.Optional - create a Hugging Face token secret for gated models
huggingFace.tokenSecretName to this name. Without license access the replica restarts with exit code 1 (see Troubleshooting).GPU Cluster Setup (BYOK)
Every cluster used withgpu.type: byok needs:
- NVIDIA GPU nodes with driver 580 or newer (the image is a CUDA 13 build) and a device plugin that exposes
nvidia.com/gpu. - A RuntimeClass named
nvidia. The template always requests it, and its handler differs per cluster type (see below). Without it the install fails withThe GPU runtime class nvidia is not supported in this cluster. If you add it after installing BYOK, restart BYOK’s actuator, which does not see new runtime classes until then:kubectl rollout restart deploy/actuator -n controlplane. - No taint on the GPU nodes. Control Plane workloads do not tolerate it.
- The GPU node label
cpln.io/gpuUsageAutoDrain: ignore. Otherwise BYOK drains a GPU node that has had no GPU pod for 5 minutes, including one where vLLM is still starting. - A GPU node boot disk of at least 200 GB. The vLLM image and the model otherwise fill the disk and the node evicts vLLM.
resourcessized to the node. A 4-vCPU GPU node (g5.xlarge, g6.xlarge, g2-standard-4, Standard_NC4as_T4_v3) cannot fit the built-in default of 6 CPU and the replica stays pending; use aboutcpu: 2000mandmemory: 8Gi.- A GVC whose only location is the BYOK location. On a Control Plane location the GPU request is ignored and vLLM cannot start.
MK8s on AWS
MK8s on AWS
- NVIDIA add-on with
taintGPUNodes: false. - An x86 NVIDIA-driver node image (an AWS Deep Learning AMI) plus the label
mk8s.cpln.io/accelerator: nvidia. The recommended+nvidiaimages currently resolve to arm64 and cannot boot GPU instances, and with a custom image the device plugin only runs on nodes carrying that label. - One instance type per GPU node pool.
- The
nvidiaRuntimeClass is built in.
MK8s on GCP
MK8s on GCP
- NVIDIA add-on with
taintGPUNodes: false. - A driver image on the GPU pool:
overrideImage.familywith projectdeeplearning-platform-releaseand familycommon-cu129-ubuntu-2404-nvidia-580, plus the labelmk8s.cpln.io/accelerator: nvidia. - Only machine types with a built-in GPU work (G2 with L4, A2, A3). GCP node pools have no accelerator field, so a T4 or V100 on an N1 machine is not possible.
- The
nvidiaRuntimeClass and the cloud load balancer work with no extra setup.
EKS
EKS
- The Amazon Linux 2023 NVIDIA AMI for the GPU node group;
eksctlselects it for GPU instance types and installs the device plugin. - RuntimeClass
nvidiawith handlernvidia. - The AWS Load Balancer Controller. BYOK’s ingress requests an
externalnetwork load balancer and gets no address without it. Installing its Helm chart after BYOK needs--disable-openapi-validation.
GKE
GKE
- A GPU node pool with
gpu-driver-version=latest, so GKE installs the driver. - RuntimeClass
nvidiawith handlerrunc. GKE has nonvidiahandler; it injects the driver itself. - On N1 machines (the only T4 family), replace BYOK’s storage classes. They create Hyperdisk volumes, which N1 machines cannot attach. Set
byok.noDefaultStorageClasses: trueincluster.jsonof the ConfigMapcpln-byok-currentinkube-system, restartdeploy/cpln-byok-agent -n kube-system, and create your owngeneral-purpose-ssd-ext4storage class onpd-balanced. Machines with a built-in GPU (G2) attach Hyperdisk without this. - If the BYOK install stalls with
istiodnever created, restartdeploy/cpln-byok-agent -n kube-system.
AKS
AKS
- A GPU node pool in an availability zone (for example
--zones 1). BYOK’s storage classes use Premium SSD v2, which Azure attaches only to zonal VMs; on a non-zonal pool the volume fails withcan be used only with Virtual Machines in an Availability Zone. - The default
--gpu-driver Install, which installs driver 580. - The NVIDIA device plugin. AKS does not install it. Give the GPU pool the label
nvidia.com/gpu.present=trueso the plugin’s Helm chart schedules there. - RuntimeClass
nvidiawith handlernvidia-container-runtime.
Installation
Install with the name of your API key secret:UI
CLI
Terraform
Pulumi
Configuration
Image
Model
The model is downloaded into the volume on first start. Any extravllm serve flag goes in extraArgs (see the engine arguments).
Credentials
Both are names of opaque secrets you create first (see Prerequisites); the key values never enter the Helm release.GPU
builtin uses Control Plane’s GPU locations; byok runs on your own NVIDIA nodes on a BYOK location (see GPU Cluster Setup (BYOK) for the cluster requirements). The built-in form cannot target BYOK nodes.
Resources and Scaling
The chart refuses CPU and memory combinations the GPU type does not allow; the comments list the limits. Each replica is an independent server with its own GPUs and its own model cache.Model Cache
capacity sizes new volumes only; to grow a live one, see Growing the Model Cache.
Access
The API key guards/v1 whether or not public access is on.
Connecting
VLLM_API_KEY, send a chat request with the default model:
base_url set to the /v1 address and api_key set to the key. The LiteLLM template can also use vLLM as an OpenAI-compatible backend.
Pairing with Open WebUI
For a chat UI, install the Open WebUI template (1.3.0 or later) in the same GVC and point its OpenAI-compatible backend athttp://RELEASE_NAME-vllm.GVC_NAME.cpln.local:8000/v1, reusing your vLLM API key secret. The exact values are on the Open WebUI page under Pairing with vLLM. On the vLLM side:
- Keep
model.toolCallParserset and matched to your model. Open WebUI offers tools on every chat, so without a parser each message fails with"auto" tool choice requires --enable-auto-tool-choice. - The default model and its 8192-token context are fine for chat.
- Open WebUI’s Control Plane tools need a context of at least 64k tokens. Qwen2.5-7B-Instruct reaches 64k with YaRN:
internalAccess.type: same-gvc does.
Operations
Backing Up
There is nothing to back up. The volume holds only downloaded model weights and vLLM’s compile cache, which a replica downloads or rebuilds on start, so the chart keeps no snapshots.Rotating the API Key
A running replica keeps the old key until it restarts. Replace the secret’s value, then force a redeployment. Save this asrotate.yaml:
Growing the Model Cache
Changingvolumeset.capacity does not resize an existing volume; it only sizes new ones. Grow a live volume online, with no restart, once per replica (--volume-index 0 for the first replica, 1 for the second, and so on):
Freeing Old Model Weights
Switchingmodel.name leaves the old model’s weights on the volume. Remove them with the Hugging Face CLI in the image, replacing ORG/NAME with the old model id:
Scaling and Availability
Withreplicas: 1 (the default) the API is down whenever the replica restarts, which includes every upgrade and setting change. Set replicas: 2 for zero-downtime restarts and upgrades; replicas are independent servers behind the workload’s load-balanced endpoint and are replaced one at a time. Each replica needs its own GPU and its own model cache volume, so check your GPU quota first.
gpu.quantity above 1 splits the model across several GPUs in one replica (tensor parallelism) rather than adding replicas; on built-in GPUs only the T4 allows it.
Troubleshooting
The deployment waits and cpln logs shows nothing
The deployment waits and cpln logs shows nothing
cpln logs returns no lines.Cause: The secret named in apiKey.secretName (or huggingFace.tokenSecretName) does not exist, so the container never starts.Fix: Read status.versions[].message, which names the missing secret, then create it as in Prerequisites. The deployment recovers by itself once it exists:A gated model restarts with exit code 1
A gated model restarts with exit code 1
GatedRepoError.Cause: A 401 means no token was supplied (huggingFace.tokenSecretName is empty). A 403 with “not in the authorized list” means the account that owns the token has not been granted access to the model.Fix: Accept the model’s license on huggingface.co with the token’s account, wait for access to be granted, and set huggingFace.tokenSecretName. To find the error:Chat requests fail with an auto tool choice error
Chat requests fail with an auto tool choice error
"auto" tool choice requires --enable-auto-tool-choice.Cause: model.toolCallParser is empty, or does not match the model family.Fix: Set model.toolCallParser to the parser for your model: hermes (Qwen), llama3_json (Llama 3) or mistral.The replica restarts before it becomes ready
The replica restarts before it becomes ready
startupTimeoutSeconds.Fix: Raise startupTimeoutSeconds (up to 1830) for large models.A replica stays pending
A replica stays pending
resources to the node (about cpu: 2000m, memory: 8Gi on a g5.xlarge or g6.xlarge). On a T4, use about cpu: 3000m and memory: 12Gi.The install fails with a GPU runtime class error on BYOK
The install fails with a GPU runtime class error on BYOK
The GPU runtime class nvidia is not supported in this cluster.Cause: The cluster has no RuntimeClass named nvidia, or BYOK’s actuator has not seen it yet.Fix: Create the RuntimeClass with your cluster’s handler (see GPU Cluster Setup (BYOK)), then restart the actuator:The model volume never attaches on a BYOK GPU node
The model volume never attaches on a BYOK GPU node
Init and Kubernetes events show FailedAttachVolume.Cause: The GPU node cannot attach BYOK’s default disk type: Hyperdisk on a GKE N1 machine, or Premium SSD v2 on a non-zonal AKS node.Fix: On AKS, put the GPU node pool in an availability zone. On GKE N1, replace BYOK’s storage classes as described in GPU Cluster Setup (BYOK).Port-forward returns 502 on a BYOK location
Port-forward returns 502 on a BYOK location
cpln port-forward returns 502 Unable to connect to upstream workload.Cause: On a BYOK location, port-forward needs internalAccess.type other than none.Fix: Set internalAccess.type to same-gvc (the default) or another allowed type.Important Notes
- Create the API key secret before installing. A missing secret stalls the install with no logs;
status.versions[].messagenames it. - The API key protects only
/v1. vLLM leaves/health,/metrics,/tokenizeand/detokenizeunauthenticated, so with public access on anyone can read metrics and use the tokenizer. - Use a GVC with exactly one location. Every location runs its own copy with its own GPUs, and on BYOK the only location must be the BYOK location.
- Rotating the API key needs a forced redeployment. The running server keeps the old key until it restarts — see Rotating the API Key.
- With one replica the API is down during every restart and upgrade. Set
replicas: 2for zero downtime; each replica needs its own GPU. volumeset.capacityonly sizes new volumes, and switching models keeps the old weights. See Growing the Model Cache and Freeing Old Model Weights.
External References
vLLM on GitHub
OpenAI-Compatible Server
Engine Arguments
vllm serve flag you can pass through model.extraArgs