Skip to main content

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.
This template deploys into an existing GVC that you already have. It does not create, provision, or manage a GVC. Use a GVC with exactly one location: every location of the GVC runs its own copy of the server, each with its own GPUs.

What Gets Created

vLLM has no browser UI. For a chat UI, pair it with the Open WebUI template (see Pairing with Open WebUI).

Prerequisites

1

Create the API key secret

Clients send this key as a Bearer token. It is an opaque secret and must exist before you install:
Set apiKey.secretName to this name.
2

Make a GPU available

Built-in GPU (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. The cluster needs NVIDIA GPU nodes with driver 580 or newer (the image is a CUDA 13 build), a device plugin that exposes nvidia.com/gpu, a nvidia runtime class, and no taint on the GPU nodes, because Control Plane workloads do not tolerate it.Only MK8s has been tested. As an example, on an MK8s cluster on AWS that means:
  • NVIDIA add-on with taintGPUNodes: false — with the taint on, nothing can use the GPU.
  • GPU node pool 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.
  • An x86 NVIDIA-driver node image plus the label mk8s.cpln.io/accelerator: nvidia — the recommended +nvidia images currently resolve to arm64 and cannot boot GPU instances; with a custom image the device plugin only runs on nodes carrying that label.
  • A GPU node boot disk of at least 200 GB — the driver image, the vLLM image and the model otherwise fill the disk and the node evicts vLLM.
  • One instance type per GPU node pool.
  • resources sized to the node — a 4-vCPU / 16 GiB GPU node (g5.xlarge, g6.xlarge) cannot fit the built-in default of 6 CPU; use about cpu: 2000m and memory: 8Gi.
Use a GVC whose only location is the BYOK location: on a Control Plane location the GPU request is ignored and vLLM cannot start.
3

Optional - create a Hugging Face token secret for gated models

Gated models such as Llama or Gemma need a Hugging Face token. Accept the model’s license on its huggingface.co page with the account that owns the token, and wait until the page shows access granted (some, like Llama, are reviewed by hand). Create a read token (a fine-grained token needs read access to public gated repos), then store it:
Set huggingFace.tokenSecretName to this name. Without license access the replica restarts with exit code 1 (see Troubleshooting).
If a secret named in apiKey.secretName or huggingFace.tokenSecretName does not exist, the deployment waits silently and cpln logs shows nothing. Read status.versions[].message, which names the missing secret:
Once the secret exists the deployment recovers by itself, which can take up to about 10 minutes; keep polling.

Installation

Install with the name of your API key secret:
The first start pulls a large image and then downloads and loads the model, so allow several minutes before the API answers.

UI

Browse, install, and manage templates visually

CLI

Manage templates from your terminal

Terraform

Declare templates in your Terraform configurations

Pulumi

Declare templates in your Pulumi programs

Configuration

Image

Model

The model is downloaded into the volume on first start. Any extra vllm 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 Prerequisites 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

With the port-forward running and the key in VLLM_API_KEY, send a chat request with the default model:
Any OpenAI SDK works with 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 at http://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.toolCallParser set 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:
vLLM must also allow Open WebUI as a caller; the default 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 as rotate.yaml:
With one replica the API is unavailable while the replica restarts; with two or more it keeps serving.

Growing the Model Cache

Changing volumeset.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

Switching model.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:
Deleting the model’s folder by hand frees nothing, because the weights live in a shared blob store.

Scaling and Availability

With replicas: 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

Symptom: The workload never becomes ready and 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:
Symptom: The replica restarts with exit code 1, and the logs show 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:
Symptom: Every message from Open WebUI or an agent client fails with "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.
Symptom: A large model never finishes loading; the replica restarts and starts the download or load again.Cause: The replica was not ready within startupTimeoutSeconds.Fix: Raise startupTimeoutSeconds (up to 1830) for large models.
Symptom: The replica is never scheduled.Cause: The requested CPU and memory do not fit the GPU node. On a BYOK 4-vCPU node the built-in default of 6 CPU cannot fit. On a built-in T4, larger requests the chart accepts (such as the 6000m / 16Gi default) did not schedule in testing.Fix: On BYOK, size 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.
Symptom: 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[].message names it.
  • The API key protects only /v1. vLLM leaves /health, /metrics, /tokenize and /detokenize unauthenticated, 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: 2 for zero downtime; each replica needs its own GPU.
  • volumeset.capacity only 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

Source, releases, and issues for the vLLM project

OpenAI-Compatible Server

The API this template serves, including tool calling

Engine Arguments

Every vllm serve flag you can pass through model.extraArgs

Supported Models

Model architectures vLLM can serve

vLLM Template

View the source files, default values, and chart definition