从主机连接运行在Docker容器中的Redis

87

我看到很多人在这方面遇到问题,感觉redis容器镜像可能存在漏洞,而其他人似乎也在追踪类似的问题。

我正在使用DockerHub上的标准redis镜像。(https://github.com/dockerfile/redis

像这样运行它:

docker run -it -p 6379:6379 redis bash

一旦我进入容器,我就可以启动服务器并从容器镜像中进行redis ping。

不幸的是,我无法从我的主机连接到redis容器。

我尝试了以下设置:

bind 127.0.0.1

并从配置中删除了绑定

并尝试关闭保护模式

protected-mode no

我知道它正在读取配置文件,因为我只是为了测试而更改端口,而我成功做到了。

我正在运行Windows 10,所以可能是Windows网络问题。通常我从不遇到Docker的问题。我感到困惑。


你是如何尝试连接到Redis容器的?你是尝试访问Redis容器内部的bash,还是尝试使用6379端口连接到Redis容器? - Rafaf Tahsin
9个回答

81

问题出在您的绑定上,您应该设置以下内容:

bind 0.0.0.0

这将使redis绑定到所有可用的接口,在容器化环境中,有一个接口(eth0)和一个回环(lo),redis会绑定到上述两个接口。 您应该考虑通过配置文件中的其他指令或使用类似防火墙的外部工具添加安全措施,因为采用这种方法,任何人都可以连接到您的redis服务器。

默认设置是bind 127.0.0.1,这将导致redis只侦听回环接口,并且只能从容器内部访问它。(出于安全考虑)

要使用自定义配置文件运行redis:

sudo docker run -d --name redis-test -p 6379:6379  -v /path/to/redisconf/redis.conf:/redis.conf redis redis-server /redis.conf

现在在安装了redis-tools的Docker主机上进行验证:

redis-cli                           
127.0.0.1:6379> 
127.0.0.1:6379> set farhad likes:stackoverflow
OK
127.0.0.1:6379> get farhad
"likes:stackoverflow"
127.0.0.1:6379> 

您还可以通过以下方式从外部主机连接到redis容器:

redis-cli -h 'IP-address-of-dockerhost-running-redis-container'

谢谢你的帮助,但还没有完全解决我的问题。看起来Redis不喜欢我从主机连接,但我启动了第二个Docker镜像,并获取了redis Docker镜像的IP地址,然后我就能够连接了。从第二个Docker镜像中,我可以这样连接到Redis服务器:redis-cli -h 172.17.0.2 - user3888307
感谢Farhad的帮助。看起来这与Docker Hub上的redis镜像有关,我在Ubuntu服务器上安装了redis,它按照我的期望工作。我将使用它来访问本地主机的redis。 - user3888307
1
在这个答案之前应该有一个警告,用大而粗的红字写着:“如果你只是应用这个,你的服务器将会被黑客攻击”。 - pkExec
1
@pkExec,也许在复制粘贴之前可以先阅读一下答案?“你应该考虑通过配置文件中的其他指令或使用外部工具(如防火墙)添加安全措施。因为采用这种方法,任何人都可以连接到你的Redis服务器。”如果需要,我可以将其加粗,但不是红色 :) - Farhad Farahi
在我的测试中,似乎默认情况下,只要将端口映射到主机上,Docker容器就可以从远程访问。 - Eric
显示剩余2条评论

76

这是设置Redis容器的更简单的方法。

下载镜像并运行容器

docker run -d --name some-redis -p 6379:6379 redis

如果您没有该镜像,此命令将会拉取它。然后,如果需要从 redis-cli 访问控制台,可以使用:

若无图像,则拉取该图像;如需从 redis-cli 访问控制台,则可使用以下命令:

docker exec -it some-redis bash

进入容器控制台后,在控制台中输入:

root@72c388dc2cb8:/data# redis-cli

输出:

127.0.0.1:6379> 

这足以满足我的使用场景 (简单快速的本地开发)。


11
看起来这是个不错的解决方案!我可以通过运行以下命令docker exec -it some-redis redis-cli直接打开redis-cli,跳过bash步骤。 - dana
43
这完全与问题中所要求的相反。他想要从主机环境(容器运行的环境)连接到在容器中运行的redis服务器。也就是说,如果你在Linux机器上启动了一个redis容器,他希望能够从Linux机器访问它,而不是从redis容器内部访问。 - cyphx

8

