双系统下Docker部署Milvus 2.3.4与ATTU可视化实战
2026/7/31 8:20:27 网站建设 项目流程

1. 项目概述:为什么要在双系统环境下折腾 Milvus?

最近在做一个本地知识库的RAG项目,向量数据库的选型自然落到了Milvus头上。我的主力开发机是Windows 10,但很多AI和数据库生态的工具链在Linux下更友好、更稳定。为了兼顾日常办公和深度开发,我在同一台机器上安装了Windows 10和Anolis OS 8(一个兼容CentOS的国产Linux发行版)双系统。

这个配置带来的一个核心挑战就是:如何在两个系统间高效、一致地部署和测试Milvus?答案就是Docker。通过Docker,我们可以在Windows和Anolis上获得近乎一致的运行环境,极大地简化了部署和迁移的复杂度。本文记录的就是我在这套“混搭”环境里,从零开始用Docker部署Milvus 2.3.4,并成功用ATTU进行可视化管理全过程。无论你是想体验双系统开发,还是单纯想在Windows或Linux上快速拉起一个Milvus服务,这篇踩坑实录都能给你提供一条清晰的路径。

2. 环境准备与核心思路拆解

2.1 双系统与Docker的选型考量

选择Windows 10 + Anolis 8双系统,主要是出于工作流分离的考虑。Windows用于文档处理、通讯以及一些仅支持Windows的软件;Anolis 8则提供了一个纯净、稳定的Linux服务器环境,更适合后端服务、数据库和容器化部署。Anolis 8作为CentOS的替代品,其软件包管理和系统稳定性非常出色,对于生产环境模拟很有帮助。

而选择Docker来部署Milvus,则是为了环境隔离和可复现性。Milvus的依赖相对复杂,包括etcd、minio、pulsar等组件。通过Docker Compose,我们可以一键拉起所有服务,并且保证每次部署的组件版本和配置完全一致。更重要的是,Docker Desktop for Windows的WSL 2后端,让Windows下的容器体验几乎与原生Linux无异,这为双系统下的统一操作奠定了基础。

核心思路:在Windows侧,我们利用Docker Desktop(基于WSL 2)来运行Milvus的容器;在Anolis 8侧,我们直接安装Docker Engine和Docker Compose。两边的部署文件(docker-compose.yml)基本可以通用,只需注意少数与宿主机相关的路径和网络配置差异。我们将以Anolis 8侧的部署作为主流程讲解,因为其更接近生产环境,同时会穿插说明Windows下的关键注意事项。

2.2 基础环境配置清单

在开始之前,请确保你的环境满足以下要求:

  1. Anolis OS 8

    • 系统已安装并可以正常启动。
    • 拥有一个具有sudo权限的用户。
    • 内存建议8GB以上,Milvus运行会占用较多资源。
    • 磁盘空间充足,用于存放Docker镜像和数据库数据。
  2. Windows 10

    • 版本为2004及以上,家庭版需升级为专业版或企业版以启用Hyper-V和WSL 2。
    • 确保BIOS中已开启虚拟化技术(Intel VT-x或AMD-V)。
    • 安装并配置好WSL 2(推荐使用Ubuntu发行版)。
    • 安装Docker Desktop for Windows,并设置其使用WSL 2作为后端。
  3. 网络:需要能够访问Docker Hub等容器镜像仓库。如果网络环境特殊,请提前配置好镜像加速器。

3. Anolis 8 侧 Docker 环境部署详解

3.1 安装 Docker Engine 与 Docker Compose

Anolis 8 默认的软件源可能不包含最新版的Docker,因此我们采用Docker官方提供的仓库进行安装。

首先,卸载旧版本(如果有):

sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine

安装必要的依赖包和配置仓库:

sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

由于Anolis兼容CentOS,这里我们使用CentOS的仓库地址。

安装Docker Engine、命令行工具以及容器运行时containerd:

sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

重要提示:这里我们直接安装了Docker官方的docker-compose-plugin,它提供了docker compose命令(注意是空格,不是横杠)。这是新版本推荐的方式。如果你习惯使用独立的docker-compose脚本,也可以另行安装,但为了统一,本文后续将使用docker compose命令。

