打开 dump.rdb 时 Redis 权限被拒绝

Redis permission denied while opening dump.rdb

我在 dockers 上使用官方 redis 图片和 sidekiq

以下是 redis 图片的 yml 配置:

redis:
  build: .
  dockerfile: Dockerfile-redis
  ports:
    - '6379:6379'
  volumes:
    - 'redis:/var/lib/redis'

sidekiq:
  build: .
  command: bundle exec sidekiq
  links:
    - db
    - redis
  volumes:
    - .:/app
  env_file:
    - .env

以下是我的Dockerfile-redis的代码:

FROM redis
COPY redis.conf /usr/local/etc/redis/redis.conf
CMD [ "redis-server", "/usr/local/etc/redis/redis.conf" ]

当我构建图像时一切正常,但一段时间后 docker-compose logs 显示以下 permission 错误:

redis_1          | 98:C 22 Jan 2019 18:40:10.098 # Failed opening the RDB file dump.rdb (in server root dir /var/lib/redis) for saving: Permission denied
redis_1          | 1:M 22 Jan 2019 18:40:10.203 # Background saving error

我已经尝试了很多解决方案,但我仍然在日志中收到此错误。每次 redis 打开 dump.rdb 文件的权限都被拒绝。我也遵循了 this 解决方案并在我的 Dockerfile-redis 中做了以下更改以授予 rootredis

的许可
USER root
CMD chown -R root:root /var/lib/redis/
CMD chown 777 /var/lib/redis/
CMD chown 777 /var/lib/redis/dump.rdb

我已经尝试 755 用于 dir644 用于 dbfilename 但它对我不起作用。我还尝试了 Dockerfile-redisredis 用户的上述配置,但我仍然在打开 dump.rdb 文件时遇到相同的 permission denied 错误。

我不知道我做错了什么。请帮我解决这个问题

似乎官方的 redis 图像正在使用一个应用用户 运行 redis-server 而不是 root(这是一个安全的最佳实践),不管 USER 定义如何 - 我从图像的入口点提取这个shell 脚本:

# allow the container to be started with `--user`
if [ "" = 'redis-server' -a "$(id -u)" = '0' ]; then
    find . \! -user redis -exec chown redis '{}' +
    exec gosu redis "[=10=]" "$@"
fi

将卷挂载到容器时,它归 root 用户所有,它将覆盖镜像层中的默认目录以及之前的权限。

redis 镜像的意图似乎不是将“/var/lib/redis”目录公开为一个卷,而是提供 mounting to '/data/' 用于持久化:

If persistence is enabled, data is stored in the VOLUME /data, which can be used with --volumes-from some-volume-container or -v /docker/host/dir:/data (see docs.docker volumes).

For more about Redis Persistence, see http://redis.io/topics/persistence.

一个小时不活动后,Redis 将尝试将内存数据库转储到磁盘。

来自官方 redis 镜像的 Redis 尝试将 .rdb 文件写入容器 /data 文件夹,这很不幸,因为它是一个 root-owned 文件夹并且它是还有一个 non-persistent 位置(如果你的 container/pod 崩溃,写入那里的数据将会消失)。

所以在一个小时不活动之后,如果您有 运行 您的 redis 容器作为 non-root 用户(例如 docker run -u 1007 而不是默认的 docker run -u 0 ),您将在日志中收到非常详细的错误消息(参见 docker logs redis):

1:M 29 Jun 2019 21:11:22.014 * 1 changes in 3600 seconds. Saving...
1:M 29 Jun 2019 21:11:22.015 * Background saving started by pid 499
499:C 29 Jun 2019 21:11:22.015 # Failed opening the RDB file dump.rdb (in server root dir /data) for saving: Permission denied
1:M 29 Jun 2019 21:11:22.115 # Background saving error

所以你需要做的是将容器的 /data 文件夹映射到外部位置(non-root 用户,此处:1007,具有写入权限),例如:

docker run --rm -d --name redis -p 6379:6379 -u 1007 -v /tmp:/data redis

从 root 启动 docker 容器,示例:

redis:
  build: .
  dockerfile: Dockerfile-redis
  user: root <-- REQUIRE
  ports:
    - '6379:6379'
  volumes:
    - 'redis:/var/lib/redis'