如果使用版本为4.0.9Docker Toolbox on Win10,那么连接Redis客户端会更加容易。只需按照以下步骤操作:

set bind 0.0.0.0
save

新的设置在停止/启动后仍然有效。

5

以下是使其正常工作的一些说明。

安装官方 Docker 而不是发行版仓库。

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
systemctl enable docker ; systemctl start docker; systemctl status docker

请参考使用方便脚本安装

从主机连接到Redis容器

mkdir -p /etc/redis/
chown -R 1000:1000 /etc/redis
sudo docker run -d --name redis -p 6379:6379 --restart unless-stopped -v /etc/redis/:/data redis redis-server /data

注意:对于您的解决方案至关重要的部分是将端口暴露 (-p 6379:6379) 给您的 Docker 主机并将其路由到容器端口。 请参考Redis Docker 文档

在您的 Docker 主机上安装 "redis-tools"。CentOS 可通过 epel 发行版安装 Redis。


4
使用以下命令创建Redis容器:
sudo docker run -d --name redis-test -p 6379:6379  -v /redis/redis.conf:/redis.conf redis redis-server /redis.conf --appendonly yes --requirepass "redis"

如果您要访问同一台计算机中的Redis,可以使用Redis-CLI,如果您使用其他计算机,则使用主机IP地址。如果您要访问同一主机上的Redis容器中的另一个Docker容器,则使用机器的私有IP地址


比写配置文件好多了。 - Mohammad Rijwan

1

docker-compose.yml

version: '3.7'

services:
  redis_1:
    image: 'redis:6.0.6'
    ports:
      - '6371:6379'
  redis_2:
    image: 'redis:6.0.6'
    ports:
      - '6372:6379'

在您的主机上:

docker compose up

redis-cli -p 6371 ping
redis-cli -p 6372 ping

0

如果您正在使用来自Windows的WSL2并在Docker或Podman中运行redis,

  • 获取并运行podman容器(如果是docker,请替换):

    podman run -d --rm --name redis_server -v redis-data:/var/redis/data -p 6379:6379 redis

上述命令创建并挂载名为redis-data的持久卷(如果不存在),并将其公开到端口6379

  • 使用ifconfig -a在您的WSL2 Ubuntu/Pengwin中获取IP地址。
  • 使用IP和端口从Windows机器连接到redis-insight

enter image description here


0

如果您想在Docker容器中运行Redis集群。

答案在Redis自我记录的redis.conf文件中,以下是文件中的一部分,告诉您如何像专业人士一样解决问题。

所有荣誉归于redis.conf文件,适用于Redis版本6及以上。

########################## CLUSTER DOCKER/NAT support  ########################

# In certain deployments, Redis Cluster nodes address discovery fails, because
# addresses are NAT-ted or because ports are forwarded (the typical case is
# Docker and other containers).
#
# In order to make Redis Cluster working in such environments, a static
# configuration where each node knows its public address is needed. The
# following two options are used for this scope, and are:
#
# * cluster-announce-ip
# * cluster-announce-port
# * cluster-announce-bus-port
#
# Each instructs the node about its address, client port, and cluster message
# bus port. The information is then published in the header of the bus packets
# so that other nodes will be able to correctly map the address of the node
# publishing the information.
#
# If the above options are not used, the normal Redis Cluster auto-detection
# will be used instead.
#
# Note that when remapped, the bus port may not be at the fixed offset of
# clients port + 10000, so you can specify any port and bus-port depending
# on how they get remapped. If the bus-port is not set, a fixed offset of
# 10000 will be used as usual.
#
# Example:
#
# cluster-announce-ip 10.1.1.5
# cluster-announce-port 6379
# cluster-announce-bus-port 6380

0
发现许多关于无法从 Windows 主机连接到在 WSL2 上作为 Docker 容器运行的 Redis 的文章、问题和 Github 问题,其中许多建议修复涉及 IP 映射。然而,使用最近(2022 年左右)的 WSL2 和 Redis 镜像版本时,我遇到了类似的问题,但解决方法很简单。 我正在使用 docker-compose,骨架设置如下:
services:
  redis:
    image: redis:7.0
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data

但是,当从非 WSL 的 Docker 环境中复制并粘贴时,我也遇到了一些问题

    network_mode: host

这个问题导致我无法从 Windows 主机连接到在 WSL 下运行的容器。一旦我删除了那行代码,Docker 为服务创建了一个默认网络,我就可以连接上了(使用 127.0.0.1:6379)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接