Проблема при подключении к главному узлу Redis, работающему в режиме часового режима в соединителях докеров - PullRequest
0 голосов
/ 30 января 2019

Я использую Redis в Docker-контейнерах и использую режим Redis Sentinel.Я настроил следующую конфигурацию -

3 redis sentinels nodes
1 redis master node
2 redis slave nodes

Я запускаю все это на моей локальной машине.Таким образом, всего 6 док-контейнеров, работающих через docker-compose в режиме моста сети.Все соединения имеют внешние порты.

Все контейнеры могут обращаться друг к другу, поскольку они находятся в одной и той же мостовой сети, созданной во время работы docker-compose up.

. Я создал клиент Java, используяБиблиотека Redisson для доступа к 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 Master, так как IP-адрес, возвращаемый сторожевым узлом, является внутренним IP-адресом Docker-сети для главного узла, который недоступен за пределами 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)

Как исправить эту проблему?Нужно ли запускать его в другом сетевом режиме?или каким-то образом перевести этот внутренний IP-адрес докера в фактический IP-адрес компьютера, на котором запущены докер-конатинеры?

1 Ответ

0 голосов
/ 15 апреля 2019

Сегодня я столкнулся с этой проблемой, пытаясь настроить ее для тестового экземпляра.Мой исходный файл композиции был основан на https://blog.alexseifert.com/2016/11/14/using-redis-sentinel-with-docker-compose/ с модификациями, чтобы удовлетворить мои потребности.Мне удалось найти обходной путь, 1) привязав порты к моей хост-машине, 2) установив флаг depen_on в docker-compose, и 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, и я не думаю, что либо работал, поэтому у меня было установлено имя хоста на машине, на которой я запускал это.Я как бы пробовал все и вся в тот момент.

У каждого стража (у меня их было три) была отдельная запись, ссылающаяся на их контексты сборки и сопоставляющая порт в sentinel.conf с локальным портом.Так что в docker-compose мои стражи выглядели так:

 # Instance 1
  redis-sentinel:
    build:
      context: <path-to-context>
    links:
      - redis-master
    ports:
      - "26379:26379"
    depends_on:
      - redis-replica

То, что я делал, было определенно хаком, и я бы не стал делать это на производстве.Я почти уверен, что есть гораздо лучшее сетевое решение для докера, я просто не хотел заходить слишком далеко в кроличью нору, чтобы проверить, что мне нужно.Надеюсь, это поможет.

...