我设法将 Ollama 作为 k8s STS 运行。我将其用于 Python Langchain LLM/RAG 应用程序。但是,以下 DockerfileENTRYPOINT
脚本尝试MODELS
从 k8s STS 清单中提取作为 ENV 导出的图像列表时遇到问题。Dockerfile 具有以下ENTRYPOINT
内容CMD
:
ENTRYPOINT ["/usr/local/bin/run.sh"]
CMD ["bash"]
run.sh
:
#!/bin/bash
set -x
ollama serve&
sleep 10
models="${MODELS//,/ }"
for i in "${models[@]}"; do \
echo model: $i \
ollama pull $i \
done
k8s日志:
+ models=llama3.2
/usr/local/bin/run.sh: line 10: syntax error: unexpected end of file
David Maze 的解决方案:
lifecycle:
postStart:
exec:
command:
- bash
- -c
- |
for i in $(seq 10); do
ollama ps && break
sleep 1
done
for model in ${MODELS//,/ }; do
ollama pull "$model"
done
ollama-0 1/2 CrashLoopBackOff 4 (3s ago) 115s
ollama-1 1/2 CrashLoopBackOff 4 (1s ago) 115s
Warning FailedPostStartHook 106s (x3 over 2m14s) kubelet PostStartHook failed
$ k logs -fp ollama-0
Defaulted container "ollama" out of: ollama, fluentd
Error: unknown command "ollama" for "ollama"
更新Dockerfile
:
ENTRYPOINT ["/bin/ollama"]
#CMD ["bash"]
CMD ["ollama", "serve"]
我需要定制Dockerfile
以便可以安装 Nvidia Container Toolkit。
从机械层面来看,循环内的反斜杠
for
会造成问题。这会导致 shell 将各行合并在一起,因此您会得到一个命令echo model: $i ollama pull $i done
,但没有独立的done
命令来终止循环。您将遇到的下一个问题是,这个入口点脚本是容器运行的唯一内容,当此脚本退出时,容器也会退出。您在后台启动 Ollama 服务器并不重要。如果您想以这种方式运行容器,您需要
wait
让服务器退出。这看起来像但是,这种启动后台进程然后
wait
为其设置权限的模型通常不是最佳方法。例如,如果 Pod 关闭,终止信号将发送到包装器脚本而不是 Ollama 服务器,您将无法干净地关闭。在 Kubernetes 上下文中(您说您在 StatefulSet 中运行它),PostStart 钩子适合这里。这将允许您运行未修改的映像,但添加您自己的脚本,该脚本在容器启动时大约同时运行。在 Kubernetes 清单中,这可能看起来像:
此设置将 shell 脚本内联写入 Kubernetes 清单中。它将其包装到
/bin/sh -c
可以以这种方式运行的文件中。这使用“exec”机制,因此脚本在同一容器中作为辅助进程运行。第一个片段最多等待 10 秒以让服务器运行,第二个片段是加载模型的循环。