Я повторил вашу проблему и нашел решение вашей проблемы.
Позвольте мне начать с объяснения причины вашей проблемы.
Протокол сплетен Redis работает следующим образом: когда вывведите cluster meet <ip> <port>
on redis1 , redis1 открывает TCP-соединение с redis2 . В обычном случае, когда redis2 получает соединение, оно принимает его, ищет IP-адрес источника подключающегося и также открывает tcp-соединение с этим адресом, поэтому в этом случае redis1 ,(Подробнее о том, как работает протокол сплетен inredis, можно найти в документации redis или в этой статье )
Здесь приводится часть istio . Istio по умолчанию настраивает посланника в качестве типичного прокси и, как вы можете прочитать в документации istio :
![interception mode](https://i.stack.imgur.com/AwfJB.png)
Istio по умолчанию используетREDIRECT
Прокси и как указано в документации:
Этот режим теряет IP-адреса источника при перенаправлении
Это наш источник проблемы.
redis2 когда получает соединение, оно видит, что оно исходит от localhost. Посланник потерял исходный IP-адрес redis1 и redis2 теперь не может открыть подключение обратно к redis1 .
Теперь у нас есть некоторыепараметры:
- вы можете попробовать изменить режим проксирования на
TPROXY
(я пробовал, но не смог заставить его работать) - использовать встроенную переменную конфигурации redis
Давайте посмотрим на второй вариант немного ближе, потому что это тот, который работал для меня. В файле redis.conf
вы можете найти этот раздел:
Поддержка CLUSTER DOCKER / NAT
В некоторых развертываниях обнаружение адресов узлов Redis Cluster не выполняется, поскольку адресаNAT-ted или потому что порты переадресованы (типичный случай - Docker и другие контейнеры).
Для того, чтобы заставить Redis Cluster работать в таких средах, необходима статическая конфигурация, где каждый узел знает свой публичный адрес. Для этой области используются следующие два параметра:
- cluster-announce-ip
- cluster-announce-port
- cluster-announce-bus-порт
Каждый сообщает узлу свой адрес, порт клиента и порт шины сообщений кластера. Затем информация публикуется в заголовке пакетов шины, чтобы другие узлы могли правильно отобразить адрес узла, публикующего информацию.
Если указанные выше параметры не используются, обычный автоматический Redis Cluster auto-detection будет использоваться вместо этого.
Обратите внимание, что при переназначении шинный порт может не иметь фиксированного смещения клиентского порта + 10000, поэтому вы можете указать любой порт и шинный порт в зависимости от того, как они переназначаются,Если шинный порт не задан, то обычно используется фиксированное смещение 10000.
Пример:
cluster-announce-ip 10.1.1.5
cluster-announce-port6379
порт кластера-анонса-шины 6380
Нам нужно установить переменную cluster-announce-ip
на собственный IP-адрес модуля pis.
Вы можете сделать это, например, изменив redis-cluster
ConfigMap следующим образом (это модифицированный redis configmap из этой статьи ):
---
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-cluster
data:
update-node.sh: |
#!/bin/sh
REDIS_NODES="/data/nodes.conf"
sed -i -e "/myself/ s/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/${POD_IP}/" ${REDIS_NODES}
cp /conf/redis.conf /redis.conf # <------HERE-----
sed -i "s/MY_IP/${POD_IP}/" /redis.conf # <------HERE-----
exec "$@"
redis.conf: |+
cluster-enabled yes
cluster-require-full-coverage no
cluster-node-timeout 15000
cluster-config-file /data/nodes.conf
cluster-migration-barrier 1
appendonly yes
protected-mode no
cluster-announce-ip MY_IP # <------HERE-----
Также не забудьте изменить command
вашего контейнера следующим образомчтобы указать redis.conf
файл справа:
command: ["/conf/update-node.sh", "redis-server", "/redis.conf"]
Каждый узел redis теперь будет объявлять этот адрес как свой собственный, поэтому другие узлы redis теперь будут знать, как с ним связаться.
Дайте мне знать, если это помогло.