Kubernetes 操作器#

LMCache Kubernetes 操作符自动化了 LMCache 多进程服务器的部署和生命周期管理。您只需声明一个 LMCacheEngine 自定义资源,操作符将协调所有底层的 Kubernetes 对象,而无需手动编写 DaemonSets、Services 和 ConfigMaps(如手册 部署指南 指南中所述)。

为什么使用操作器#

手动 DaemonSet 方法可以工作,但它有一些操作员消除的尖锐边缘:

  • 自动注入的 Pod 设置 -- 操作器始终设置 hostIPC: true--host 0.0.0.0。在手动编写的清单中忘记 hostIPC 会导致难以调试的静默 CUDA IPC 失败 (cudaErrorMapBufferObjectFailed)。

  • 节点本地服务发现 -- 操作员创建一个 ClusterIP 服务,设置 internalTrafficPolicy=Local,并创建一个连接的 ConfigMap,vLLM pod 只需挂载它。没有 hostNetwork,没有向下 API,没有 shell 变量替换。

  • 自动计算资源大小 -- 内存请求和限制来自 l1.sizeGB,避免了 OOM 杀死(资源不足)或浪费节点容量(资源过剩)。

  • 声明式 Prometheus 集成 -- 设置 prometheus.serviceMonitor.enabled: true,操作符会创建一个 ServiceMonitor CR,Prometheus 操作符会自动发现它。

  • CRD 验证 -- OpenAPI 架构验证在 kubectl apply 时捕获配置错误(例如,l1.sizeGB <= 0,无效的端口范围),在创建任何 pod 之前。

先决条件#

  • Kubernetes 1.20+

  • kubectl 配置为访问您的集群

  • (可选) Prometheus Operator 以支持 ServiceMonitor

安装 Operator#

选项 A:从发布版一行安装(推荐)

# Latest stable release
kubectl apply -f https://github.com/LMCache/LMCache/releases/download/operator-latest/install.yaml

# Or nightly build from the dev branch
kubectl apply -f https://github.com/LMCache/LMCache/releases/download/operator-nightly-latest/install.yaml

选项 B:从源代码构建

cd operator
make build
make install
make deploy IMG=<your-registry>/lmcache-operator:latest

部署 LMCacheEngine#

一个最小的 CR 在每个 GPU 节点上部署一个具有 60 GB L1 缓存的 DaemonSet:

apiVersion: lmcache.lmcache.ai/v1alpha1
kind: LMCacheEngine
metadata:
  name: my-cache
spec:
  l1:
    sizeGB: 60
kubectl apply -f lmcache-engine.yaml

操作符自动:

  • 在每个匹配的节点上创建一个运行 LMCache 服务器 Pod 的 DaemonSet

  • 设置 hostIPC: true 并将 --host 0.0.0.0 传递给服务器

  • 为 vLLM 发现创建一个节点本地的 ClusterIP 服务

  • 创建一个连接 ConfigMap (my-cache-connection),其中包含 vLLM 所需的 kv-transfer-config JSON。

  • 自动计算 L1 缓存大小的资源请求/限制

  • 默认将 nodeSelector 设置为 nvidia.com/gpu.present: \"true\"

备注

该操作符将容器镜像默认设置为 lmcache/vllm-openai:latest。可以通过 spec.image.repositoryspec.image.tag 来覆盖,以固定特定版本。

连接 vLLM#

操作符创建一个名为 <engine-name>-connection 的 ConfigMap,其中包含 kv-transfer-config JSON。将其挂载到您的 vLLM 部署中:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm
spec:
  replicas: 1
  selector:
    matchLabels:
      app: vllm
  template:
    metadata:
      labels:
        app: vllm
    spec:
      # Required for CUDA IPC between vLLM and LMCache
      hostIPC: true
      containers:
        - name: vllm
          image: lmcache/vllm-openai:latest
          env:
            # Deterministic hashing required by LMCache
            - name: PYTHONHASHSEED
              value: "0"
          command: ["/bin/sh", "-c"]
          args:
            - |
              exec python3 -m vllm.entrypoints.openai.api_server \
                --model <your-model> \
                --port 8000 \
                --gpu-memory-utilization 0.8 \
                --kv-transfer-config "$(cat /etc/lmcache/kv-transfer-config.json)"
          ports:
            - name: http
              containerPort: 8000
          volumeMounts:
            - name: kv-transfer-config
              mountPath: /etc/lmcache
              readOnly: true
          resources:
            limits:
              nvidia.com/gpu: "1"
      volumes:
        - name: kv-transfer-config
          configMap:
            name: my-cache-connection  # <engine-name>-connection

vLLM Pod 的关键要求:

  • hostIPC: true -- CUDA IPC (cudaIpcOpenMemHandle) 需要在 vLLM 和 LMCache 之间共享 IPC 命名空间。

  • PYTHONHASHSEED=0 -- 确保确定性令牌哈希,以便 vLLM 和 LMCache 生成一致的缓存键。

  • ConfigMap挂载 -- $(cat ...) 模式在线读取连接 JSON。ConfigMap 名称始终为 <LMCacheEngine name>-connection

  • 不需要 hostNetwork -- 操作员的节点本地服务通过 internalTrafficPolicy=Local 处理路由。

