我正在docker容器中运行Redis,并且正在使用Redis标记模式。 我已经设置了以下配置-
3 redis sentinels nodes
1 redis master node
2 redis slave nodes
我正在本地计算机上运行所有这些程序。因此,总共有6个docker容器在网桥联网模式下通过docker-compose
运行。
所有conatiners都具有到外部的端口映射。
所有容器都可以彼此访问,就像它们在docker-compose up
运行期间创建的同一桥docker网络中一样。
我已经使用Redisson库创建了Java客户端来访问Redis。 将客户端配置为使用redis-sentinel模式,如下所示-
Config config = new Config();
config.useSentinelServers()
.setMasterName("redis-master")
.addSentinelAddress("redis://127.0.0.1:26379")
.addSentinelAddress("redis://127.0.0.1:26380")
.addSentinelAddress("redis://127.0.0.1:26381")
RedissonClient client = Redisson.create(config);
这是我面临的问题。 每当我尝试通过此客户端在Redis上运行一些命令时,请求都会通过哨兵节点,从而为我提供当前的Redis主节点地址。 但是我的Java客户端无法直接与Redis主机进行通信,因为哨兵节点返回的IP是主机节点的内部Docker网络IP,无法在Docker网络外部访问,并且失败,出现类似以下的异常-
Exception in thread "main" org.redisson.client.RedisConnectionException: Unable to connect to Redis server: 172.21.0.2/172.21.0.2:6379
at org.redisson.connection.pool.ConnectionPool$2$1.operationComplete(ConnectionPool.java:161)
at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:511)
如何解决此问题? 我需要在其他网络模式下运行它吗? 或某种方式将此内部docker ip转换为运行docker conatiners的计算机的实际ip?
答案 0 :(得分:0)
我今天也遇到了这个问题,试图为测试实例进行设置。我最初的撰写文件基于https://blog.alexseifert.com/2016/11/14/using-redis-sentinel-with-docker-compose/,并进行了修改以满足我的需要。我能够找到一种解决方法,方法是:1)将端口绑定到我的主机上; 2)在docker-compose中设置depends_on标志; 3)设置我的sentinel.conf指向我的主服务器正在运行的主机名: https://docs.docker.com/compose/startup-order/
有点难以解释,但我会尽力而为: 您的主服务器/副本在docker-compose中将如下所示:
redis-master:
image: redis:5.0.4-alpine
volumes:
- <mounted-data-directory>
- "<local-master-config-directory>/redis.conf:/usr/local/etc/redis/redis.conf"
ports:
- "6379:6379"
command:
- redis-server
- /usr/local/etc/redis/redis.conf
redis-replica:
image: redis:5.0.4-alpine
links:
- redis-master
volumes:
- <mounted-data-directory>
- "<local-replica-config-directory>:/usr/local/etc/redis/redis.conf"
ports:
- "6380:6380"
depends_on:
- redis-master
command:
- redis-server
- /usr/local/etc/redis/redis.conf
- --slaveof redis-master 6379
对于我的哨兵,我给了每个Dockerfile和一个sentinel.conf(每个都有不同的端口): Dockerfile:
FROM redis:5.0.4-alpine
RUN mkdir -p /redis
WORKDIR /redis
COPY sentinel.conf .
RUN chown redis:redis /redis/*
ENTRYPOINT ["redis-server", "/redis/sentinel.conf", "--sentinel"]
sentinel.conf
port 26379
dir /tmp
bind 0.0.0.0
sentinel monitor mymaster <hostname> 6379 2
sentinel down-after-milliseconds mymaster 1000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 10000
值得注意的是,我尝试使用127.0.0.1和localhost来执行此操作,但我认为这都不起作用,因此我在运行该程序的计算机上设置了主机名。那时我有点尝试任何事情。
每个哨兵(我有三个)都有一个单独的条目,它们引用他们的构建上下文并将sendinel.conf中的端口映射到本地端口。所以在docker-compose中,我的前哨看起来像这样:
# Instance 1
redis-sentinel:
build:
context: <path-to-context>
links:
- redis-master
ports:
- "26379:26379"
depends_on:
- redis-replica
我所做的肯定是黑客,我不会在生产中使用它。我很确定有一个针对docker的更好的网络解决方案,我只是不想为需要测试的内容走得太远。希望这会有所帮助。