使用模型上下文协议管理容器

模型上下文协议(MCP)正在人工智能领域获得显著关注。该协议得到了大多数大型语言模型(LLM)提供商的支持,它增强了 LLM 的能力,使其能够管理诸如您的笔记本电脑文件系统AWS 服务,以及本次讨论最重要的容器等资源。

Running Containers with an MCP Server

MCP 采用客户端-服务器架构。本地 MCP 客户端将 LLM 提供商连接到一个或多个执行专业任务的 MCP 服务器。MCP 服务器的开发非常简单,这使得可用服务器数量迅速增加

虽然 MCP 协议非常引人入胜(请参阅此处此处的介绍性文章),但本文重点演示 LLM 如何使用 MCP 服务器管理容器。具体来说,我们将使用 RamaLama 在本地运行 Qwen 2.1 模型,Goose CLI 作为 MCP 客户端,以及 mcp-server-docker 来执行 Podman 命令。

使用 RamaLama 在本地运行 AI 模型

RamaLama 是一个用于在本地容器中运行 AI 模型的引擎,这使得在个人笔记本电脑上运行模型变得极其简单和安全。RamaLama 分析机器硬件(CPU、GPU、NPU 等),并自动选择最佳容器镜像和推理服务器选项来运行 AI 工作负载。

