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

Rai*_*per 5 ruby-on-rails redis sidekiq digital-ocean docker-compose

我正在使用官方redis图像。sidekiqdockers

以下是图像yml的配置redis

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
Run Code Online (Sandbox Code Playgroud)

以下是我的代码Dockerfile-redis

FROM redis
COPY redis.conf /usr/local/etc/redis/redis.conf
CMD [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
Run Code Online (Sandbox Code Playgroud)

当我构建图像时,一切正常,但一段时间后 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
Run Code Online (Sandbox Code Playgroud)

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

USER root
CMD chown -R root:root /var/lib/redis/
CMD chown 777 /var/lib/redis/
CMD chown 777 /var/lib/redis/dump.rdb
Run Code Online (Sandbox Code Playgroud)

我已经尝试了755一次dir又一次644dbfilename但它对我没有用。Dockerfile-redis我还尝试了用户的上述配置,但在打开文件时redis仍然遇到相同的错误。permission denieddump.rdb

我不知道我在这里做错了什么。请在这件事上给予我帮助

mir*_*phd 8

闲置一小时后,Redis 将尝试将内存数据库转储到磁盘。

官方redis镜像中的 Redis 尝试在容器文件夹中写入 .rdb 文件/data,这是相当不幸的,因为它是 root 拥有的文件夹,而且也是一个非持久位置(如果您的容器/pod 写入那里的数据将会消失)崩溃)。

因此,在一小时不活动后,如果您redis以非 root 用户身份运行容器(例如,docker run -u 1007而不是 default 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
Run Code Online (Sandbox Code Playgroud)

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

docker run --rm -d --name redis -p 6379:6379 -u 1007 -v /tmp:/data redis
Run Code Online (Sandbox Code Playgroud)


0e1*_*val 5

似乎官方的 redis 镜像使用应用用户来运行 redis-server,而不是 root(这是安全最佳实践),无论用户定义如何 - 我从镜像的入口点 shell 脚本中提取了它:

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

当将卷安装到容器时,它由 root 用户拥有,它将覆盖图像层中的默认目录以及以前的权限。

看来 redis 镜像的目的不是将“/var/lib/redis”目录公开为卷,而是提供挂载到“/data/”以实现持久性:

如果启用持久性,数据将存储在 VOLUME /data 中,可以与 --volumes-from some-volume-container 或 -v /docker/host/dir:/data 一起使用(请参阅 docs.dockervolumes)。

有关 Redis 持久化的更多信息,请参阅http://redis.io/topics/persistence