1. 概述

在 Docker 容器中运行 Redis 服务时,我们可能会误以为容器启动就意味着服务可用。但实际上,容器运行并不等于 Redis 正常工作。例如,Redis 可能无法响应命令,或无法写入文件系统,这些都会导致服务处于“假死”状态。

Redis 通常用于缓存、队列、会话存储等关键任务。因此,在生产环境中,必须确保 Redis 处于健康、响应良好的状态。

本文将介绍如何使用官方 Redis 镜像(如 redis:6-alpine)中自带的工具来对 Redis 服务进行健康检查。我们会通过一个小型项目演示配置过程,讲解常见问题及解决方法。


2. 示例项目搭建

我们使用 Docker Compose 来运行 Redis 服务。

步骤如下:

  1. 创建项目目录并进入:
$ mkdir redis-healthcheck-demo && cd redis-healthcheck-demo
  1. 创建 docker-compose.yml 文件:
version: '3.8'

services:
  redis:
    image: redis:6-alpine
    container_name: redis_server
    ports:
      - "6379:6379"
  1. 启动容器:
$ docker-compose up -d

容器启动后,我们就可以在本地通过 localhost:6379 访问 Redis。


3. 添加基础健康检查

Redis 官方镜像自带了 redis-cli 工具,我们可以用它来执行 ping 命令,验证 Redis 是否正常响应。

修改 docker-compose.yml

version: '3.8'

services:
  redis:
    image: redis:6-alpine
    ports:
      - "6379:6379"
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 3

这个配置告诉 Docker:

  • 每 10 秒执行一次 redis-cli ping
  • 每次最多等待 5 秒
  • 连续失败 3 次则标记为 unhealthy

4. 验证健康状态

启动容器:

$ docker-compose up -d

查看健康状态:

$ docker inspect --format='{{json .State.Health}}' $(docker-compose ps -q redis) | jq

输出示例:

{
  "Status": "healthy",
  "FailingStreak": 0,
  "Log": [
    {
      "Start": "2025-04-30T18:36:58.834324106Z",
      "End": "2025-04-30T18:36:58.913174172Z",
      "ExitCode": 0,
      "Output": "PONG\n"
    }
  ]
}
  • Status: healthy 表示 Redis 健康
  • Log 显示了每次健康检查的详细日志

⚠️ 注意:jq 是一个用于格式化输出 JSON 的工具,若未安装可省略,直接使用 docker inspect 查看原始输出。


5. 使用自定义脚本进行健康检查

有时候我们希望添加更多检查逻辑,比如判断响应是否为 PONG,或者检查 Redis 的写入能力。

创建脚本 healthcheck.sh

#!/bin/sh

response=$(redis-cli ping)

if [ "$response" != "PONG" ]; then
  echo "Health check failed: $response"
  exit 1
else
  echo "Redis responded: $response"
  exit 0
fi

赋予执行权限:

$ chmod +x healthcheck.sh

修改 docker-compose.yml

version: '3.8'

services:
  redis:
    image: redis:6-alpine
    ports:
      - "6379:6379"
    volumes:
      - ./healthcheck.sh:/usr/local/bin/healthcheck.sh
    healthcheck:
      test: ["CMD-SHELL", "/usr/local/bin/healthcheck.sh"]
      interval: 10s
      timeout: 5s
      retries: 3

重启服务并验证:

$ docker-compose down && docker-compose up -d --build

查看状态:

$ docker ps

输出中会显示 healthyunhealthy


6. 解决常见的 ContainerConfig 错误

错误信息示例:

ERROR: for redis_server  'ContainerConfig'
...
KeyError: 'ContainerConfig'

这是由于本地缓存的 Redis 镜像损坏或不完整导致的。

解决方法:

  1. 停止容器:
$ docker-compose down
  1. 删除镜像:
$ docker rmi redis:6-alpine
  1. 重新构建并启动:
$ docker-compose up -d --build

Docker 会重新拉取完整镜像,避免此类错误。


7. 模拟 Redis 故障

为了验证健康检查是否有效,我们可以模拟 Redis 服务故障,而不关闭整个容器。

创建 redis-entrypoint.sh

#!/bin/sh

redis-server &
echo $! > /tmp/redis.pid
tail -f /dev/null

赋予执行权限:

$ chmod +x redis-entrypoint.sh

更新 docker-compose.yml

services:
  redis:
    image: redis:6-alpine
    ports:
      - "6379:6379"
    volumes:
      - ./healthcheck.sh:/usr/local/bin/healthcheck.sh
      - ./redis-entrypoint.sh:/usr/local/bin/redis-entrypoint.sh
    entrypoint: ["/bin/sh", "/usr/local/bin/redis-entrypoint.sh"]
    healthcheck:
      test: ["CMD-SHELL", "/usr/local/bin/healthcheck.sh"]
      interval: 10s
      timeout: 5s
      retries: 3

重建并启动容器:

$ docker-compose down && docker-compose up -d --build

模拟 Redis 崩溃:

$ docker exec -it redis-healthcheck-demo_redis_1 sh -c 'kill $(cat /tmp/redis.pid)'

稍等片刻后查看状态:

$ docker ps

输出中应显示容器状态为 unhealthy,说明健康检查成功检测到故障。


8. 总结

通过本文,我们完成了以下工作:

✅ 在 Docker 中部署 Redis
✅ 配置了基于 redis-cli ping 的基本健康检查
✅ 编写并使用了自定义健康检查脚本
✅ 解决了常见的镜像缓存问题
✅ 模拟了 Redis 服务故障并验证健康检查有效性

即使容器运行正常,Redis 也可能处于“假死”状态。因此,建议始终为 Redis 配置健康检查机制,使用 redis-cli 或自定义脚本,确保服务可用性。

掌握这些技巧后,你就能更有效地监控 Docker 中 Redis 的运行状态,提升服务的稳定性与可靠性。


原始标题:How to Check the Health of a Redis Server in a Docker Image