在 Kubernetes 上部署 LocalAI:从原生 Deployment 到 Helm Chart 的完整指南
【免费下载链接】LocalAILocalAI is the open-source AI engine. Run any model - LLMs, vision, voice, image, video - on any hardware. No GPU required.项目地址: https://gitcode.com/GitHub_Trending/lo/LocalAI
Kubernetes 是生产化部署 LocalAI 的推荐路径之一:你可以借助编排能力管理多副本 API、持久化模型文件、健康检查与 GPU 调度。本文以仓库中的 kubernetes.md 为核心骨架,结合仓库自带的注释版清单、健康检查源码与 GPU 加速文档,梳理从kubectl apply快速启动、到 NVIDIA/AMD GPU 透传、再到 Helm Chart 声明式管理的完整实操路径。读完本文,你将能够独立把 LocalAI 跑在任意 K8s 集群上,并为模型加载与推理配置正确的探针、存储与资源调度。
部署方式总览:两条官方推荐路径
LocalAI 官方为 Kubernetes 提供两种部署方式,你可以按团队习惯任选其一:
| 方式 | 适用场景 | 优点 |
|---|---|---|
kubectl apply应用示例清单 | 快速验证、单 Pod 部署 | 命令直接、清单可完全自控 |
Helm Chart(go-skynet/local-ai) | 生产化、参数化部署 | 通过values.yaml统一管理镜像、GPU 与存储配置 |
两种方式底层运行的都是同一个容器镜像,因此 容器化部署文档 中关于镜像 tag、数据目录、健康检查的约定在 Kubernetes 下同样适用。
路径一:用 kubectl 快速部署(CPU)
官方文档给出的最小部署方式是从示例仓库直接应用 Deployment 清单:
kubectl apply -f https://raw.githubusercontent.com/mudler/LocalAI-examples/refs/heads/main/kubernetes/deployment.yaml如果项目仓库已经克隆到本地,也可以直接应用仓库自带的注释版清单 —— 它包含了完整的 Namespace、PVC 与探针配置,比远端示例更适合作为团队内的基线:
kubectl apply -f website/static/install/kubernetes.yaml清单结构逐段拆解
仓库中的 website/static/install/kubernetes.yaml 是一份可完整运行的参考实现,其资源组织值得在生产中复刻:
1. 独立 Namespace
apiVersion: v1 kind: Namespace metadata: name: local-ai所有资源集中到local-ai命名空间,卸载时执行kubectl delete namespace local-ai即可连卷一并清理。
2. 两个持久化卷声明(PVC)
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: local-ai-models namespace: local-ai spec: accessModes: - ReadWriteOnce resources: requests: storage: 20Gi # 另一个名为 local-ai-backends 的 PVC 结构完全相同注释中解释了拆分原因:LocalAI 会在首次使用时按需下载两部分内容 ——/models存放从模型库安装的权重文件,/backends存放第一次被模型请求时才拉取的引擎镜像。若两者不做持久化,Pod 每次重启都会重新下载,既慢又浪费带宽。20Gi 是入门级的保守起步值,实际应依据你计划安装的模型与后端数量调大。
3. Deployment 与更新策略
apiVersion: apps/v1 kind: Deployment metadata: name: local-ai namespace: local-ai spec: replicas: 1 strategy: type: Recreate # PVC 为 ReadWriteOnce,旧 Pod 必须先释放卷因为两块 PVC 都是ReadWriteOnce,滚动更新时新旧 Pod 无法同时挂载同一卷,因此使用Recreate策略。若你需要无间断滚动更新,则必须把存储换成 ReadWriteMany 的共享存储(如 NFS/云厂商 RWX 卷),或改用共享模型卷的分布式模式。
容器规格中值得注意的几点:
fsGroup: 1000:保证无论存储类如何处理所有权,挂载卷都对本容器可写;resources.requests.cpu: "1"、memory: 4Gi,limits.memory: 12Gi:注释明确说明故意不设 CPU limit—— 推理是 CPU 密集任务,CPU 上限只会带来节流(throttling)而非资源保护。
三个探针与 LocalAI 的启动语义
清单定义了三个探针,语义与源码中的实现一一对应:
startupProbe: httpGet: { path: /readyz, port: http } periodSeconds: 10 failureThreshold: 60 # 覆盖首次启动下载模型的慢场景 readinessProbe: httpGet: { path: /readyz, port: http } periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 livenessProbe: httpGet: { path: /healthz, port: http } periodSeconds: 30 failureThreshold: 5在 core/http/routes/health.go 中可以看到两个端点的真实语义:
/healthz—— 存活探针,"进程是否活着"。它刻意独立于就绪状态,因为启动阶段可能正在下载数十 GB 的模型,此时若把下载当作"进程卡死",编排器会在下载途中杀掉 Pod 导致永远无法完成(源码注释原文:a long startup preload must not read as a hung process);/readyz—— 就绪探针,"该副本是否应该接收流量"。启动完成前返回503 {"status":"starting","reason":"startup preload in progress"},只有就绪后返回 200。如果就绪期间就返回 200,Service 会把 Pod 提前加进 endpoints,流量会轮询到一个尚不能服务的副本上。
三者配合:startupProbe承担首次启动的慢场景,readinessProbe决定何时进负载均衡,livenessProbe负责回收真正死掉的进程。
关键环境变量(对应清单中的 env 段)
清单通过环境变量把容器路径与挂载点对齐。这些变量名均可在 core/cli/run.go 与 core/cli/models.go 的声明中找到依据:
| 环境变量 | 值 | 作用 |
|---|---|---|
LOCALAI_MODELS_PATH | /models | 模型权重目录,对应 models PVC |
LOCALAI_BACKENDS_PATH | /backends | 后端引擎目录,对应 backends PVC |
LOCALAI_ADDRESS | :8080 | API 监听地址与端口 |
LOCALAI_API_KEY | (Secret 引用) | 启用后所有请求都必须携带 API Key 认证 |
清单中还预留了把LOCALAI_API_KEY通过secretKeyRef从 Kubernetes Secret 注入的注释示例,生产环境应取消注释并使用 Secret 管理密钥(API Key 鉴权机制见 core/cli/run_safety.go 中的说明)。
暴露服务
清单末尾的 Service 使用ClusterIP类型,保证在任何集群上都能直接 apply:
# 本地端口转发访问 kubectl -n local-ai port-forward svc/local-ai 8080:8080 # 或把 Service type 改为 LoadBalancer,由云厂商分配公网入口转发成功后访问http://localhost:8080即可打开 WebUI,curl http://localhost:8080/v1/models可查看可用模型列表。首次启动时/readyz会在模型预加载完成前保持 503,这是预期行为。
路径二:NVIDIA GPU 节点部署
官方文档为 GPU 场景提供了独立的清单:
kubectl apply -f https://raw.githubusercontent.com/mudler/LocalAI-examples/refs/heads/main/kubernetes/deployment-nvidia.yaml对照 容器镜像与 GPU 加速文档,这份清单相对 CPU 版通常只有两处关键差异:
1. 切换为 GPU 镜像 tag
LocalAI 的镜像同时发布在 Docker Hub(localai/localai:latest-gpu-nvidia-cuda-12等)与 Quay(quay.io/go-skynet/local-ai:latest-gpu-nvidia-cuda-12等)。Kubernetes 环境下请使用带 GPU 后缀的 tag,例如 CUDA 12 使用-gpu-nvidia-cuda-12,CUDA 13 使用-gpu-nvidia-cuda-13(完整 tag 矩阵见 容器部署文档)。
2. 声明 GPU 资源
resources: limits: nvidia.com/gpu: '1'要让这段声明生效,集群必须已安装对应厂商的 device plugin(NVIDIA 使用 NVIDIA/k8s-device-plugin)。调度器只有看到resources.limits中的nvidia.com/gpu才会把 Pod 调度到具备 GPU 的节点上,并将 GPU 设备注入容器。
GPU 生效还需要模型配置配合
容器镜像与资源声明只解决了"设备可用",真正把推理放到 GPU 上还需要模型 YAML 配置gpu_layers—— 指定卸载到 GPU 的层数。以 llama.cpp 后端为例(来自 GPU 加速文档):
name: my-model-name parameters: model: llama.cpp-model.ggmlv3.q5_K_M.bin context_size: 1024 threads: 1 f16: true # GPU 加速需开启 gpu_layers: 22 # 卸载到 GPU 的层数;设成 999 则尽可能全量卸载注意以下几点:
- 模型文件路径相对于
/models(即 PVC 挂载点); gpu_layers只在使用 CUDA/ROCm 编译的后端上生效;- 如果推理日志显示模型仍跑在 CPU 上,优先检查镜像 tag 是否带 GPU 后缀、
gpu_layers是否设置、以及DEBUG=true日志里是否有 GPU 初始化信息; - 多个 GPU 时 llama.cpp 会自动在设备间分配层,可用
CUDA_VISIBLE_DEVICES(NVIDIA)或HIP_VISIBLE_DEVICES(AMD)限定可见设备。
其他厂商的 Kubernetes 特殊说明
- AMD ROCm:部署前需先在集群安装 AMD 的 k8s-device-plugin(提供
amd.com/gpu资源)。Deployment 中同样通过resources.limits/requests声明amd.com/gpu: '1',并可用HIP_VISIBLE_DEVICES选择设备;若宿主机存在 iGPU,建议显式指定,因为 iGPU 兼容性不被保证(详见 GPU 加速文档 的 k8s 示例段); - Ingress 上传限制:在 K8s 上使用 whisper 转写或 llava/bakllava 视觉模型时,若上传音频/图片遇到
Error 413,通常是 Ingress 限制了请求体大小,需要为 Ingress 添加注解nginx.ingress.kubernetes.io/proxy-body-size: "25m"。
路径三:用 Helm Chart 参数化部署(推荐生产使用)
当配置项增多(镜像、GPU、副本、存储、探针),Helm 是更可控的选择。官方文档给出的完整流程如下:
# 1. 添加 Chart 仓库 helm repo add go-skynet https://go-skynet.github.io/helm-charts/ # 2. 更新仓库索引 helm repo update # 3. 导出默认 values 作为定制基线 helm show values go-skynet/local-ai > values.yaml # 4. 按需编辑 values.yaml 后安装 helm install local-ai go-skynet/local-ai -f values.yaml工作流建议:先执行helm show values生成一份可读的默认配置,再逐项覆盖。常见需要定制的字段包括:
- 镜像:默认 CPU 镜像,NVIDIA 场景改为 GPU tag(
image.repository/image.tag); - GPU 资源:在容器
resources段加入nvidia.com/gpu或amd.com/gpu限额; - 存储:模型与后端目录的 PVC 大小(参考 20Gi 起步的示例)以及 storageClass;
- 副本数与更新策略:默认 RWO 存储下副本为 1,改用 RWX 后可扩容;
- 认证:注入
LOCALAI_API_KEY(对应 API 鉴权开关)。
AMD ROCm 用户在 GPU 加速文档的 k8s 一节中的实践结论是:安装好 AMD device plugin 后,"helm chart from go-skynet 可基本不改动地直接配置使用"(其作者已在 SUSE Rancher 管理的自定义集群上验证通过)。由于 Chart 仍在演进,GPU 相关字段可能存在变动,请以helm show values实际输出的字段为准。
数据目录与持久化约定(Kubernetes 与容器一致)
无论走哪条部署路径,容器内的四个数据目录都遵循统一约定(见 容器部署文档 的卷表):
| 容器路径 | 内容 | 说明 |
|---|---|---|
/models | 模型权重文件 | 必须持久化,否则每次重启重新下载 |
/backends | 后端引擎 | 首次被请求时按需拉取,同样应持久化 |
/configuration | 动态配置文件(api_keys.json、runtime_settings.json 等) | 需持久化以保留运行时设置 |
/data | 应用数据(集合、Agent 状态、任务等) | 需持久化 |
仓库的 Kubernetes 参考清单只持久化了前两者(/models、/backends),因为它是 CPU 单实例的最小场景;如果你用到了 Agent、任务队列或运行时设置持久化(如 runtime_settings_persist.go 对应的能力),应把/configuration与/data也纳入 PVC。需要再次强调容器文档中的警告:镜像升级重建容器时,未挂卷的文件会全部丢失,四个目录全部持久化是最稳妥的选择。
部署后的运维要点
- 验证启动状态:
kubectl -n local-ai rollout status deploy/local-ai,随后kubectl -n local-ai get pods观察探针从starting转为Running; - 安装模型:WebUI(Models → Explore → Install)或通过进入 Pod 执行
local-ai models list/local-ai models install llama-3.2-1b-instruct:q4_k_m(命令详见 模型配置文档)。安装进度可在 WebUI 的 Operate → Activity 中跟踪; - 平滑更新:由于镜像升级会重建容器并触发
Recreate,请预留足够的启动宽限期 —— 仓库 docker-compose 与 K8s 清单都把首启预加载(可能下载数十 GB)视为正常慢启动,通过startupProbe(failureThreshold 60 × 10s)覆盖,而非缩短超时; - 安全加固:启用
LOCALAI_API_KEY并通过 Kubernetes Secret 注入(secretKeyRef),避免把密钥写死在清单里。
小结
- 快速体验用
kubectl apply应用 website/static/install/kubernetes.yaml 这份自含注释的 CPU 清单,GPU 场景切换 GPU 镜像 tag 并声明nvidia.com/gpu资源; - 生产化部署优先选择 Helm Chart,通过
helm show values导出基线后以values.yaml参数化镜像、存储与资源; - 无论何种方式,都要吃透三个探针的语义:
/healthz管存活、/readyz管流量、startupProbe覆盖模型预加载的慢启动,并确保/models、/backends(以及用到时的/configuration、/data)持久化,模型推理真正走 GPU 还需在模型 YAML 中配置gpu_layers与f16: true。
相关参考:容器镜像与 tag 矩阵见 containers.md,GPU 配置细节见 GPU-acceleration.md,健康检查端点实现见 core/http/routes/health.go,模型安装方式见 models.md。
【免费下载链接】LocalAILocalAI is the open-source AI engine. Run any model - LLMs, vision, voice, image, video - on any hardware. No GPU required.项目地址: https://gitcode.com/GitHub_Trending/lo/LocalAI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考