打开 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
中做了以下更改以授予 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
我已经尝试 755
用于 dir
和 644
用于 dbfilename
但它对我不起作用。我还尝试了 Dockerfile-redis
与 redis
用户的上述配置,但我仍然在打开 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'
我在 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
中做了以下更改以授予 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
我已经尝试 755
用于 dir
和 644
用于 dbfilename
但它对我不起作用。我还尝试了 Dockerfile-redis
与 redis
用户的上述配置,但我仍然在打开 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'