1. 离线环境部署Milvus的核心挑战
在完全隔离网络的环境中部署Milvus向量数据库,就像在没有超市的荒岛上搭建一个完整的厨房系统。我去年在金融行业的一个保密项目中就遇到过这种场景,当时花了整整三天时间才把所有依赖理顺。离线部署最大的难点在于依赖链条的完整性——你永远不知道哪个看似不起眼的组件会成为压垮骆驼的最后一根稻草。
CentOS 7.x系列(特别是7.6-7.9版本)作为企业级Linux发行版,其稳定性是优势,但老旧的软件源和内核版本会带来三个典型问题:
- 依赖库版本冲突:比如glibc的版本可能不满足Docker最新版要求
- 内核模块缺失:OverlayFS等现代存储驱动需要内核支持
- 软件包兼容性:Python等基础组件的版本可能过低
实测发现,在CentOS 7.9上部署Milvus 2.4.5时,至少需要准备以下组件:
- Docker CE 23.0.1(太新的版本反而容易出问题)
- Docker Compose v2.16.0(必须匹配Docker版本)
- Milvus standalone镜像包(包含etcd、minio等所有依赖)
- 基础依赖库(如libstdc++.so.6的最新版)
提示:建议准备一个至少100GB的临时存储空间,因为光Docker和Milvus的镜像包就可能占用超过30GB
2. Docker环境的离线搭建
2.1 依赖包的系统性准备
很多人以为离线安装Docker就是下载个rpm包那么简单,其实这是个典型的认知误区。我在某次政府项目部署时就踩过坑——直接安装docker-ce-23.0.1.rpm后出现container-selinux依赖错误。正确的做法应该是分层下载依赖:
# 在有网络的机器上创建下载目录 mkdir -p ~/docker-offline/centos7 cd ~/docker-offline/centos7 # 使用yumdownloader下载主包及依赖 yum install -y yum-utils repotrack --arch=x86_64 docker-ce-23.0.1 docker-ce-cli-23.0.1 containerd.io docker-buildx-plugin docker-compose-plugin # 检查下载内容(应该看到几十个rpm包) ls -lh下载完成后,用tar -zcvf docker-offline.tar.gz *打包,然后通过U盘或内部文件服务器传输到目标机器。这里有个细节:CentOS 7.6和7.9的依赖包略有差异,建议按实际系统版本分别准备。
2.2 离线安装的关键步骤
在目标机器上执行安装时,最容易出问题的环节是依赖解析顺序。我总结的最佳实践是:
# 解压传输过来的安装包 tar -zxvf docker-offline.tar.gz -C /tmp/docker-offline # 按特定顺序安装关键依赖 cd /tmp/docker-offline rpm -ivh libcgroup-*.rpm rpm -ivh container-selinux-2.119.2-1.911c772.el7_8.noarch.rpm rpm -ivh containerd.io-*.rpm rpm -ivh docker-ce-*.rpm # 验证安装 systemctl start docker docker --version # 应显示23.0.1如果遇到/lib64/libc.so.6: version GLIBC_2.28 not found这类错误,说明系统GCC环境太旧。这时需要手动安装较新版本的libstdc++:
rpm -ivh libstdc++-8.3.1-5.1.el7.x86_64.rpm3. Milvus镜像的离线准备
3.1 在线环境预部署
在可联网的跳板机上,建议使用以下优化过的部署脚本:
# 创建专用目录避免污染环境 mkdir -p ~/milvus-offline && cd ~/milvus-offline # 使用国内镜像加速下载 cat > daemon.json <<EOF { "registry-mirrors": ["https://registry.cn-hangzhou.aliyuncs.com"] } EOF sudo mv daemon.json /etc/docker/ # 下载standalone部署脚本 wget https://ghproxy.com/https://raw.githubusercontent.com/milvus-io/milvus/master/scripts/standalone_embed.sh chmod +x standalone_embed.sh # 启动服务(会自动拉取所有依赖镜像) ./standalone_embed.sh start这个过程中,关键是要监控镜像下载情况:
docker images | grep milvus应该能看到如下核心镜像:
- milvusdb/milvus:v2.4.5
- quay.io/coreos/etcd:v3.5.5
- minio/minio:RELEASE.2023-03-20T20-16-18Z
3.2 镜像打包与传输
打包时有个技巧:使用docker save的批量操作模式可以显著减少文件体积:
# 批量打包所有相关镜像 docker save \ milvusdb/milvus:v2.4.5 \ quay.io/coreos/etcd:v3.5.5 \ minio/minio:RELEASE.2023-03-20T20-16-18Z \ -o milvus-offline.tar # 检查打包文件(正常应该超过5GB) ls -lh milvus-offline.tar传输到离线环境后,加载时建议先检查磁盘空间:
# 查看可用空间(至少需要打包文件两倍的空间) df -h /var/lib/docker # 加载镜像 docker load -i milvus-offline.tar # 验证加载结果 docker images | grep -E 'milvus|etcd|minio'4. 离线环境部署实战
4.1 部署脚本的适配改造
直接从GitHub下载的standalone_embed.sh在离线环境直接运行会失败,需要做三处关键修改:
注释掉镜像拉取逻辑: 找到
pull_images()函数,在开头添加return 0修改健康检查策略: 将
wait_for_healthy()中的超时时间从300秒延长到600秒禁用版本检查: 在
main()函数开始处添加SKIP_CHECK_VERSION=true
修改后的脚本应该通过内网文件共享传输到目标机器,记得赋予执行权限:
chmod +x standalone_embed.sh4.2 服务启动与验证
启动命令和在线环境看似相同,但有几个隐蔽的坑需要注意:
# 启动服务(建议在tmux或screen中运行) ./standalone_embed.sh start # 查看实时日志(观察有无报错) docker logs -f milvus-standalone如果看到[ERROR] [sessionutil/session_util.go:53] ["failed to connect to etcd"]之类的错误,通常是etcd没有正常启动。这时候需要分步排查:
# 检查各容器状态 docker ps -a --filter "name=milvus" # 单独检查etcd日志 docker logs etcd成功启动的标志是在日志中出现[INFO] [server/server.go:276] ["Milvus Proxy start successfully"]。此时可以用Attu客户端验证:
# 获取Milvus容器IP MILVUS_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' milvus-standalone) # 使用curl简单测试(应该返回HTTP 200) curl -I http://${MILVUS_IP}:195305. 常见问题排错指南
5.1 存储空间不足问题
在资源有限的服务器上,最容易遇到磁盘爆满的情况。我常用的清理策略是:
# 查看Docker磁盘使用 docker system df # 针对性清理 docker volume prune # 清理无用卷 docker image prune -a # 清理悬空镜像如果还是空间不足,可以考虑修改Docker的存储位置:
# 创建新的存储目录 mkdir -p /data/docker # 修改服务配置 cat > /etc/docker/daemon.json <<EOF { "data-root": "/data/docker" } EOF # 重启服务 systemctl restart docker5.2 端口冲突处理
Milvus standalone模式默认会占用以下关键端口:
- 19530(Milvus服务)
- 9091(指标监控)
- 2379(etcd)
如果遇到Address already in use错误,可以通过修改standalone_embed.sh中的映射规则来解决:
# 找到docker run命令中的端口映射部分 # 将原始参数: -p 19530:19530 -p 9091:9091 # 改为: -p 29530:19530 -p 29091:90915.3 性能调优建议
离线环境通常资源有限,可以通过这些参数提升性能:
# 修改standalone_embed.sh中的启动参数 --cache_size=4GB # 根据内存调整 --knowhere_thread_num=8 # CPU核心数的一半 --enable_system_metrics=false # 关闭监控节省资源对于需要长期运行的场景,建议配置日志轮转:
# 在/etc/docker/daemon.json中添加 { "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "3" } }6. 部署后的维护策略
离线环境下的维护比在线环境复杂得多,我通常会建立以下机制:
定期健康检查脚本:
#!/bin/bash MILVUS_STATUS=$(docker inspect -f '{{.State.Status}}' milvus-standalone) if [ "$MILVUS_STATUS" != "running" ]; then echo "[CRITICAL] Milvus container is $MILVUS_STATUS" docker logs milvus-standalone | tail -50 fi数据备份方案:
# 备份元数据(etcd) docker exec etcd etcdctl snapshot save /backup/etcd.db # 备份存储数据(minio) docker cp minio:/data /backup/minio_data版本升级预案: 在测试环境先打包新版本镜像,通过以下命令对比变更:
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower --run-once --monitor-only milvus-standalone
在实际生产环境中,这些准备工作可能看起来繁琐,但当你真的遇到网络隔离的情况时,前期细致的准备会让部署过程顺利很多。最近一次在军工企业的部署中,我们甚至准备了针对不同内核版本的备用方案,最终在系统内核版本不一致的三台机器上都成功部署了Milvus集群。