Как настроить Redis Cluster внутри кластера Kubernetes, чтобы он был доступен для внешних приложений

У меня проблемы с открытием моего Redis Cluster в Kubernetes внешним приложениям. Используя службу балансировки нагрузки Kubernetes, я могу назначить Redis внешний IP-адрес, который обеспечивает начальное подключение. Проблема в том, что всякий раз, когда клиент получает команду MOVED , IP-адрес является внутренним IP-адресом POD Kubernetes, который недоступен для клиентов redis за пределами кластера.

Вот пример сеанса из redis-cli для демонстрации:

10.150.0.5:7000> set test value
-> Redirected to slot [6918] located at 10.28.1.9:6379
Could not connect to Redis at 10.28.1.9:6379: Operation timed out

Как решить эту проблему? Ни одно из учебных пособий / руководств, которые я прочитал, не проливает света на доступ к кластеру внешним службам. Большинство из них озабочено настройкой кластера Redis в K8s.

1
задан 26 September 2019 в 13:31
3 ответа

Для тех, кто все еще ищет ответ, лучшим вариантом, который я нашел, является использование (теперь официальное) прокси-сервера Redis https://github.com/RedisLabs/redis- кластер-прокси.

Примечание. Как упоминает Йогеш в своем комментарии, это альфа-код, поэтому, пожалуйста, не делайте этого в производственных рабочих нагрузках, пока код не станет стабильным / вы не знаете, что делаете.

  1. Настройте кластер Redis в K8
  2. Разверните redis-cluster-proxy и настройте его для подключения к вашему кластеру Redis
  3. Создайте внешнюю службу K8, чтобы она указывала на экземпляр redis-cluster-proxy, а НЕ на фактический экземпляр кластера Redis
  4. Ваши приложения должны использовать эту службу для подключения к Redis

Объяснение Прокси-сервер в основном «притворяется» одним экземпляром Redis, поэтому клиентам, подключающимся к нему, не нужно знать о кластере.

Вы должны использовать последнюю версию Redis, желательно v6 или выше.

3
ответ дан 4 September 2020 в 07:28

ОБНОВЛЕНИЕ:

Думаю, я не совсем понимаю вопрос. И после комментария ОП. Я собираюсь изучить настройку кластера Redis и аналогичные проблемы.

Вот что я обнаружил

Из этой проблемы Github Когда Redis выполняет такое поведение «Перенаправлен в слот xxx», он не проксирует соединение через сервер Redis, а просто передает IP-адрес соответствующего сервера обратно клиенту, который затем инициирует подключение напрямую.

Из этого Проблема с Github В случае, когда один из контейнеров докеров умирает, и появляется новый контейнер, мы повторно подключаем node.conf из тома к нему, чтобы он мог присоединиться к текущему запущенному Redis кластер снова автоматически. Однако когда контейнер возвращается, он получает другой IP-адрес. И когда мы запускаем новый сервер Redis внутри этого контейнера, он не обновляет IP-адрес внутри файла nodes.conf для единственного нового сгенерированного контейнера. Но все остальные узлы знают о новом IP-адресе внутри своего файла nodes.conf. В целом, вышедший из строя узел не обновляет свой IP-адрес внутри nodes.conf

Итак, вывод состоит в том, что нам необходимо обновить IP-адрес модуля в файле nodes.conf после перезапуска. , поэтому он может присоединиться к кластеру. Пример можно найти здесь , добавив скрипт для добавления podIP в node.conf после перезапуска.

СТАРЫЙ ОТВЕТ:

Если вы используете LoadBalancer , рассмотрите возможность использования статического IP-адреса, чтобы он не был назначен новому IP-адресу.

Вот пример

apiVersion: v1
kind: Service
metadata:
  name: redis
  labels:
    app: redis
spec:
  selector:
    app: redis
  ports:
  - port: 6379
    targetPort: 6379
  type: LoadBalancer
  loadBalancerIP: "YOUR.IP.ADDRESS.HERE"

Замените ВАШ.IP.АДРЕС.ЗДЕСЬ зарезервированным внутренним IP ( и помните, что это региональный IP-адрес).

Как зарезервировать внутренний IP-адрес в GCP

0
ответ дан 4 December 2019 в 02:42

Я исследовал эту проблему на стороне Google Cloud Platform, поскольку это моя область знаний, и обнаружил следующую документацию [1]. Другая документация по Redis [2] подтвердила ваши предположения о том, как Redis обрабатывает IP-адреса. Похоже, что узлы Redis будут использовать свой собственный IP-адрес при отправке клиенту, поэтому, когда клиент отвечает (через балансировщик нагрузки), используется неправильный IP-адрес. Такое поведение могло быть преднамеренным дизайнерами Redis. Мне не удалось найти обходной путь, и я должен признать, что это выходит за рамки моих возможностей. Пища для размышлений: хотя GKE можно использовать с базой данных, это не лучшая практика. Если вы действительно хотите использовать базу данных в k8s, вам следует использовать StatefulSet, который будет пытаться поддерживать тот же IP-адрес пода. Google предлагает альтернативные методы интеграции в облако. Доступно несколько продуктов, возможно, время, потраченное на изучение ваших потребностей и возможностей продуктов Google, будет полезным. Одним из них, в частности, будет Cloud Memorystore, поскольку он предназначен для использования с Redis. В документации к этому продукту говорится: «Cloud Memorystore для Redis полностью совместим с протоколом Redis». [3]

[1] Подключение к экземпляру Redis: https://cloud.google.com/memorystore/docs/redis/connect-redis-instance-gke [2] Роли клиента и сервера: https://redis.io/topics/cluster-spec [3] Обзор Cloud Memorystore для Redis: https://cloud.google.com/memorystore/docs/redis/redis-overview

0
ответ дан 4 December 2019 в 02:42

Теги

Похожие вопросы