Skip to main content
Helm is the primary install path for the Tensormesh Operator. A single helm install command deploys the operator, registers the LMCacheEngine CRD, and (by default) creates an engine CR that the operator reconciles into a DaemonSet on your GPU nodes.
The chart is distributed through a private registry. To install it, request an access token from the Tensormesh team. You’ll use it to authenticate before installing (shown below).
If your target is OpenShift, install with Helm as described here and add the openshift.enabled=true flag — see Install on OpenShift for the full overlay.

Prerequisites

  • Helm 3.8 or newer (helm version)
  • Cluster access with permission to create cluster-scoped resources
  • A reachable Kubernetes 1.28+ cluster — see Getting Started
  • An access token from the Tensormesh team

Install

Authenticate to the registry with the token Tensormesh provided, then install:
# One-time: log in with the token Tensormesh gave you. When authenticating with a token,
# the username is not validated — any non-empty value works (we use "tensormesh" here).
echo '<TOKEN_FROM_TENSORMESH>' | helm registry login ghcr.io -u tensormesh --password-stdin

helm install tensormesh-operator \
  oci://ghcr.io/tensormesh-production/charts/tensormesh-operator \
  --version 0.4.5 \
  --namespace tensormesh-operator \
  --create-namespace \
  -f my-values.yaml \
  --wait
The login is stored locally, so subsequent helm upgrade/helm pull commands just work until you helm registry logout ghcr.io. Put all configuration in my-values.yaml (see Customizing the install) rather than --set flags, and pin explicit image tags there — never rely on latest.
For re-runs, use helm upgrade --install instead of helm install. The --install flag makes upgrade idempotent — it installs if missing, upgrades if present. Plain helm install errors with cannot reuse a name that is still in use on the second run.
If install fails, jump to Troubleshooting. Common failure modes covered there: CRD ownership conflict from a previous install (exists and cannot be imported), engine pod stuck Pending (missing GPU node label), ImagePullBackOff, and OpenShift CreateContainerError (missing openshift.enabled=true).
--wait blocks until the operator Deployment is Ready, so you don’t have to poll. Pair it with --timeout 5m on slow clusters.

Verify

1

The release exists

helm list -n tensormesh-operator
Example:
NAME                  NAMESPACE             REVISION  UPDATED                   STATUS    CHART                      APP VERSION
tensormesh-operator   tensormesh-operator   1         2026-05-24 02:05:00 UTC   deployed  tensormesh-operator-0.4.5  nightly-20260508-c7394b8
STATUS should be deployed.
2

The operator pod is Running

kubectl get pods -n tensormesh-operator
Example:
NAME                                  READY   STATUS    RESTARTS   AGE
tensormesh-operator-5f47f76bd6-bzmqf  1/1     Running   0          2m
3

The CRD is registered

kubectl get crd lmcacheengines.lmcache.lmcache.ai
Example:
NAME                              CREATED AT
lmcacheengines.lmcache.lmcache.ai 2026-05-24T02:04:10Z
4

An engine CR exists and is being reconciled

kubectl get lmcacheengines -n tensormesh-operator
kubectl describe lmcacheengine -n tensormesh-operator
Example:
NAME                                PHASE     READY   DESIRED   AGE
tensormesh-operator-default-engine  Running   1       1         2m
In kubectl describe, the healthy state is Phase: Running with 1/1 instances ready.
5

The engine DaemonSet landed on your GPU nodes

kubectl get pods -n tensormesh-operator -o wide \
  -l app.kubernetes.io/component=cache-engine
Example:
NAME                                      READY   STATUS    RESTARTS   AGE   IP            NODE
tensormesh-operator-default-engine-gfj2k  1/1     Running   0          2m    10.129.6.79   worker-gpu-a100-1
Expect one pod per GPU node. On a cluster with no GPU nodes this list is empty — which is correct, not a failure.
6

Run the bundled smoke tests

helm test tensormesh-operator -n tensormesh-operator
Example:
NAME: tensormesh-operator
LAST DEPLOYED: Sat May 24 02:05:00 2026
NAMESPACE: tensormesh-operator
STATUS: deployed
TEST SUITE:     tensormesh-operator-test-basic
Last Started:   2026-05-24 02:08:00 +0000 UTC
Last Completed: 2026-05-24 02:08:20 +0000 UTC
Phase:          Succeeded

Install modes

The chart toggles the operator and the engine independently, so the same chart supports several deployment shapes:
operator.enabledengine.enabledUse case
true (default)true (default)Single-tenant. Full stack from one release.
truefalseMulti-tenant. Operator only; tenants ship their own LMCacheEngine CRs.
falsetrueCR-only. Operator already running cluster-wide.
falsefalseCRDs-only. Use with crds.enabled=true to ship the schema alone.

Customizing the install

The chart exposes its full configuration through values.yaml. Keep your overrides in a values file (-f my-values.yaml) rather than --set flags — it’s reproducible, reviewable, and the place to pin explicit image tags. Common knobs:
my-values.yaml
operator:
  replicas: 1                       # leader-elected; set to 2 for HA standby
  # operator image is supplied by the chart version (--version 0.4.5); override only to test a build
  resources:
    requests: { cpu: 10m, memory: 256Mi }
    limits: { cpu: 500m, memory: 1Gi }
  serviceMonitor:
    enabled: false                   # set true if you run Prometheus Operator

engine:
  enabled: true
  spec:
    l1:
      sizeGB: 60                     # per-node L1 cache size
    image:
      repository: lmcache/vllm-openai
      tag: v0.4.5                     # pin explicitly (matches chart version)
      pullPolicy: IfNotPresent
    nodeSelector:
      nvidia.com/gpu.present: "true" # default selector — override for custom GPU labels

crds:
  enabled: true                      # set false to manage CRDs out-of-band

openshift:
  enabled: false                     # set true on OpenShift
Pin to immutable tags, never latest. Pin the chart with --version 0.4.5 (which selects the matched operator image) and the vLLM image with tag: v0.4.5. With imagePullPolicy: IfNotPresent, a node that already cached an image under a mutable tag like latest keeps the stale copy — so latest can silently run an old build. Immutable tags make the version deterministic.
Pass it with -f my-values.yaml on the install command above.
The chart ships a values.schema.json, so typos and wrong types are caught at parse time rather than at apply time. Run helm show values oci://ghcr.io/tensormesh-production/charts/tensormesh-operator --version 0.4.5 to see every available key with its default.

Upgrade

helm upgrade tensormesh-operator \
  oci://ghcr.io/tensormesh-production/charts/tensormesh-operator \
  --version 0.4.5 -n tensormesh-operator \
  -f my-values.yaml
Roll back if needed:
helm history tensormesh-operator -n tensormesh-operator
helm rollback tensormesh-operator <revision> -n tensormesh-operator

Uninstall

helm uninstall tensormesh-operator -n tensormesh-operator
A pre-delete hook removes the LMCacheEngine CR first so its finalizers run cleanly before the operator Deployment is torn down.
The CRD survives helm uninstall — same convention cert-manager and kube-prometheus-stack use. To remove it (and cascade-delete any remaining CRs):
kubectl delete crd lmcacheengines.lmcache.lmcache.ai

Next steps

Install on OpenShift

Add the privileged SCC binding required for hostIPC.

Modify Existing vLLM Deployment

Patch the workload you already run to consume the engine connection ConfigMap.

Troubleshooting

Engine Pending, ImagePullBackOff, hung uninstalls, and more.