启动Docker服务并设置开机自启:

sudo systemctl start docker sudo systemctl enable docker

验证安装是否成功:

sudo docker run hello-world

如果能看到欢迎信息,说明Docker引擎安装并运行正常。

将当前用户加入docker组,避免每次使用docker命令都需要sudo

sudo usermod -aG docker $USER

执行此命令后,你需要完全退出当前终端会话并重新登录,用户组变更才会生效。

3.2 配置 Docker 镜像加速与存储路径

国内从Docker Hub拉取镜像速度可能较慢,建议配置国内镜像加速器。这里以阿里云加速器为例(你需要有自己的阿里云账号获取专属加速地址)。

编辑Docker守护进程配置文件:

sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { “registry-mirrors”: [“https://your-own-mirror.mirror.aliyuncs.com”], “exec-opts”: [“native.cgroupdriver=systemd”], “log-driver”: “json-file”, “log-opts”: { “max-size”: “100m” }, “storage-driver”: “overlay2” } EOF

请将“https://your-own-mirror.mirror.aliyuncs.com”替换为你从阿里云容器镜像服务控制台获取的加速器地址。native.cgroupdriver=systemd是为了与Anolis 8的systemd更好地集成。

默认情况下,Docker的镜像、容器等数据存储在/var/lib/docker,如果系统根目录空间不足,可以修改存储路径。假设我们想将数据存放到/data/docker

  1. 停止Docker服务:sudo systemctl stop docker
  2. 移动原有数据(如果存在且重要):sudo mv /var/lib/docker /data/
  3. 创建软链接:sudo ln -s /data/docker /var/lib/docker
  4. 或者在上述daemon.json中直接添加“data-root”: “/data/docker”字段。

配置完成后,重新加载配置并重启Docker:

sudo systemctl daemon-reload sudo systemctl restart docker

4. 部署 Milvus 2.3.4 集群

4.1 获取与解析 Docker Compose 文件

Milvus官方为单机测试提供了非常方便的Docker Compose部署文件。我们直接使用2.3.4版本对应的文件。

首先,创建一个工作目录并下载配置文件:

mkdir -p ~/milvus-standalone && cd ~/milvus-standalone wget https://github.com/milvus-io/milvus/releases/download/v2.3.4/milvus-standalone-docker-compose.yml -O docker-compose.yml

下载完成后,强烈建议你先用文本编辑器(如vimnano)打开这个docker-compose.yml文件浏览一遍。它定义了四个核心服务:

  1. etcd:用于元数据存储,服务发现。
  2. minio:用于对象存储,存放插入Milvus的原始向量数据、索引文件等。
  3. standalone:即Milvus单机版服务本身。
  4. attu:Milvus的可视化管理工具(本文后面会用到)。

理解这个文件的结构,有助于后续排查问题。例如,你可以看到各个服务的镜像标签、容器间的网络配置、端口映射、数据卷挂载等关键信息。

4.2 启动 Milvus 服务集群

在包含docker-compose.yml文件的目录下,执行以下命令启动所有服务:

sudo docker compose up -d

命令中的-d参数表示在后台运行(detached mode)。

执行后,Docker会开始从镜像仓库拉取所需的镜像(etcd、minio、milvus、attu),这个过程耗时取决于你的网速。拉取完成后会自动创建并启动容器。

你可以使用以下命令查看容器状态:

sudo docker compose ps

如果所有服务的状态(STATUS)都是“Up”,则表示启动成功。也可以查看日志来监控启动过程:

# 查看所有服务的日志 sudo docker compose logs # 持续跟踪Milvus服务本身的日志 sudo docker compose logs -f standalone

关键端口说明

  • 19530: Milvus服务的gRPC端口,客户端(如PyMilvus SDK)通过此端口连接。
  • 9091: Milvus服务的HTTP端口,用于健康检查和一些HTTP API。
  • 9000: MinIO服务的API端口。
  • 9090: MinIO服务的Web控制台端口。
  • 2379: etcd服务的客户端通信端口。
  • 3000: Attu Web界面的访问端口。

确保这些端口在宿主机(Anolis 8)上没有其他程序占用。

4.3 基础功能验证与连接测试

服务启动后,我们进行一个最简单的连接和集合创建测试,以确保Milvus核心功能正常。

首先,进入Milvus服务容器内部,使用其自带的milvus-cli工具:

sudo docker exec -it milvus-standalone /bin/bash

在容器内部,执行:

milvus-cli

这会进入Milvus命令行交互界面。依次执行以下命令:

connect -h 127.0.0.1 -p 19530 create collection -c test_collection -f “id:INT64:pk” -f “vector:FLOAT_VECTOR:128” -f “title:VARCHAR:100” -p “id”
  • connect: 连接本容器内的Milvus服务。
  • create collection: 创建一个名为test_collection的集合,包含三个字段:一个INT64类型的主键字段id,一个128维的浮点向量字段vector,一个最大长度100的字符串字段title。分区键(partition key)设置为id字段。

如果命令执行成功,没有报错,则说明Milvus服务运行正常,可以接受基本的操作指令。输入exit退出milvus-cli,再输入exit退出容器。

5. 使用 ATTU 进行可视化管理和操作

5.1 访问与登录 ATTU Web 界面

在部署的Compose文件中,已经包含了Attu服务。它会在后台自动启动。你只需要打开浏览器,访问http://<你的Anolis系统IP地址>:3000

例如,如果你的Anolis系统IP是192.168.1.100,则访问http://192.168.1.100:3000

首次打开会看到登录界面。连接信息如下:

  • Address: 填写你的Milvus服务地址。这里是个关键点:因为Attu容器和Milvus容器在同一个Docker网络内,它们可以通过服务名standalone直接通信。所以,这里应该填写standalone,而不是127.0.0.1或宿主机IP。
  • Port:19530
  • Username/Password: Milvus默认没有启用用户名密码认证,这两项留空即可。

点击“Connect”,如果一切正常,你将成功进入ATTU的主界面。

注意:如果你在宿主机(Anolis系统本身)的浏览器中访问,使用standalone作为地址是无效的,因为standalone这个主机名只在Docker网络内部有效。此时,你需要填写127.0.0.1或者宿主机的实际IP地址。这是容器网络与宿主机网络访问的区别,务必理解。

5.2 ATTU 核心功能实操指南

登录成功后,ATTU的界面非常直观。左侧是导航栏,主要功能区包括:

  1. Collections(集合):这里列出所有的集合。你可以点击“Create Collection”来通过图形界面创建集合,定义字段、索引、分区键等,比命令行更友好。我们之前创建的test_collection也会显示在这里。
  2. Data Query(数据查询):这是最重要的功能之一。你可以选择某个集合,进行数据的“插入”(Insert)、“查询”(Search)和“删除”(Delete)。
    • 插入数据:点击“Insert”,可以手动输入或上传JSON/CSV文件来添加数据。你需要按照集合定义的字段格式来准备数据。对于向量字段,需要输入一个JSON数组,如[0.1, 0.2, ..., 0.128]
    • 向量搜索:点击“Search”,这是Milvus的精华。你需要:
      • 选择索引类型(如果已创建索引)。
      • 输入一个查询向量(同样是一个JSON数组)。
      • 选择度量类型(如L2欧氏距离、IP内积)。
      • 设置返回结果数量topK。 点击搜索,下方会返回最相似的向量结果及其ID、距离分数。
  3. Index(索引):为集合的向量字段创建索引以加速搜索。常见的索引类型有FLAT(暴力检索)、IVF_FLATIVF_SQ8HNSW等。创建索引需要指定nlist(聚类中心数)等参数,ATTU提供了参数说明和默认值。
  4. System View(系统视图):可以查看Milvus集群的健康状态、节点信息、配置参数等,对于监控很有帮助。

实操建议:在ATTU中重复一遍之前在CLI里做的“创建集合”操作,感受图形化操作的便捷。然后尝试插入几条包含随机向量和文本的数据,最后进行一次向量相似度搜索,体验完整的流程。

6. Windows 10 侧部署的特别注意事项

在Windows 10上通过Docker Desktop部署Milvus,流程与Anolis 8侧高度相似。主要区别和注意事项如下:

6.1 解决 Docker Desktop 启动失败与虚拟化问题

如果你遇到“Docker Desktop failed to start because virtualisation support wasn‘t detected”错误,请按以下步骤排查:

  1. 确认CPU虚拟化已开启:重启电脑进入BIOS/UEFI设置(通常是开机时按F2、Del、F10等键),找到“Virtualization Technology”(Intel VT-x或AMD-V)选项,确保其状态为“Enabled”。
  2. 关闭 Hyper-V 和 Windows 沙盒(如果不需要):对于某些主板,Hyper-V可能与BIOS虚拟化冲突。以管理员身份打开PowerShell,运行:
    Disable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-All
    重启后检查。如果后续其他开发需要Hyper-V,可以再开启。
  3. 启用WSL 2:WSL 2是Docker Desktop for Windows的推荐后端。以管理员身份打开PowerShell并运行:
    wsl --install
    这个命令会默认安装Ubuntu发行版并启用WSL 2特性。你也可以通过wsl --list --online查看可用发行版,用wsl --install -d <发行版名称>安装指定版本。
  4. 配置 Docker Desktop:安装Docker Desktop后,打开设置(Settings):
    • 在“General”中,确保“Use the WSL 2 based engine”被勾选。
    • 在“Resources” -> “WSL Integration”中,启用你已安装的Linux发行版(如Ubuntu)的集成。这样可以在WSL子系统中直接使用docker命令。

完成以上步骤后,重启Docker Desktop通常可以解决问题。

6.2 路径映射与文件权限的坑

在Windows下编写docker-compose.yml文件时,如果需要将宿主机目录挂载到容器内(例如,想持久化MinIO的数据),路径写法需要注意。

错误示例(在docker-compose.yml中):

volumes: - C:\Users\YourName\milvus_data:/minio/data

这种Windows绝对路径在Docker Desktop的上下文中可能无法被正确解析,尤其是在使用WSL 2后端时。

正确做法

  1. 使用WSL中的路径:如果你启用了WSL集成,最好的方式是在WSL子系统中进行操作。打开WSL终端(如Ubuntu),在/home/yourname/下创建目录,然后在docker-compose.yml中使用WSL路径,如- /home/yourname/milvus_data:/minio/data。Docker Desktop可以无缝识别这些路径。
  2. 使用相对路径:将docker-compose.yml和数据目录放在同一个父目录下,使用相对路径,如- ./minio_data:/minio/data。这是最便携、最推荐的方式。
  3. 如果需要映射Windows目录:可以尝试使用/c/Users/YourName/milvus_data这种格式(Git Bash风格),但并非所有情况都稳定。建议优先采用方法1或2。

文件权限问题:Linux容器对挂载的卷有用户权限要求。如果你在Windows下创建了目录并挂载,容器内的进程(如MinIO)可能因为没有写权限而启动失败。在WSL子系统中创建目录并确保其权限开放(如chmod 777),可以避免大部分问题。

6.3 双系统间的数据共享与迁移思路

在双系统环境下,你可能希望Windows和Anolis都能访问同一份Milvus测试数据。由于两个系统文件格式不同,直接共享磁盘分区可能较复杂。这里提供两个实用思路:

  1. 通过 Docker 镜像和导出/导入实现:这是最干净的方式。在Anolis系统上,使用docker commitdocker export将包含数据的容器(如MinIO)保存为镜像或文件包。然后将这个镜像文件复制到Windows系统,使用docker loaddocker import导入。这样可以在两个系统获得一模一样的数据环境。适合阶段性备份和迁移。
  2. 使用网络存储或同步目录:在家庭网络内,可以搭建一个Samba或NFS服务器,将数据目录放在这个网络存储上。然后在Windows和Anolis的docker-compose.yml中,都将数据卷挂载指向这个网络路径(如- /nfs/milvus_data:/minio/data)。这样两个系统操作的就是同一份数据。这需要一定的网络配置知识。

对于日常开发测试,第一种镜像迁移的方法更简单可控。

7. 常见问题排查与性能调优实录

7.1 部署与启动常见问题

问题1:docker compose up -d后,某个服务(如standalone)反复重启,状态一直是Restarting

  • 排查:首先查看该容器的详细日志:docker compose logs <服务名>。常见原因有:
    • 依赖服务未就绪:Milvus依赖etcd和minio。可能是网络问题导致Milvus启动时无法连接它们。检查Compose文件中服务间的依赖关系(depends_on),并确保etcd和minio的日志显示启动成功。
    • 端口冲突:宿主机19530或其他端口已被占用。使用netstat -tlnp | grep <端口号>命令检查,并停止冲突进程或修改Compose文件中的端口映射。
    • 内存不足:Milvus standalone容器默认可能占用较大内存。检查宿主机可用内存,或尝试在Compose文件中为standalone服务添加资源限制,如mem_limit: 4g,先保证它能启动。

问题2:ATTU 无法连接,提示连接超时或拒绝。

  • 排查
    1. 确认Milvus服务是否真的在运行:docker compose ps,查看standalone服务状态是否为Up
    2. 确认ATTU容器是否运行正常。
    3. 最关键的一步:检查连接地址。如果你在宿主机浏览器访问,地址应为http://宿主机IP:3000,连接Milvus的地址应填宿主机IP:19530。如果你在容器网络内部(比如从另一个测试容器连接),才填standalone:19530。这是最容易出错的地方。
    4. 检查防火墙:Anolis 8默认的firewalld或Windows防火墙可能阻止了3000或19530端口。使用sudo firewall-cmd --list-ports(Anolis)或在Windows防火墙中添加入站规则。

问题3:插入或搜索向量时,客户端报错“collection not found”或“index not exist”。

  • 排查
    1. 确认集合名称拼写无误,且确实已创建成功。在ATTU界面或使用milvus-clilist collections命令确认。
    2. 进行搜索前,必须为向量字段创建索引。在ATTU的“Index”页面,为对应集合的向量字段创建索引(如IVF_FLAT),并执行“Load”操作将集合加载到内存。只有加载后的集合才能被搜索。

7.2 基础性能调优建议

对于单机部署的Milvus用于开发和测试,以下几点调整可以提升体验:

  1. 调整 Docker 资源限制:在Docker Desktop(Windows/Mac)或/etc/docker/daemon.json(Linux)中,为Docker分配更多的CPU核心和内存。对于Milvus standalone,建议至少分配4GB内存和2个CPU核心。
  2. 优化 Milvus 配置:Milvus的配置可以通过环境变量或修改配置文件进行覆盖。在docker-compose.yml中,可以为standalone服务添加环境变量,例如:
    environment: - “common.retentionDuration=432000” # 元数据保留时间(秒) - “quotaAndLimits.enable=true” - “quotaAndLimits.forceDeny=false”
    更详细的配置项可以参考Milvus官方文档。对于测试环境,主要关注内存相关的参数,避免OOM(内存溢出)。
  3. 索引类型选择FLAT索引最精确但速度慢,适合向量数量少(<10万)的场景。IVF_FLATIVF_SQ8HNSW是更通用的选择,需要在创建索引时指定nlist(聚类中心数)或M/efConstruction(HNSW参数)。一个简单的起点:对于百万级数据,nlist可以设置为sqrt(向量总数)左右。在ATTU创建索引时,有参数说明和推荐值。
  4. 批量插入数据:通过SDK(如PyMilvus)插入数据时,尽量使用批量插入(每次插入几百到几千条),而不是单条插入,这可以极大提升数据导入效率。

7.3 数据持久化与备份

默认的Docker Compose配置中,已经通过卷(volumes)将etcd、minio和Milvus的日志数据映射到了宿主机的匿名卷。为了更好的管理,建议将其改为命名卷绑定挂载到宿主机特定目录

修改docker-compose.yml中的卷定义示例:

volumes: # 将匿名卷改为命名卷 milvus-etcd-data: milvus-minio-data: milvus-logs: services: etcd: # ... volumes: - “milvus-etcd-data:/etcd_data” minio: # ... volumes: - “milvus-minio-data:/minio/data” standalone: # ... volumes: - “milvus-logs:/milvus/logs” - “milvus-logs:/milvus/data”

这样,即使删除容器,数据卷依然存在。你可以使用docker volume ls查看和管理这些命名卷。

备份策略:定期备份的关键是MinIO中的数据(存储桶)和etcd中的元数据。可以编写脚本,使用mc(MinIO客户端)命令备份存储桶,并使用etcdctl工具备份etcd数据。将备份文件存储到宿主机其他安全位置或云存储。

8. 从部署到应用:一个简单的 Python 示例

部署好Milvus后,我们最终是要用程序来操作它的。这里给出一个在Anolis 8或Windows WSL中,使用Python连接我们刚部署的Milvus,并进行插入与搜索的极简示例。

首先,确保你的Python环境(建议3.8+)已安装pymilvus库:

pip install pymilvus==2.3.4

然后,创建测试脚本milvus_demo.py

from pymilvus import connections, Collection, FieldSchema, CollectionSchema, DataType, utility import random # 1. 连接到 Milvus 服务 # 注意:如果Python脚本运行在宿主机,host填‘127.0.0.1’;如果运行在Docker网络内的另一个容器,填‘standalone’ connections.connect(host=‘127.0.0.1’, port=‘19530’) # 2. 定义集合结构(如果已存在,可以跳过创建) collection_name = “demo_collection” if not utility.has_collection(collection_name): fields = [ FieldSchema(name=“id”, dtype=DataType.INT64, is_primary=True, auto_id=True), FieldSchema(name=“title”, dtype=DataType.VARCHAR, max_length=200), FieldSchema(name=“embedding”, dtype=DataType.FLOAT_VECTOR, dim=128) # 假设是128维向量 ] schema = CollectionSchema(fields, description=“Demo collection for search”) collection = Collection(name=collection_name, schema=schema) print(f“Collection {collection_name} created.”) else: collection = Collection(collection_name) print(f“Collection {collection_name} already exists.”) # 3. 创建索引(仅需执行一次) index_params = { “index_type”: “IVF_FLAT”, “metric_type”: “L2”, “params”: {“nlist”: 128} } # 为向量字段创建索引 collection.create_index(field_name=“embedding”, index_params=index_params) print(“Index created.”) # 4. 加载集合到内存(搜索前必须加载) collection.load() print(“Collection loaded.”) # 5. 准备并插入一些随机数据 num_entities = 1000 data = [ [f“title_{i}” for i in range(num_entities)], # 标题 [[random.random() for _ in range(128)] for _ in range(num_entities)] # 随机向量 ] # 注意:id字段是自增的,所以不需要提供 mr = collection.insert([data[0], data[1]]) print(f“{num_entities} entities inserted. Inserted ids: {mr.primary_keys[:5]}...”) # 打印前5个ID # 6. 执行向量相似度搜索 search_vectors = [[random.random() for _ in range(128)]] # 一个随机查询向量 search_params = {“metric_type”: “L2”, “params”: {“nprobe”: 10}} # nprobe是搜索时访问的聚类中心数 results = collection.search( data=search_vectors, anns_field=“embedding”, param=search_params, limit=5, # 返回最相似的5条结果 output_fields=[“title”, “id”] # 同时返回这些字段 ) # 7. 打印搜索结果 for i, hits in enumerate(results): print(f“Search results for query {i}:”) for hit in hits: print(f“ id: {hit.id}, title: {hit.entity.get(‘title’)}, distance: {hit.distance}”) # 8. 清理(可选):删除集合 # utility.drop_collection(collection_name) # print(f“Collection {collection_name} dropped.”)

运行这个脚本:

python milvus_demo.py

如果一切顺利,你将看到集合创建、索引构建、数据插入和搜索的完整过程输出。这个例子展示了PyMilvus SDK的基本用法,你可以在此基础上构建更复杂的应用,如结合LangChain、构建RAG系统等。

通过这个从系统准备、Docker部署、可视化操作到客户端编程的完整闭环,你应该已经掌握了在混合操作系统环境下驾驭Milvus这项强大工具的基本能力。记住,容器化部署的核心优势在于环境一致性,无论是Windows下的快速原型验证,还是Anolis/Linux下的稳定服务部署,你都能拥有相同的体验。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询