Docker 环境下 Milvus 向量数据库的稳定部署与常见问题
前言
Milvus 作为高性能开源向量数据库,在 AI 应用中被广泛使用。但在 Docker 环境下部署时,很多小伙伴会遇到镜像拉取失败、容器反复重启、磁盘空间爆满、数据"不翼而飞"、锁屏后服务中断等一系列问题。本文将结合我在 VMware 虚拟机 + CentOS 7 环境下的真实排坑经历,从零到一,带你完成一个稳定、持续运行的 Milvus 独立部署,并附上各类常见故障的解决方案。
环境介绍
- 宿主机:Windows 10 + VMware Workstation 16
- 虚拟机:CentOS 7.9(带图形界面)
- Docker 版本:20.10.x
- Milvus 版本:v2.6.2(standalone 模式)
- 其他工具:Attu(Milvus 可视化管理)、pymilvus、Dify(知识库应用)
一、安装 Milvus:使用官方脚本
Milvus 官方提供了 standalone_embed.sh 脚本,可以一键拉取镜像并启动内嵌 etcd 的 standalone 版本,非常适合本地开发与测试。
1.1 下载安装脚本
由于 raw.githubusercontent.com 在国内经常被屏蔽,我们改用 jsDelivr CDN 下载:
bash
curl -sfL https://cdn.jsdelivr.net/gh/milvus-io/milvus/scripts/standalone_embed.sh -o standalone_embed.sh
chmod +x standalone_embed.sh
如果 CDN 也失败,你可以手动创建脚本内容(文末附有简洁版脚本)。
1.2 配置 Docker 镜像加速(必须)
编辑 /etc/docker/daemon.json,添加国内镜像源:
bash
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.xuanyuan.me",
"https://docker.1ms.run",
"https://docker.m.daocloud.io"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
1.3 启动 Milvus
bash
bash standalone_embed.sh start
脚本会自动拉取镜像(默认 milvusdb/milvus:v2.6.2),创建容器并等待约 90 秒初始化。看到 "Start successfully." 即安装成功。
端口说明:
19530:gRPC 服务端口(SDK 连接用)9091:WebUI 管理界面(可通过浏览器访问)2379:内嵌 etcd 端口(一般不用关心)
二、让 Milvus 持续驻留,告别"自动掉线"
很多同学反映容器运行一段时间后就自己停了,尤其是在锁屏或重启虚拟机之后。问题核心在于:
- 容器没有自动重启策略
- 虚拟机锁屏后可能挂起(Suspend)
2.1 添加容器自动重启策略
在脚本启动成功后,立即执行:
bash
docker update --restart unless-stopped milvus-standalone
这样即使容器异常退出(如 OOM、etcd 故障),Docker 也会自动把它拉起来。
2.2 安全地禁止虚拟机挂起(非常重要!)
千万不要 用 systemctl mask sleep.target ... ,它会导致图形界面无法启动或黑屏!取而代之,我们编辑 /etc/systemd/logind.conf 并重启服务:
bash
sudo sed -i 's/^#HandleSuspendKey=.*/HandleSuspendKey=ignore/' /etc/systemd/logind.conf
sudo sed -i 's/^#HandleLidSwitch=.*/HandleLidSwitch=ignore/' /etc/systemd/logind.conf
sudo systemctl restart systemd-logind
这样锁屏或合上笔记本盖都不会触发挂起,且完全不影响桌面环境。
2.3 限制 Docker 日志防止磁盘爆满(血的教训!)
如果容器日志无限制,几天就可能占满整个虚拟机磁盘,导致容器退出(状态 Exited)。在 /etc/docker/daemon.json 中追加日志限制:
bash
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [...],
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
EOF
sudo systemctl restart docker
配置后已经运行的容器不会立即生效 ,需要重建容器或重启 Docker 后重新创建容器。如果当前容器未限制日志,可先 docker stop milvus-standalone && docker rm milvus-standalone 再重新运行脚本启动即可。
三、数据持久化与恢复
3.1 数据到底存在哪儿?
脚本启动时会自动将当前目录下的 volumes/milvus 映射到容器内的 /var/lib/milvus,因此所有向量数据和 etcd 元数据都在宿主机上。只要这个目录不被删除,容器怎么换都丢不了数据。
千万不要执行 bash standalone_embed.sh delete,这个命令会彻底删除数据目录!
3.2 "数据不见了"怎么办?
常见场景:重启 Milvus 后,用 Attu 或 pymilvus 连上发现集合为空。这大概率不是数据丢了,而是内嵌 etcd 元数据损坏或服务未正常启动。可通过以下步骤修复:
bash
# 1. 停止故障容器
docker stop milvus-standalone
docker rm milvus-standalone
# 2. 备份并重置 etcd 元数据(原有的向量数据还在)
mv /root/volumes/milvus/etcd /root/volumes/milvus/etcd_backup_$(date +%Y%m%d%H%M%S)
# 3. 重新用脚本启动(会自动生成新的 etcd 并扫描旧数据)
bash standalone_embed.sh start
docker update --restart unless-stopped milvus-standalone
启动后,之前的 collection 和向量数据会重新出现。
3.3 磁盘空间爆满的排查
突然发现根分区 100% 占用,常见元凶是:
- 容器内部数据(忘记挂载外部卷) :如果你某次用了错误的
docker run -v或没用挂载,Milvus 会将数据全部写入容器可写层,快速占满磁盘。此时docker container prune -f删除已停止的旧容器即可瞬间释放几十 GB。 - Docker 日志无限增长:日志大小限制必须提前设置,否则很快就吞掉磁盘。
四、常见错误与解决
| 错误信息 | 原因 | 解决办法 |
|---|---|---|
iptables: No chain/target/match by that name |
Docker 的 iptables 规则链丢失 | 重启 Docker 服务:sudo systemctl restart docker |
etcdserver: request timed out |
etcd 连接超时,元数据损坏 | 按上述"重置 etcd 元数据"步骤处理 |
| 容器反复重新启动 (Exited 255) | 通常为 etcd 损坏或 OOM | 查看日志 docker logs milvus-standalone,并考虑增加内存或重置 etcd |
pymilvus 连接 ECONNRESET |
服务未完全就绪或 etcd 故障 | 等待 1-2 分钟,或检查日志;若 etcd 报错则重置 etcd |
| Attu 连接成功但看不到集合 | etcd 元数据丢失 | 同样需要重置 etcd |
| 虚拟机锁屏后 Milvus 停止 | 系统挂起导致 | 按上面方法配置 logind.conf |
五、管理与连接
5.1 Attu 图形化连接
下载 Attu 桌面版或使用 Docker 版,连接地址:127.0.0.1:19530(如果在虚拟机内部访问)。
如果从宿主机访问,需在 VMware 中配置端口转发(NAT 模式)或使用桥接网络,防火墙放行 9091/19530/5432 等端口。
5.2 pymilvus 连接示例
python
from pymilvus import connections
connections.connect(host="localhost", port="19530")
5.3 备份 Milvus 数据
建议定期备份:
bash
sudo tar -czf /backup/milvus_$(date +%Y%m%d).tar.gz /root/volumes/milvus
六、总结与最佳实践
- 启动脚本 :始终用
standalone_embed.sh start,避免手动docker run时遗漏挂载参数。 - 自动重启 :创建后立即
docker update --restart unless-stopped。 - 防挂起 :使用
HandleSuspendKey=ignore代替systemctl mask。 - 日志限制:部署之初就配置 Docker deamon 日志上限。
- 数据备份 :定期打包
/root/volumes/milvus。 - 清理旧容器 :每周运行
docker container prune -f回收空间。
按照这样的配置,你的 Milvus 服务就能在 Docker 环境中非常稳定地运行,无论是开发调试还是作为 Dify 等应用的向量存储后端,都不会轻易掉线。希望本文对你有所帮助!