avatar

超级赛亚人技术站

保持饥饿,保持战斗

  • 首页
主页 RustFS 容器健康检查问题排查文档
文章

RustFS 容器健康检查问题排查文档

发表于 2天前 更新于 2天前
作者 Administrator
20~26 分钟 阅读

1. 问题描述

RustFS 容器启动后,Docker Compose 显示容器状态为 (unhealthy):

容器虽然正常运行(9001、9002 端口均正常监听),但健康检查持续失败,导致 Docker 认为容器不健康。

在通过 Docker Compose 部署 RAG 系统的底层向量数据库(Milvus-stack)时,对象存储组件 rustfs 启动后,Docker 容器状态持续显示为 (unhealthy)。该异常可能导致上层 milvus-standalone 服务由于等待底层存储就绪超时而启动失败,进而影响整个问答助手系统的向量检索功能。

2. 环境与配置信息

  • 组件角色:Milvus 向量数据库的底层对象存储(替代 MinIO)

  • 镜像版本:rustfs/rustfs:1.0.0-alpha.72

  • 网络环境:Docker 自定义网络 milvus-net

  • 核心端口:9002 (S3 兼容 API),9001 (Console WebUI)

  • 初始探针配置:

    YAML

    healthcheck:
      test: ["CMD", "sh", "-c", "wget -qO- http://localhost:9002/ || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 5

3. 排查过程

3.1 现象确认与初步收集

在执行 docker-compose up -d 启动基础组件栈后,通过 Portainer 面板及 docker ps 命令观察到 rustfs 容器的状态呈现为持续的 (unhealthy)。然而,上层依赖它的 standalone (Milvus) 尚未出现由于存储组件缺失导致的严重崩溃。

随即提取容器运行日志进行比对:

Bash

docker logs --tail 50 rustfs

日志分析结果:日志显示 RustFS API: http://172.22.0.5:9002 与 Console WebUI available at: http://172.22.0.5:9001... 均已成功启动,无任何 panic、Error 或网络绑定失败(如 address already in use)的报错。服务本身处于绝对健康的运行状态。

3.2 聚焦健康检查机制 (Healthcheck 探针分析)

既然服务本身正常,问题必定出在 Docker 的监控探针上。为了获取 Docker 探针视角的真实报错,提取了容器的详细健康检查审计日志:

Bash

docker inspect --format='{{json .State.Health.Log}}' rustfs

排查发现:探针历史记录中充斥着非 0 的退出码(Exit Code)。Docker 一旦捕获到非零退出码,即判定服务处于异常状态。

3.3 深入容器环境验证 (极简镜像黑盒探测)

探针命令执行失败,通常有两个原因:一是网络不通或页面返回 404;二是执行探针命令的环境本身存在缺失。为了验证后者,尝试进入容器内部手动执行诊断命令:

Bash

# 测试 1:尝试进入容器的 shell 环境
docker exec -it rustfs sh
# 实际结果:报错 "executable file not found in $PATH" (找不到 sh 命令)

# 测试 2:尝试直接调用网络工具
docker exec -it rustfs wget --help
# 实际结果:报错 "executable file not found in $PATH" (找不到 wget 命令)

推断验证:rustfs:1.0.0-alpha.72 采用了极致精简的构建策略(Distroless 或 Scratch 基础镜像)。整个容器内除了由 Rust 编译出的单一二进制可执行文件 /usr/bin/rustfs 之外,没有任何基础 Linux 核心工具集(无 sh、bash、curl、wget)。Docker 按照 YAML 指令去寻找 sh 准备执行 wget 时,直接吃了个闭门羹。

3.4 替代方案的尝试与阻碍 (API 探测碰壁)

在确认无法使用常规 Shell 工具后,团队尝试利用外部网络探测其原生 API 接口,模拟 MinIO 的标准健康检查流程:

Bash

# 尝试请求 S3 兼容的存活端点
curl -I http://localhost:9002/minio/health/live

阻碍:返回状态码为 HTTP/1.1 403 Forbidden。 原因剖析:RustFS 严格遵循 S3 规范。直接裸调接口会被安全机制拦截,要求必须附带复杂的 AWS Signature V4 签名(涉及 HMAC-SHA256 加密计算)。在不依赖外部脚本且无 Shell 环境的前提下,极难在简短的探针配置中完成动态签名构造。

3.5 最终排查定论

  1. 服务运行态:完全健康,端口监听正常。

  2. 异常根因:极简镜像环境与基于 Shell 的常规网络探针存在硬性不兼容。

  3. API 限制:严格的 S3 签名校验阻断了无状态的 HTTP 状态码探测。


4. 解决方案与实施部署

基于“容器内无 Shell 环境”这一硬性客观条件,最优解是调整容器编排层面的依赖逻辑,摒弃无效的内部探针。

4.1 移除无效探针

修改 docker-compose.yaml,将 rustfs 服务下方的 healthcheck 配置块完全删除,避免 Docker 引擎持续发起无效探测并产生误报。

4.2 降级编排依赖条件

修改 Milvus 主服务(standalone)的 depends_on 逻辑。将对 rustfs 的依赖条件从“等待健康检查通过”放宽为“等待容器启动完成”。因为 Rust 程序的启动速度极快(通常为毫秒级),放宽此条件不会造成级联启动失败。

配置修改如下:

YAML

  standalone:
    # ... (其他配置保持不变)
    depends_on:
      etcd:
        condition: service_healthy    # etcd 镜像包含 shell,保留健康检查
      rustfs:
        condition: service_started    # 适配极简镜像,仅等待容器启动

4.3 平滑更新验证

在服务器对应目录下执行以下命令,无损应用新配置:

Bash

docker-compose -f milvus-stack-2.6.6.compose.yaml up -d

验证结果:rustfs 容器重置后不再显示 unhealthy 标签,状态恢复正常。standalone 顺利挂载对象存储并建立连接,向量数据库集群成功拉起。


5. 总结与最佳实践

在进行大模型周边基础设施的容器化部署时,不可盲目照搬常规的 Healthcheck 配置。特别是针对使用 Golang、Rust 等编译型语言打包的 Distroless/Scratch 极简镜像,必须预先确认其内部是否包含基础 Shell 工具链。灵活运用 Docker Compose 的 service_started 依赖条件,是解决此类架构兼容性问题的标准途径。

许可协议:  CC BY 4.0
分享

相关文章

下一篇

上一篇

RPC接口超时怎么解决?

最近更新

  • RustFS 容器健康检查问题排查文档
  • RPC接口超时怎么解决?
  • 有 MySQL 为什么还要有 MongoDB?游戏业务的主力数据库
  • 解决MYSQL间隙锁引起的死锁
  • MySQL 间隙锁导致的死锁!全链路实战排查!

热门标签

故障排查

目录

©2026 超级赛亚人技术站. 保留部分权利。

使用 Halo 主题 Chirpy