Невозможно подключиться к Redis Cluster изнутри контейнера Docker

У меня есть приложение Node, использующее эту клиентскую библиотеку javascript ioredis. Моя проблема в том, что я не могу подключить это приложение, которое также является докеризированным, к моему кластеру Redis (на портах с 7000 по 7005) и его контейнеру. Вот моя установка и результаты:

Я клонирую это репозиторий Docker-redis-cluster и следую инструкциям по созданию образа из Dockerfile.

$ docker build -t gsccheng/redis-cluster .

Однако перед сборкой моим единственным изменением было установить свою собственную версию, которую я изменил на

ARG redis_version=3.2.1

Следуя инструкциям, я бегу

docker run -i -t -p 7000:7000 -p 7001:7001 -p 7002:7002 -p 7003:7003 -p 7004:7004 -p 7005:7005 -p 7006:7006 -p 7007:7007 gsccheng/redis-cluster

ОТЛИЧНО ...

За исключением нескольких предупреждений типа: WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128., пока все в порядке. Почему?:

  1. Вот снимок экрана с выходными данными.
  2. Я могу войти в интерфейс командной строки, используя redis-cli -c -p 7000
  3. С docker inspect [container id] я вижу, что у него есть NetworkSettings> IPAddress 172.17.0.2, а в NetworkSettings> Ports я вижу

    "Ports": {
                "6379/tcp": null,
                "7000/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "7000"
                    }
                ],
                ...
             }
    

Далее останавливаю и удаляю все контейнеры. Я перехожу в корень своего веб-приложения, где у меня есть Dockerfile и docker-compose.yml, которые находятся здесь:

docker-compose.yml

version: '2.1'
services:
  web:
    build: .
    ports:
      - '8080:8080'
    depends_on:
        - redis
  redis:
    image: gsccheng/redis-cluster
    ports:
      - '7000:7000'
      - '7001:7001'
      - '7002:7002'
      - '7003:7003'
      - '7004:7004'
      - '7005:7005'

Dockerfile

FROM node:4.4.7

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install

# Bundle app source
COPY . /usr/src/app

EXPOSE 8080
CMD [ "npm", "run", "prod" ]

connect.js

import Redis from 'ioredis';
console.log('I am totally in here');

// The commented out host options shows the many different configurations I tried too.
const node = [{
            // Just need to connect to at least one of the startup nodes in the cluster. Redis will find the rest of the nodes in the cluster. All nodes only have a single db of 0 and SELECT is disabled.
            port: 7000,
            // host: '0.0.0.0'
            // host: '127.0.0.1'
            // host: '172.18.0.4'
            host: 'redis'
            // host: 'gsccheng/redis-cluster'
        }, {
            port: 7001,
            // host: '0.0.0.0'
            // host: '127.0.0.1'
            // host: '172.18.0.4'
            host: 'redis'
            // host: 'gsccheng/redis-cluster'
        }]

client = new Redis.Cluster(node, {});
...

Я тогда бегу

$ docker-compose build

а также

$ docker-compose up

Вывод находится в этой сути. Я удалил оттуда несколько нерелевантных строк (обозначенных "...") для этого примера.

Если это имеет значение, мое приложение было создано на основе этого шаблона React-redux, но он не включал Redis.

Проверка работоспособности

  1. Когда docker-compose up запущен и ошибки постоянно регистрируются, как вы видите в сути, я все еще могу подключиться к кластеру извне контейнера, когда я выполняю:

    $ redis-cli -c -p 7000
    
  2. $ docker ps показывает этот снимок экрана.

  3. $ docker exec 4b3ec3e53e32 ps aux | grep redis показывает этот снимок экрана.

  4. Вот полный вывод из $ docker inspect 4b3ec3e53e32 снова контейнера redis. Обратите внимание на "IPAddress": "" под _22 _...

Дополнительные вопросы

  1. ... Почему это пусто? Поэтому мой клиент Redis не может подключиться к кластеру?
  2. В чем разница между этим ip и "HostIp": "0.0.0.0",? 0.0.0.0 был привязан к redis.conf конфигурациям, и я думаю, это означает, что сервер будет слушать только запросы с этого адреса. Означает ли это, что указанный там IP-адрес должен совпадать с IP-адресом другого моего ctn_web_1 контейнера?
  3. Мы также видели из вывода docker-compose up, что серверы Redis работают на 172.18.0.2. Я заметил, что это также сильно менялось от экземпляра к экземпляру (например, 172.18.0.4, 172.18.0.3) моего запуска docker-compose. Почему? Это потому, что я еще не полностью удалил контейнеры перед повторным запуском? Однако мне не следует использовать этот IP-адрес в моем connect.js коде правильно, потому что этот адрес является внутренним для контейнера redis (тогда как интерфейс, который будет интересовать мой веб-контейнер, является адресом контейнера redis)?

