LMCacheEngine custom
resources into a DaemonSet of LMCache cache servers, and — when observability is
enabled — wires those engines to an OpenTelemetry Collector that fans metrics and
traces out to Prometheus and Tempo.
What gets created, and by whom
Every piece follows the same pattern: the chart writes a declaration (a CR); a controller reconciles it into a running thing. The chart runs exactly one controller itself — the Tensormesh Operator. The Collector and Tempo are reconciled by operators you pre-install; the chart only submits their CRs. This table is the precise “which thing belongs where”:| Declaration (the chart creates this) | Reconciled by | Becomes | Scope |
|---|---|---|---|
LMCacheEngine CR | Tensormesh Operator (this chart) | engine DaemonSet — 1 pod per GPU node | Namespaced |
OpenTelemetryCollector CR | OpenTelemetry Operator (prerequisite) | OTel Collector pod | Namespaced |
TempoMonolithic CR | Tempo Operator (prerequisite) | Tempo instance | Namespaced |
ServiceMonitor | Prometheus Operator (prerequisite) | a scrape target (no new pod) | Namespaced |
CRD lmcacheengines.lmcache.lmcache.ai | — (registered with the API server) | defines the LMCacheEngine kind | Cluster |
Deployment (no CR needed) and owns the
engine DaemonSet’s lifecycle.
Data flow
| Hop | Transport | Port |
|---|---|---|
| vLLM → engine | shared-memory IPC (hostIPC) | — (same node) |
| engine → Collector | OTLP gRPC | 4317 |
| Collector → Prometheus | scrape of the Collector’s exporter | 8889 |
| Collector → itself | otelcol_* internal metrics | 8888 |
| Collector → Tempo / external | OTLP | per backend |
Resources the chart creates
Everything the chart can render, with its scope — this is the table to consult before a cleanup, because cluster-scoped resources survive a namespace delete and must be removed explicitly.| Resource | API group | Scope | Created when | Cleanup notes |
|---|---|---|---|---|
CustomResourceDefinition lmcacheengines.lmcache.lmcache.ai | apiextensions.k8s.io | Cluster | crds.enabled (default true) | ⚠️ Kept on helm uninstall (resource-policy: keep). Survives namespace delete. Remove with kubectl delete crd …. |
| ClusterRole (operator) | rbac.authorization.k8s.io | Cluster | operator.rbac.create | ⚠️ Survives namespace delete — sweep manually. |
| ClusterRoleBinding (operator) | rbac.authorization.k8s.io | Cluster | operator.rbac.create | ⚠️ Survives namespace delete — sweep manually. |
| ClusterRole / ClusterRoleBinding (pre-delete hook) | rbac.authorization.k8s.io | Cluster | helm uninstall hook | Created and removed by the hook; can orphan if uninstall fails mid-way. |
LMCacheEngine (CR) | lmcache.lmcache.ai/v1alpha1 | Namespaced | engine.enabled (default true) | Has a lmcache.ai/cleanup finalizer — if the operator is gone, it blocks namespace deletion. See troubleshooting. |
OpenTelemetryCollector (CR) | opentelemetry.io | Namespaced | observability.enabled | Goes with the namespace. |
TempoMonolithic (CR) | tempo.grafana.com | Namespaced | observability.traces.tempoCR.enabled | Goes with the namespace. |
ServiceMonitor (CR) | monitoring.coreos.com | Namespaced | operator.serviceMonitor.enabled and/or observability.prometheus.serviceMonitor.enabled | Goes with the namespace. |
| Deployment (controller-manager) | apps | Namespaced | operator.enabled | Goes with the namespace. |
| DaemonSet (engine) | apps | Namespaced | created by the operator from the CR | Removed when the CR/namespace is. |
| Service (metrics) | core | Namespaced | operator.enabled | Goes with the namespace. |
| ServiceAccount (operator) | core | Namespaced | operator.serviceAccount.create | Goes with the namespace. |
| Role / RoleBinding (operator) | rbac.authorization.k8s.io | Namespaced | operator.rbac.create | Goes with the namespace. |
| ServiceAccount + RoleBinding (privileged SCC) | core / rbac… | Namespaced | openshift.enabled | Goes with the namespace. Binds to the built-in system:openshift:scc:privileged ClusterRole — do not delete that. |
| NetworkPolicy | networking.k8s.io | Namespaced | operator.networkPolicy.enabled | Goes with the namespace. |
| Job + ServiceAccount + Role + RoleBinding (pre-delete hook) | batch / core / rbac… | Namespaced | helm uninstall hook | Transient; removed after the hook runs. |
The three things a namespace delete leaves behind
If youkubectl delete namespace instead of helm uninstall, these cluster-scoped
resources orphan and need explicit cleanup:
- CRD
lmcacheengines.lmcache.lmcache.ai - ClusterRole for the operator
- ClusterRoleBinding for the operator
LMCacheEngine finalizer first).
Next steps
Configuration
Every
values.yaml key and example overlays.Observability
The OTel Collector / Tempo / Prometheus wiring in detail.