验证部署#

# Check LMCacheEngine status
kubectl get lmc

预期输出:

NAME       PHASE     READY   DESIRED   AGE
my-cache   Running   3       3         5m
# Check the connection ConfigMap
kubectl get configmap my-cache-connection -o yaml

# Check LMCache pods
kubectl get pods -l app.kubernetes.io/managed-by=lmcache-operator

# Check detailed status with endpoints
kubectl describe lmc my-cache

CRD 规格参考#

图像#

字段

默认

描述

image.repository

lmcache/vllm-openai

容器镜像仓库。

image.tag

latest

容器镜像标签。

image.pullPolicy

如果不存在

Always, Never, 或 IfNotPresent

imagePullSecrets

--

镜像拉取密钥引用。

服务器#

字段

默认

描述

server.port

5555

ZMQ 监听端口 (1024--65535)。

server.chunkSize

256

令牌块大小。

server.maxWorkers

1

ZMQ 请求的工作线程。

server.hashAlgorithm

blake3

builtin, sha256_cbor, 或 blake3

L1 缓存#

字段

默认

描述

l1.sizeGB

必需

L1 缓存大小(以 GB 为单位)。必须大于 0。

逐出#

字段

默认

描述

eviction.policy

LRU

仅支持 LRU

eviction.triggerWatermark

0.8

触发逐出的使用比例 (0.0--1.0]。

eviction.evictionRatio

0.2

逐出比例 (0.0--1.0]。

普罗米修斯#

字段

默认

描述

prometheus.enabled

true

暴露 Prometheus 指标。

prometheus.port

9090

/metrics 端口。

prometheus.serviceMonitor.enabled

false

创建一个 ServiceMonitor CR。

prometheus.serviceMonitor.interval

30s

抓取间隔。

prometheus.serviceMonitor.labels

--

ServiceMonitor上的额外标签。

L2 存储#

字段

默认

描述

l2Backends

--

L2 后端列表 (type + config)。请参见 L2 存储(持久缓存)

调度#

字段

默认

描述

nodeSelector

GPU 节点

默认为 nvidia.com/gpu.present: \"true\"

affinity

--

Pod 亲和性规则。

tolerations

--

Pod 容忍。

priorityClassName

--

用于 Pods 的优先级类。

覆盖与额外选项#

字段

默认

描述

logLevel

INFO

DEBUG, INFO, WARNING, ERROR

resourceOverrides

--

覆盖自动计算的资源。

env

--

额外的环境变量。

volumes

--

额外的卷。

volumeMounts

--

额外的卷挂载。

podAnnotations

--

额外的 pod 注释。

podLabels

--

额外的 pod 标签。

serviceAccountName

--

用于 pods 的 ServiceAccount。

extraArgs

--

额外的 CLI 标志(最后附加,可以覆盖)。

自动计算资源#

spec.resourceOverrides 未设置时,操作符从 l1.sizeGB 派生资源:

  • CPU 请求: 4 核心

  • 内存请求: ceil(l1.sizeGB + 5) Gi

  • 内存限制: ceil(memoryRequest * 1.5) Gi

例如,l1.sizeGB: 60 会产生 65 Gi 的请求和 98 Gi 的限制。

自动注入的 Pod 设置#

操作符始终将这些注入到 Pod 规格中(它们无法通过 CRD 配置):

  • hostIPC: true -- 这是在 LMCache 和 vLLM 之间进行 CUDA IPC 所必需的。

  • --host 0.0.0.0 -- 将服务器绑定到所有接口,以便节点本地服务可以路由到它。

  • NVIDIA_VISIBLE_DEVICES=all -- 确保 GPU 可用于基于 IPC 的内存传输。

  • TCP socket 探测 -- 启动(初始 5 秒,30 次失败)、存活(10 秒)和就绪(5 秒)探测在服务器端口上。

备注

操作符**不**在 /dev/shm 挂载 emptyDir。使用 hostIPC: true 时,容器直接访问主机的 /dev/shm。挂载 emptyDir 会用私有 tmpfs 进行遮蔽,从而破坏 CUDA IPC。

创建的资源#

对于名为 my-cacheLMCacheEngine

资源

名称

目的

守护进程集

my-cache

运行 LMCache 服务器 Pod。

服务 (ClusterIP)

my-cache

节点本地发现(internalTrafficPolicy=Local)。

无头服务

my-cache-metrics

Prometheus 抓取目标。

ConfigMap

my-cache-connection

kv-transfer-config vLLM 的 JSON。

服务监控器

my-cache

启用时的 Prometheus Operator 集成。

连接 ConfigMap 包含:

{
  "kv_connector": "LMCacheMPConnector",
  "kv_role": "kv_both",
  "kv_connector_extra_config": {
    "lmcache.mp.host": "tcp://my-cache.default.svc.cluster.local",
    "lmcache.mp.port": "5555"
  }
}

