Ubuntu 22.04 LTS下用Docker Compose一键部署Milvus 2.2.16(附可视化工具Attu配置)
最近在折腾几个AI应用的原型,发现向量检索这块儿总是绕不开。无论是想给聊天记录加个语义搜索,还是给图片库做个以图搜图,一个高效、稳定的向量数据库是底层基石。在对比了几款主流产品后,我最终把目光锁定在了Milvus上——它生态成熟,社区活跃,最关键的是,用Docker Compose部署起来真的非常“优雅”。
不过,理想很丰满,现实却可能因为版本兼容、网络配置这些细节而“骨感”。特别是当你兴冲冲地跟着一篇教程操作,最后却卡在某个端口错误或者镜像拉取失败时,那种挫败感,相信不少朋友都体会过。今天,我就以Ubuntu 22.04 LTS这个长期支持版为舞台,带你一步步搭建Milvus 2.2.16这个稳定版本,并配好Attu这个官方可视化工具。我会把过程中可能遇到的“坑”以及我自己的解决经验都揉进去,目标是让你拿到一个开箱即用、配置清晰的开发测试环境。
1. 环境准备与核心组件安装
部署Milvus,本质上是在搭建一个由多个容器协同工作的微服务集群。因此,一个干净、规范的容器运行环境是成功的第一步。Ubuntu 22.04 LTS作为服务器系统的优秀选择,其软件源和内核版本都能很好地支持现代容器技术。
1.1 系统更新与Docker引擎安装
首先,我们需要确保系统包列表是最新的,并安装一些必要的工具包。打开你的终端,执行以下命令:
sudo apt update && sudo apt upgrade -y sudo apt install -y ca-certificates curl gnupg lsb-release接下来是安装Docker。我强烈建议使用Docker官方提供的仓库进行安装,这能保证我们获取到经过充分测试的最新稳定版本,避免因系统自带版本过旧引发的兼容性问题。
添加Docker官方GPG密钥和软件源:
sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null这里我们建立了安全的密钥环,并添加了对应Ubuntu 22.04 (Jammy Jellyfish)的Docker仓库。
安装Docker引擎:
sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin我们一次性安装了Docker的核心组件,包括最新的
docker-compose-plugin,它是一个集成在Docker CLI中的Compose实现。验证安装并设置开机自启:
sudo systemctl start docker sudo systemctl enable docker sudo docker run hello-world如果看到“Hello from Docker!”的欢迎信息,说明Docker引擎已经正常运行。
注意:如果你身处网络环境特殊的区域,可能会在拉取镜像时遇到超时问题。一个常见的解决方案是为Docker Daemon配置国内镜像加速器。你可以编辑
/etc/docker/daemon.json文件(如果不存在则创建),加入如下配置(以阿里云镜像加速器为例,请根据实际情况替换):{ "registry-mirrors": ["https://your-mirror.mirror.aliyuncs.com"] }修改后,需要重启Docker服务:
sudo systemctl restart docker。
1.2 安装独立版Docker Compose
虽然我们已经安装了Docker的Compose插件(可通过docker compose命令调用),但许多现有的脚本和文档仍在使用独立的docker-compose(带短横线)命令。为了最大兼容性,我们同时安装独立版本。
访问Docker Compose的GitHub发布页,找到最新的稳定版本号(例如v2.24.5)。在终端中执行:
# 下载指定版本的二进制文件到/usr/local/bin目录 sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose # 赋予可执行权限 sudo chmod +x /usr/local/bin/docker-compose # 验证安装 docker-compose --version至此,我们的容器运行环境已经就绪。你可以通过docker --version和docker-compose --version两个命令来确认所有组件均已正确安装。
2. 获取与解析Milvus Standalone部署文件
Milvus提供了多种部署方式,对于开发测试而言,standalone(单机)模式是最佳选择。它通过一个Docker Compose文件,启动了Milvus所需的所有核心服务,包括存储元数据的etcd、进行对象存储的MinIO,以及Milvus自身的多个组件。
2.1 下载特定版本的Compose文件
版本匹配是部署成功的关键。Milvus的不同版本,其组件镜像标签和Compose文件结构可能有细微差别。我们选择2.2.16这个经过充分验证的稳定版。
在你的工作目录(例如~/milvus)下,执行以下命令下载对应的Compose文件:
mkdir -p ~/milvus && cd ~/milvus wget https://github.com/milvus-io/milvus/releases/download/v2.2.16/milvus-standalone-docker-compose.yml -O docker-compose.yml下载完成后,我建议你先不要急着启动,而是花几分钟浏览一下这个YAML文件。用cat docker-compose.yml或你喜欢的文本编辑器打开它。你会看到它定义了多个服务,下面是一个简化的结构解读:
| 服务名 | 核心作用 | 默认端口 | 说明 |
|---|---|---|---|
| etcd | 元数据存储 | 2379 | 存储集合、分区、索引等元数据信息。 |
| minio | 对象存储 | 9000 | 存储插入的向量数据、索引文件等。 |
| standalone | Milvus核心服务 | 19530 | 对外提供gRPC服务的核心组件。 |
| attux | 指标监控(可选) | 9090 | 提供Prometheus格式的监控指标。 |
2.2 关键配置项预览与调整
在默认的docker-compose.yml中,有几个地方值得关注:
- 资源限制:文件里通常已经为容器设置了默认的内存和CPU限制。对于开发环境,默认配置通常足够。但如果你计划导入大量数据进行测试,可能需要适当调高
standalone服务的mem_limit。 - 数据持久化:Compose文件中通过
volumes配置,将etcd和minio的数据挂载到了宿主机的特定路径(如./volumes/etcd,./volumes/minio)。这意味着即使容器被删除,你的元数据和向量数据依然保留在本地。 - 网络配置:所有服务被置于一个自定义的Docker网络(如
milvus)中,它们通过服务名相互访问,这简化了内部通信。
在绝大多数情况下,你无需修改这个文件即可成功启动。但了解其结构,能在出问题时帮你快速定位。
3. 启动服务与验证部署
环境与配置准备妥当,现在可以启动我们的Milvus服务了。这个过程非常简单,但启动后的验证步骤同样重要。
3.1 一键启动与状态监控
在包含docker-compose.yml文件的目录下,运行以下命令:
sudo docker-compose up -d-d参数代表“detached”,让服务在后台运行。命令执行后,Docker会开始从Docker Hub拉取所需的镜像,然后依次创建并启动容器。你可以通过以下命令观察启动进度和日志:
# 查看所有容器的运行状态 sudo docker-compose ps # 动态查看所有容器的聚合日志(按Ctrl+C退出) sudo docker-compose logs -f # 仅查看milvus-standalone容器的日志 sudo docker-compose logs -f standalone当看到所有服务的状态(State)均为Up时,表示启动成功。首次启动由于需要拉取镜像,可能需要几分钟时间。
3.2 功能连通性测试
容器状态正常,不代表服务内部就绪。我们需要进行更深入的连通性测试。
检查核心服务端口: Milvus的核心服务端口是19530。我们可以用
netstat或简单的curl命令检查端口是否监听(注意:Milvus使用gRPC协议,普通HTTP curl可能不返回有效内容,但能检测端口是否开放)。sudo netstat -tlnp | grep 19530 # 或使用nc工具 nc -zv localhost 19530使用
milvus-cli进行快速测试(可选但推荐): Milvus提供了一个官方的命令行工具,非常适合做快速验证。首先安装它:pip install pymilvus milvus-cli然后连接到你刚启动的服务:
milvus-cli connect --host localhost --port 19530连接成功后,你可以尝试执行
list collections等简单命令,如果返回空列表或成功信息,则证明Milvus服务完全就绪。
提示:如果启动过程中某个容器不断重启(
Restarting状态),最常见的原因是端口冲突或宿主机资源(特别是内存)不足。请使用docker-compose logs [服务名]查看具体错误日志。例如,如果19530端口已被占用,你需要在docker-compose.yml中修改standalone服务的端口映射,如将"19530:19530"改为"19531:19530"。
4. 配置与使用Attu可视化管理工具
通过命令行操作虽然高效,但在开发调试阶段,一个直观的可视化管理界面能极大提升效率。Milvus官方推荐的Attu正是这样一个工具,它提供了集合管理、数据插入/查询、索引构建、系统监控等全方位功能。
4.1 启动Attu容器并配置连接
Attu本身也是一个Docker容器,我们需要将其启动,并正确配置其连接到我们刚刚部署的Milvus服务。
重要:Attu的版本需要与Milvus服务端版本大致兼容。对于Milvus 2.2.x,建议使用Attu 2.3.x版本。执行以下命令启动Attu:
sudo docker run -d \ --name attu \ -p 8000:3000 \ -e MILVUS_URL=host.docker.internal:19530 \ --restart unless-stopped \ zilliz/attu:v2.3.7让我们拆解一下这个命令:
-d: 后台运行。--name attu: 为容器指定一个名字,方便管理。-p 8000:3000: 将容器内的3000端口映射到宿主机的8000端口。这意味着你通过浏览器访问http://<你的服务器IP>:8000就能打开Attu。-e MILVUS_URL=...: 设置环境变量,告诉Attu Milvus服务在哪里。这里使用了Docker Desktop在Mac/Windows上提供的特殊域名host.docker.internal,它指向宿主机。如果你的Ubuntu是纯Linux服务器环境,这个域名可能无效。zilliz/attu:v2.3.7: 指定使用的Attu镜像及其标签。
针对纯Linux环境的连接配置调整: 在Linux服务器上,Attu容器无法直接通过host.docker.internal访问宿主机上的另一个Docker服务。有三种解决方案:
使用宿主机真实IP:首先用
ip addr show或hostname -I命令查出宿主机的内网IP(如192.168.1.100),然后将启动命令中的MILVUS_URL改为该IP。sudo docker run -d --name attu -p 8000:3000 -e MILVUS_URL=192.168.1.100:19530 zilliz/attu:v2.3.7使用Docker网络(更优雅):将Attu容器加入到Milvus Compose创建的网络中。首先找到Milvus网络的名称(通常在Compose文件所在目录运行
docker network ls,名字可能叫milvus_default或目录名加_default),然后启动Attu时指定网络,并使用Milvus的服务名(standalone)作为连接地址。# 假设网络名为 milvus_default sudo docker run -d --name attu --network milvus_default -p 8000:3000 -e MILVUS_URL=standalone:19530 zilliz/attu:v2.3.7这种方式更符合Docker最佳实践,容器间通过服务名通信,无需关心IP变化。
4.2 设置登录认证与安全访问
默认情况下,Attu启动后无需密码即可访问。这在公网或多人共享的开发环境中是极不安全的。从Attu 2.3.0版本开始,支持通过环境变量设置用户名和密码。
启动带认证的Attu容器: 只需在启动命令中添加HISTORY_USER和HISTORY_PASSWORD两个环境变量即可。
sudo docker run -d \ --name attu_secure \ -p 8000:3000 \ -e MILVUS_URL=standalone:19530 \ -e HISTORY_USER=admin \ -e HISTORY_PASSWORD=YourStrongPassword123! \ --network milvus_default \ zilliz/attu:v2.3.7启动后,首次访问http://<服务器IP>:8000,就会弹出登录框,要求输入上面设置的用户名(admin)和密码(YourStrongPassword123!)。
注意:请务必为生产环境或暴露在公网的实例设置强密码。此外,考虑使用HTTPS(例如通过Nginx反向代理配置SSL证书)来加密前端通信,是进一步提升安全性的必要步骤。
4.3 Attu核心功能实战导览
成功登录Attu后,你会看到一个清晰的管理界面。下面我结合几个典型场景,介绍如何利用Attu高效工作:
连接管理与服务健康:在首页,Attu会显示你连接的Milvus集群状态,包括版本、组件健康度(etcd, minio等)。这是你判断服务是否完全正常的第一站。
集合(Collection)管理:
- 创建集合:点击“Create Collection”,你需要定义集合名、描述,以及最重要的——Schema。Schema定义了集合的字段,包括主键字段、向量字段和标量字段。例如,一个图片搜索集合的Schema可能包含:
id(Int64, 主键)image_vector(FloatVector, 维度512) // 存储图片特征向量image_path(VarChar, 最大长度255) // 存储图片路径
- 插入数据:在集合详情页,进入“Data Insert”标签页。你可以手动输入JSON格式数据,或者更常见的,通过编写Python脚本,使用PyMilvus SDK批量导入数据。Attu提供了数据插入的预览和验证功能。
- 构建索引:向量检索的速度和精度严重依赖于索引。在“Index”标签页,你可以为向量字段创建索引。Milvus支持多种索引类型,如
IVF_FLAT、HNSW等。你需要根据数据规模、查询速度和精度要求来选择,并设置相应的参数(如nlist,M/efConstruction)。# 一个在Python中创建IVF_FLAT索引的示例(与Attu操作对应) index_params = { "index_type": "IVF_FLAT", "metric_type": "L2", # 距离度量方式,如L2、IP "params": {"nlist": 1024} } collection.create_index("image_vector", index_params)
- 创建集合:点击“Create Collection”,你需要定义集合名、描述,以及最重要的——Schema。Schema定义了集合的字段,包括主键字段、向量字段和标量字段。例如,一个图片搜索集合的Schema可能包含:
向量搜索:在“Search”标签页,你可以进行交互式搜索。输入一个查询向量(或从已有数据中选择一条),选择索引和搜索参数(如
nprobe),Attu会实时返回最相似的Top-K条结果,并显示它们的ID、距离以及标量字段信息。这对于调试搜索效果、调整参数至关重要。系统监控:Attu集成了简单的监控面板,可以查看QPS(每秒查询数)、延迟、内存使用情况等关键指标,帮助你了解系统负载和性能瓶颈。
5. 部署后优化与日常运维要点
服务跑起来只是开始,要让这个开发环境稳定、高效地服务于你的项目,还需要一些额外的关注点。
5.1 数据持久化与备份策略
我们之前提到,Compose文件已经配置了数据卷。你需要知道这些数据的具体位置,以便进行备份。
- Milvus元数据:存储在
./volumes/etcd目录下。这是Milvus的“大脑”,记录了所有集合、分区、索引的定义和状态信息。 - Milvus向量数据与索引文件:存储在
./volumes/minio目录下。这是实际数据所在。
简易备份方案: 你可以定期(例如每天)使用tar命令打包这些目录,并传输到安全的存储位置。
cd ~/milvus tar -czf milvus_backup_$(date +%Y%m%d).tar.gz volumes/ # 随后可将备份文件scp到远程服务器或上传至云存储5.2 资源监控与日志管理
随着数据量的增长,监控资源使用情况很重要。
查看容器资源占用:
sudo docker stats这个命令会实时显示所有容器的CPU、内存、网络I/O和磁盘I/O使用情况。
集中查看与管理日志: 虽然
docker-compose logs很好用,但对于长期运行的服务,建议将日志导出到文件,或使用如ELK(Elasticsearch, Logstash, Kibana)或Grafana Loki这样的日志聚合系统。一个简单的起步方法是使用Docker的日志驱动将日志发送到json-file并配置日志轮转(log-rotation),这可以在Compose文件中为每个服务配置:services: standalone: # ... 其他配置 ... logging: driver: "json-file" options: max-size: "10m" max-file: "3"这样配置后,每个容器的日志文件最大为10MB,最多保留3个,防止日志占满磁盘。
5.3 版本升级与迁移考量
当你未来需要将开发环境的Milvus升级到新版本时,务必谨慎。
- 查阅官方升级指南:Milvus文档通常会提供详细的版本间升级步骤和注意事项,特别是涉及大版本升级时(如2.1.x到2.2.x)。
- 完整备份:升级前,务必按照上述方法对
volumes目录进行完整备份。 - 在测试环境演练:如果条件允许,先在另一个测试服务器上恢复备份数据,进行升级演练,验证业务兼容性。
- 使用新版本的Compose文件:升级通常意味着需要下载新版本的
milvus-standalone-docker-compose.yml文件。不要直接在原Compose文件上修改镜像标签,因为服务配置和依赖可能已发生变化。
最后,记得这个用Docker Compose部署的Standalone模式,虽然方便,但其设计初衷是开发、测试和学习。当你的项目需要走向生产环境,面临高可用、水平扩展、更高性能的需求时,就需要考虑使用Kubernetes Operator部署、或者利用云原生的Milvus服务了。不过,那将是另一个充满挑战和乐趣的故事了。至少现在,你已经拥有了一个功能完备、可视化的Milvus沙盒,可以尽情开始你的向量检索实验了。如果在操作中遇到其他具体问题,多翻翻官方文档和GitHub issue,社区里通常已经有先行者提供了答案。