Docker 上的 Redis Sentinel 提供 Docker 网络 IP 地址

问题描述 投票:0回答:1

我的目标是使用 Docker 在单个 Docker VM 上设置 3x Redis 服务器和 3x Redis Sentinel,并将每个 Redis 服务器和 Sentinels 暴露给本地网络。

我的Docker主机的静态IP是192.168.2.90.

我给 Redis 服务器端口编号为 6379、6380、6381,并通过 Docker 公开了这些端口。

我的本地网络是192.168.2.0/24

我的Docker机器的内网是172.16.0.0/12.

一切都在 Docker 容器本身内运行良好。当我尝试使用本地网络上的另一台机器连接到 Redis 时,问题就来了。

我的 python 测试脚本成功连接到 Redis Sentinel。问题是当它发现主从时,地址都在 172.16.0.0/12 子网上。

Redis master: 
('172.18.3.1', 6379)

Redis slaves: 
[('172.18.3.3', 6381), ('192.168.2.90', 6379),('172.18.3.2', 6380)]

当我远程登录到 master 并运行 INFO 时,它同样给了我 172.16.0.0/12 地址。

role:master
connected_slaves:2 
slave0:ip=172.18.3.3,port=6381,state=online,offset=252692195,lag=0
slave1:ip=172.18.3.2,port=6380,state=online,offset=252692195,lag=0

我不知道如何让 Redis Server 和 Redis Sentinel 报告 192.168.2.0/24 子网。

我定义了我的 Redis 服务器容器如下:

  redis-a-1:
    container_name: redis-a-1
    hostname: redis-a-1
    image: redis
    command: "redis-server --port 6379 --bind-source-addr 192.168.2.90"    
    environment:
      - REDIS_HOST=192.168.2.90
    ports:
    - "6379:6379"
    restart: unless-stopped
    networks:
      blue-green-network:
        ipv4_address: 172.18.3.1

  redis-a-2:
    container_name: redis-a-2
    hostname: redis-a-2
    image: redis
    command: "redis-server --port 6380 --bind-source-addr 192.168.2.90 --slaveof 192.168.2.90 6379"        
    environment:
      - REDIS_HOST=192.168.2.90
    ports:
    - "6380:6380"
    restart: unless-stopped
    networks:
      blue-green-network:
        ipv4_address: 172.18.3.2

  redis-a-3:
    container_name: redis-a-3
    hostname: redis-a-3
    image: redis
    command: "redis-server --port 6381 --bind-source-addr 192.168.2.90 --slaveof 192.168.2.90 6379"        
    environment:
      - REDIS_HOST=192.168.2.90
    ports:
    - "6381:6381"
    restart: unless-stopped
    networks:
      blue-green-network:
        ipv4_address: 172.18.3.3  

我尝试了很多方法让每个 Redis 服务器将它们的 IP 地址作为 Docker 主机的 IP 地址相互报告,但没有成功。

关于我如何做到这一点的任何想法,或者我是在做傻事吗?

非常感谢。

注意:我知道机器本身是单点故障

docker networking docker-compose redis redis-sentinel
1个回答
0
投票

您通过公开 Redis 服务器的端口所做的是创建从主机 IP 地址到内部 Docker IP 地址的映射。但是,这 not 改变了 Redis 服务器看到并用来相互通信的 IP 地址。他们仍然认为自己的 IP 地址位于 172.16.0.0/12 子网中。

Docker 默认情况下将容器与宿主机和其他容器隔离,并为每个容器提供自己的网络堆栈。容器从内部 Docker 子网(在您的示例中为 172.16.0.0/12)分配 IP 地址,这些地址通常无法从 Docker 主机外部访问。

你正在使用 Redis Sentinel(它应该有助于管理 Redis 服务器拓扑,提供监控、通知、自动故障转移和配置等服务),当它查询 Redis 服务器时,它们会报告它们的内部 Docker IP 地址:这就是你看到了。

阅读“IP地址和DNS名称”,您可以使用“

announce-ip
”:这将告诉Redis向客户端和其他Redis服务器宣布不同的IP地址。

--announce-ip
选项可用于告诉 Redis 服务器向客户端和其他 Redis 服务器通告不同的 IP 地址,当 Redis 在 Docker 容器内运行并需要与外部实体通信时,这会有所帮助。

您的问题出在 Redis Sentinel 上,由于 Docker 的端口重新映射,它无法发现 Redis 服务器和其他 Sentinel 实例。根据 Redis 文档,您应该在 Sentinel 配置中使用

sentinel announce-ip <ip>
sentinel announce-port <port>
指令来解决此问题 1 。

redis-sentinel-1:
  container_name: redis-sentinel-1
  hostname: redis-sentinel-1
  image: redis
  command: "redis-server /etc/redis/sentinel.conf --sentinel --announce-ip 192.168.2.90 --announce-port 26379"
  environment:
    - REDIS_HOST=192.168.2.90
  ports:
  - "26379:26379"
  restart: unless-stopped
  networks:
    blue-green-network:
      ipv4_address: 172.18.3.4

这将使用 Redis 映像设置 Redis Sentinel,并使用

--announce-ip
--announce-port
选项运行 Sentinel 服务。
将 26379 替换为适合您的 Sentinel 实例的端口号。另外,请注意,您的 Docker 容器中需要有一个哨兵配置文件(在本例中为
/etc/redis/sentinel.conf
)才能正常工作。

redis-a-2
redis-a-3
重复此操作,希望这可以解决您的问题。


“主机网络模式下的 Docker”将是一个更简单的解决方案,但前提是它与您的设置和安全要求兼容。

在主机网络模式下,Docker 容器与 Docker 主机本身共享网络堆栈,这意味着它不执行任何网络地址转换 (NAT) 或端口映射。这可以缓解您在使用 Redis Sentinel 的自动发现和故障转移机制时遇到的问题。

但显然,这不太安全(容器在主机模式下的网络隔离较少,因为它们共享主机的网络命名空间并可以访问其所有网络接口),并且可能包括与主机上应用程序的端口冲突。

© www.soinside.com 2019 - 2024. All rights reserved.