1. 概述
在 Docker 容器中运行 Redis 服务时,我们可能会误以为容器启动就意味着服务可用。但实际上,容器运行并不等于 Redis 正常工作。例如,Redis 可能无法响应命令,或无法写入文件系统,这些都会导致服务处于“假死”状态。
Redis 通常用于缓存、队列、会话存储等关键任务。因此,在生产环境中,必须确保 Redis 处于健康、响应良好的状态。
本文将介绍如何使用官方 Redis 镜像(如 redis:6-alpine
)中自带的工具来对 Redis 服务进行健康检查。我们会通过一个小型项目演示配置过程,讲解常见问题及解决方法。
2. 示例项目搭建
我们使用 Docker Compose 来运行 Redis 服务。
步骤如下:
- 创建项目目录并进入:
$ mkdir redis-healthcheck-demo && cd redis-healthcheck-demo
- 创建
docker-compose.yml
文件:
version: '3.8'
services:
redis:
image: redis:6-alpine
container_name: redis_server
ports:
- "6379:6379"
- 启动容器:
$ 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
输出中会显示 healthy
或 unhealthy
。
6. 解决常见的 ContainerConfig 错误
错误信息示例:
ERROR: for redis_server 'ContainerConfig'
...
KeyError: 'ContainerConfig'
这是由于本地缓存的 Redis 镜像损坏或不完整导致的。
解决方法:
- 停止容器:
$ docker-compose down
- 删除镜像:
$ docker rmi redis:6-alpine
- 重新构建并启动:
$ 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 的运行状态,提升服务的稳定性与可靠性。