Назад | Перейти на главную страницу

Как настроить 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.

Я исследовал эту проблему на стороне 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

ОБНОВИТЬ:

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

Вот что я нашел

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

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

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

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

Если вы используете LoadBalancer service, рассмотрите возможность использования статического 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"

Заменить YOUR.IP.ADDRESS.HERE с зарезервированным внутренним IP-адресом (помните, что это региональный IP-адрес).

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