RamaLama 可以在 macOS、Windows 和 Linux 上运行。我们使用此命令在 macOS 上安装了它(有关不同的安装选项,请参阅文档

curl -fsSL https://ramalama.ai/install.sh | bash

RamaLama 需要 Podman 或 Docker 才能在容器中运行 AI 模型。在 macOS 和 Windows 上,必须首先创建 Podman 机器。对于 macOS,我们使用以下命令创建 Podman 机器(任何现有的 Podman 机器必须首先停止)

$ CONTAINERS_MACHINE_PROVIDER=libkrun \
    podman machine init --memory 4096 --now mcp-test

为了在运行 AI 模型的容器中使 Apple GPU 可用,使用 libkrun 而非默认的 applehv 至关重要。

Podman 配置完成后,RamaLama 的 serve 命令允许我们在容器中运行 Qwen 2.5 模型

$ ramalama --container --runtime=llama.cpp serve \
           --ctx-size=32768 \
           --port=11434 \
           --webui off \
           qwen2.5:7b

我们使用 --ctx-size 参数指定了一个大的上下文大小。与默认的 4K 令牌上下文相比,AI 模型在与 MCP 服务器交互时,32K 令牌上下文的性能更好。有关其他选项,请参阅 RamaLama 文档

安装 MCP 客户端:Goose CLI

本地 MCP Agent 是使用 MCP 服务器的先决条件。有许多选项,例如 Claude Desktop 和 Visual Studio Code。我们将使用 Goose CLI,一个用于 CLI 脚本和自动化的命令行代理。

在 macOS 上,可以通过在终端中运行以下命令来安装 Goose CLI(也有适用于 Linux 和 Windows 的说明

curl -fsSL \
  https://github.com/block/goose/releases/download/stable/download_cli.sh \
  | bash

Goose 连接到 LLM 提供商可以通过交互式方式完成,使用命令 goose configure,或者编辑其配置文件(macOS 上为 ~/.config/goose/config.yaml

cat << EOF > ~/.config/goose/config.yaml
GOOSE_PROVIDER: ollama
OLLAMA_HOST: localhost
GOOSE_MODEL: qwen2.5
EOF

此配置使 Goose 能够连接到 Ollama,并且至关重要的是 RamaLama。默认使用的模型将是 Qwen 2.5。

让 AI 模型使用 mcp-server-docker 运行容器

为了演示使用 MCP 服务器管理容器,我们将使用 mcp-server-dockermcp-server-docker 需要正确配置 uv安装说明)和 Podman 或 Docker。

尽管名为 mcp-server-docker,如果 Podman 作为服务运行,它也可以使用 Podman。它使用 Python Docker SDK 并连接到默认的 Docker 套接字。$DOCKER_HOST 可用于指定不同的套接字路径。

Goose 的 run 命令,使用 mcp-server-docker 扩展,指示 AI 模型“部署一个 nginx 容器,将 80 端口暴露到 9000 端口”

goose run \
  --with-extension "uvx mcp-server-docker" \
  -n container-tests \
  -t "deploy an nginx container exposing port 80 on port 9000"

上述示例在 macOS 上有效,Podman 机器已配置为监听默认的 Docker 套接字(unix:///var/run/docker.sock)。在 Linux 上,您可能需要明确指定 Podman 套接字路径

--with-extension \
    “DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock \
     uvx mcp-server-docker”

结果,MCP 服务器将启动一个 nginx 容器并提供一些有用的信息

请注意,Goose 将会话状态保存在 ~/.local/share/goose/sessions/ 文件夹中,并将日志保存在 ~/.local/state/goose/logs/cli 中,这对于调查其操作可能很有帮助。

值得注意的是,尽管 AI 模型在容器中运行,但 Goose 和 MCP 服务器在主机上执行,并拥有对主机资源的完全访问权限。如果这引起安全问题,可以将它们运行在容器中。

附录 1:使用不同的模型提供商

在本博客文章的准备过程中,尝试使用 Anthropic 和 Ollama 很有帮助。Anthropic 是一个更强大、更精细的模型提供商,与本地模型相比,它提供了更快的反馈循环,这有助于理解 MCP 服务器的功能。Ollama 促进了本地模型实验,而无需配置 Podman 或 Docker。一旦设置与这些提供商配合良好,RamaLama 可以很容易地进行调整,以在容器中运行相同的本地模型。

要将 Goose 与 Anthropic(使用模型 Claude Sonet 3.5)配合使用

$ export ANTHROPIC_API_KEY=<your key>       # Get Key at https://console.anthropic.com/
$ cat << EOF > ~/.config/goose/config.yaml  # Configure Goose
GOOSE_PROVIDER: anthropic
GOOSE_MODEL: claude-3-5-sonnet-latest
ANTHROPIC_HOST: https://api.anthropic.com
EOF

要将 Goose 与 Ollama(使用模型 Qwen 2.5)配合使用

$ cat << EOF > ~/.config/goose/config.yaml  # Configure Goose
GOOSE_PROVIDER: ollama
OLLAMA_HOST: localhost
GOOSE_MODEL: qwen2.5
EOF
$ OLLAMA_CONTEXT_LENGTH=32768 ollama server  # Start Ollama
$ curl https://:11434                # Check that Ollama is running
$ ollama run qwen2.5                         # Pull Qwen 2.5 and run it locally
$ ollama ps                                  # Show the running models details

附录 2:使用 podman-mcp-server 而非 mcp-server-docker

另一个用于 LLM 容器管理的 MCP 服务器是 podman-mcp-server。尽管它的 GitHub 星标少于 `mcp-server-docker`,并且尚未列入官方 MCP 服务器页面,但它不需要 Podman 作为服务运行,并且由 Red Hatter 的同事 Marc Nuri 开发,我决定对其进行测试

goose run \
  --with-extension "npx -y podman-mcp-server" \
  -n container-tests \
  -t "deploy an nginx container exposing port 80 on port 9000"

生成的输出类似,并且容器创建正确。我注意到 `podman-mcp-server` 避免了我在 mcp-server-docker 中观察到的“已启动”和“已创建”之间的一些状态混淆。

附录 3:幻觉

由于 AI 模型的非确定性性质,一致的提示(“部署一个 nginx 容器,将其暴露在 9000 端口”)可能会产生略有不同的答案。有时,模型会遵循错误的路径,并确信错误的事情是真实的(被称为“幻觉”)。以下是一个示例,在本博客文章的准备过程中遇到,其中 AI 模型确信它应该创建一个卷但未能成功

发表评论

订阅

输入您的电子邮件地址以接收来自本网站的电子邮件更新。

返回

您的消息已发送

警告
警告
警告。

分类


搜索