Обновление:

A. $ docker-compose ps вывод находится здесь. Б. Также обратите внимание на эту проблему. В частности, что

кластер redis еще не поддерживает докеры (если вы не используете сеть хоста) -> объявленный IP-адрес будет отличаться от того, через который они могут разговаривать


person writofmandamus    schedule 05.03.2017    source источник
comment
Этот вопрос теперь трансформировался за рамки того, что я лично считаю хорошим вопросом SO (см. справку для получения дополнительных сведений о том, как задать вопросы, но самое главное, это должен быть вопрос, а не список меняющихся вопросов).   -  person BMitch    schedule 05.03.2017
comment
Спасибо за ваш вклад. Мне еще не удалось прочитать справку, но я изменил свои обновления, которые были в форме вопроса на утверждение. Основная идея заключалась не столько в том, чтобы задать вопрос, сколько в том, чтобы предоставить читателю более подробную информацию, чтобы помочь в устранении неполадок. Эти две дополнительные части информации были бы полезны, не так ли?   -  person writofmandamus    schedule 05.03.2017


Ответы (1)


Вы должны удалить линию

host: '0.0.0.0'

из вашего connect.js. Вам необходимо подключиться к другим контейнерам по их DNS-имени (redis), которое будет работать, пока вы запускаете их в той же сети докеров. Это поведение по умолчанию для docker-compose с файлом yml версии 2.

Контейнеры могут начинаться с разных IP-адресов. Я бы рекомендовал не пытаться жестко закодировать IP-адрес контейнера в любых файлах конфигурации, поскольку по замыслу целевой контейнер может приходить и уходить.


Судя по проблеме, на которую вы ссылались, похоже, что то, что вы пытаетесь сделать, не поддерживается авторами основной ветки разработки. Я не уверен, как это согласуется с вашими первоначальными выводами о том, что redis-cli работал. Мой ответ был основан на предположении о рабочей среде Redis. Чтобы ответить на еще одно недоразумение:

  • 0.0.0.0 - это IP-адрес для прослушивания, который указывает, что все интерфейсы должны прослушиваться. Вы не подключаетесь к 0.0.0.0 от клиента, только слушаете этот адрес как сервер.

  • Пустой IP-адрес, который вы видели, является результатом реорганизации некоторого вывода json, все IP-адреса теперь перечислены только с их конкретной сетью, и на верхнем уровне больше нет IP-адресов по умолчанию.

person BMitch    schedule 05.03.2017
comment
К сожалению, я не прокомментировал конфигурацию должным образом и случайно оставил там две host строки, но вы поняли. К сожалению, при использовании host: redis у меня все еще появляются те же ошибки. То есть под DNS-именем вы имеете в виду то же имя, которое я упоминаю в depends_on в Dockerfile, верно? - person writofmandamus; 05.03.2017
comment
DNS будет именем службы, в вашем случае redis, что также является значением, на которое указывает depends_on. Обнаружение на основе DNS будет работать от контейнера к контейнеру, которые находятся в одной сети внутри докера. - person BMitch; 05.03.2017
comment
Ваши комментарии заставили меня задуматься о том, как я могу проверить из контейнера, может ли он найти другой контейнер в той же сети. Это заставило меня обновить свой вопрос внизу, добавив в него пункты 8 и 9. До моего обновления казалось, что запуск с host: 'redis' заставил бы все работать в режиме docker-compose right (что все остальное выглядит нормально)? Вызывают ли мои последние два обновления какие-либо новые идеи относительно возможного решения? - person writofmandamus; 05.03.2017
comment
В вашем текущем обновлении строка, которую я рекомендовал удалить, является единственной строкой без комментариев. Похоже, вы не пробовали сделать это предложение. - person BMitch; 05.03.2017
comment
Во время моего тестового прогона я удалил строку host: '0.0.0.0' и оставил строку host: 'redis' активной, как я упоминал в комментариях выше (с кажущимися теми же результатами на первый взгляд). Я не хотел обновлять свой исходный вопрос по этому поводу, потому что все мои журналы на самом деле были для случая host: '0.0.0.0', и на всякий случай я не хотел аннулировать мои журналы, которые могут затем потенциально сбить читателей. Однако теперь кажется, что отказ от обновления имеет больше негативных последствий, поэтому я обновлю его в соответствии с вашим предложением. Извините за путаницу. - person writofmandamus; 05.03.2017
comment
Спасибо за помощь. Я пометил ваш ответ как решение, потому что это комбинация всего этого, и я не перестраивал образы докеров и не использовал обновленные контейнеры для изменений в моем connect.js файле. - person writofmandamus; 06.03.2017