状态与条件#

kubectl describe lmc my-cache

状态部分包括:

  • phase: 待处理, 运行中, 降级, 或 失败

  • readyInstances / desiredInstances: 实例计数。

  • endpoints: 每个节点的连接信息(节点名称、主机 IP、Pod 名称、端口、就绪状态)。

  • 条件

    • 可用 -- 至少有一个实例已准备好。

    • AllInstancesReady -- 所有期望的实例都已准备好。

    • ConfigValid -- 配置验证通过。

验证规则#

操作符在应用时验证 CR 规格:

字段

规则

l1.sizeGB

必需,必须 > 0。

eviction.policy

必须是 ``LRU``(如果设置)。

eviction.triggerWatermark

必须在 (0.0, 1.0] 之间。

eviction.evictionRatio

必须在 (0.0, 1.0] 之间。

server.port

必须在 [1024, 65535] 之间。

示例#

仅目标 GPU 节点#

使用 nodeSelector 仅在 GPU 节点上运行 LMCache。新的 GPU 节点会自动获得一个 LMCache pod:

apiVersion: lmcache.lmcache.ai/v1alpha1
kind: LMCacheEngine
metadata:
  name: my-cache
spec:
  nodeSelector:
    nvidia.com/gpu.present: "true"
  l1:
    sizeGB: 60

备注

操作符默认将 nodeSelector 设置为 nvidia.com/gpu.present: \"true\",当未指定时,因此最小的 CR 已经针对 GPU 节点。

自定义服务器端口#

如果默认端口(5555)与其他服务冲突:

apiVersion: lmcache.lmcache.ai/v1alpha1
kind: LMCacheEngine
metadata:
  name: my-cache
spec:
  server:
    port: 6555
  l1:
    sizeGB: 60

连接 ConfigMap 会自动更新 -- vLLM pods 在重启时会获取新端口。

使用 Prometheus 监控的生产环境#

apiVersion: lmcache.lmcache.ai/v1alpha1
kind: LMCacheEngine
metadata:
  name: production-cache
  namespace: llm-serving
spec:
  nodeSelector:
    nvidia.com/gpu.present: "true"
  image:
    repository: lmcache/standalone
    tag: v0.1.0
  server:
    port: 6555
    chunkSize: 256
    maxWorkers: 4
  l1:
    sizeGB: 60
  eviction:
    triggerWatermark: 0.8
    evictionRatio: 0.2
  prometheus:
    enabled: true
    port: 9090
    serviceMonitor:
      enabled: true
      labels:
        release: kube-prometheus-stack
  podAnnotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "9090"
  priorityClassName: system-node-critical

请参阅 可观察性 以获取指标名称和 Grafana 配置。

覆盖自动计算的资源#

apiVersion: lmcache.lmcache.ai/v1alpha1
kind: LMCacheEngine
metadata:
  name: my-cache
spec:
  l1:
    sizeGB: 60
  resourceOverrides:
    requests:
      memory: "70Gi"
      cpu: "8"
    limits:
      memory: "100Gi"

操作员与手动部署#

关注

手动 DaemonSet

LMCacheEngine Operator

hostIPC

必须手动设置

自动注入

--host 0.0.0.0

必须手动设置

自动注入

服务发现

hostNetwork + status.hostIP

节点本地 ClusterIP 服务 + ConfigMap

vLLM 配置

将 JSON 复制到部署中

挂载 <name>-connection ConfigMap

资源大小调整

手动计算

l1.sizeGB 自动计算

普罗米修斯

手动 ServiceMonitor

serviceMonitor.enabled: true

验证

仅限运行时错误

kubectl apply 拒绝无效的规格

新的 GPU 节点

DaemonSet 处理它

DaemonSet 处理它(相同)

安全考虑事项#

hostIPC 将主机的 IPC 命名空间(System V IPC,POSIX 消息队列)暴露给容器。容器中的任何进程都可以与同一主机上其他进程的 IPC 资源进行交互。

  • 仅在受信任的环境中部署。

  • 使用 Pod 安全标准的集群必须允许 LMCache 命名空间的 privileged 配置文件 -- baselinerestricted 配置文件拒绝 hostIPC

开发#

make generate     # Generate DeepCopy methods
make manifests    # Generate CRD YAML + RBAC
make build        # Compile operator binary
make fmt          # go fmt
make vet          # go vet
make test         # Run unit tests
make lint         # Run golangci-lint

推送自定义操作符镜像:

# Docker Hub
make docker-build docker-push IMG=docker.io/<your-user>/lmcache-operator:latest
make deploy IMG=docker.io/<your-user>/lmcache-operator:latest

# Multi-platform (amd64 + arm64)
make docker-buildx IMG=<your-registry>/lmcache-operator:latest

如果您的集群需要拉取凭据:

kubectl create secret docker-registry regcred \
  --docker-server=<your-registry> \
  --docker-username=<username> \
  --docker-password=<password> \
  -n lmcache-operator-system