【问题标题】:Redis permission denied while opening dump.rdb打开 dump.rdb 时 Redis 权限被拒绝
【发布时间】:2019-06-16 07:24:22
【问题描述】:

我在dockers 上使用带有sidekiq 的官方redis 图片。

以下是ymlredis 图像的配置:

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 中进行了以下更改,以将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

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

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

【问题讨论】:

    标签: ruby-on-rails redis docker-compose digital-ocean sidekiq


    【解决方案1】:

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

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

    因此,在闲置一个小时后,如果您以非 root 用户身份运行 redis 容器(例如 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 文件夹映射到外部位置(非root 用户,此处为:1007,具有写入权限),例如:

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

    【讨论】:

      【解决方案2】:

      无论用户定义如何,似乎官方 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
      

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

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

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

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

      【讨论】:

        【解决方案3】:

        从root启动docker容器,示例:

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

        【讨论】:

          猜你喜欢
          • 2013-01-08
          • 2013-03-13
          • 1970-01-01
          • 2014-04-05
          • 1970-01-01
          • 2020-05-31
          • 2018-09-08
          • 2018-03-20
          • 2016-03-13
          相关资源
          最近更新 更多