Подключение к службе Redis на Kubernetes с именем службы

Вопрос или проблема

Я настроил кластер k3s на Raspberry Pi и пытаюсь развернуть на нем приложение Django. Приложение требует Celery и Redis и работает за прокси nginx. В своей конфигурации nginx я указываю прокси uwsgi, используя имя сервиса django:

location / {
        include uwsgi_params;
        uwsgi_pass django-svc:3031;          
    }

Это работает нормально с моим сервисом django:

apiVersion: v1
kind: Service
metadata:
  name: django-svc
  namespace: myapp
  labels:
    app: myapp
spec:
  type: ClusterIP
  selector:
    app: myapp
    type: django
  ports:
    - port: 3031
      targetPort: 3031

Я настроил свой сервис redis:

apiVersion: v1
kind: Service
metadata:
  name: redis-svc
  namespace: myapp
spec:
  type: ClusterIP
  selector:
    app: redis
  ports:
    - protocol: TCP
      port: 6379
      targetPort: 6379

Затем в своей конфигурационной карте я указываю две переменные окружения для redis:

  CACHE_REDIS_URL: "redis://redis-svc:6379/1"
  CELERY_BROKER_URL: "redis://redis-svc:6379/0"

Но когда я пытаюсь запустить приложение, я получаю redis.exceptions.ConnectionError: Error 111 connecting to redis-svc:6379. Connection refused. ошибка в django. Если я заменяю redis-svc на его IP-адрес кластера, оно работает, но не с его именем сервиса. Почему так происходит?

Ответ или решение

Подключение к сервису Redis в Kubernetes по имени сервиса

В вашем случае с деплоем Django-приложения и использования Celery и Redis на кластере k3s на Raspberry Pi, проблема подключения к Redis через его имя сервиса кажется довольно распространённой. Давайте разберёмся в причинах, почему вы получаете ошибку подключения, и предложим шаги для её решения.

Описание проблемы

Вы указали, что используете правильные сервисы в своём приложении и ваши настройки выглядят корректно. Тем не менее, ошибка redis.exceptions.ConnectionError: Error 111 connecting to redis-svc:6379. Connection refused. указывает на то, что ваше приложение не может подключиться к Redis по имени сервиса. При этом подключение через IP-адрес кластера работает без проблем.

Возможные причины проблемы

  1. Неправильная конфигурация селектора сервиса: Убедитесь, что селектор вашего сервиса Redis правильно указывает на ваши поды Redis. Проверьте, что поды имеют метки, соответствующие селектору app: redis. Вы можете это сделать с помощью команды:

    kubectl get pods -n myapp --show-labels

    Убедитесь, что метка app: redis присутствует на всех подах Redis.

  2. Ошибка в назначении пространства имён: Если ваше приложение и сервис Redis находятся в разных пространствах имён, он не будет доступен по имени, как ожидается. Проверьте, что ваше Django-приложение развернуто в пространстве имён myapp, и Redis также расположен в том же пространстве имен.

  3. Проблемы с инициализацией Redis: Если Redis под ещё не запущен или испытывает проблемы, он не сможет принимать подключения. Убедитесь, что под Redis работает корректно:

    kubectl get pods -n myapp

    Если под Redis не работает, посмотрите журналы, чтобы понять источник проблемы:

    kubectl logs <имя-пода-redis> -n myapp
  4. Политики NetworkPolicy: Если в вашем кластере настроены политики сетевой безопасности, убедитесь, что они позволяют трафик между подами вашего Django-приложения и сервисом Redis.

  5. Синтаксис URL для Redis: Проверьте корректность URL в переменных окружения. Ваши строки:

    CACHE_REDIS_URL: "redis://redis-svc:6379/1"
    CELERY_BROKER_URL: "redis://redis-svc:6379/0"

    выглядят корректно, но убедитесь, что они обновляются в подах. Вы можете проверить переменные окружения внутри работающего пода Django:

    kubectl exec -it <имя-пода-django> -n myapp -- env
  6. Тайм-ауты: Если Redis под запускается медленно, возможно, ваш Django-приложение пытается подключиться к Redis до его полной инициализации. Это можно исправить, добавив тайм-аут или сделав повторные попытки в коде Django.

Рекомендации для решения проблемы

  • Убедитесь, что все метки и селекторы правильно настроены.
  • Проверьте, что оба пода находятся в одном пространстве имён и работают, используя команды для проверки подов и их журналов.
  • Если использование имени сервиса продолжает вызывать ошибки, вы можете настроить restartPolicy для вашего пода или использовать инициализационные контейнеры, чтобы убедиться, что Redis доступен перед запуском основного приложения Django.
  • Проверьте, нет ли проблем с сетевыми политиками, если они применяются в вашем кластере.

Вывод

Использование имени сервиса в Kubernetes должно работать корректно при правильной настройке. Основные шаги, которые вы должны предпринять, — это проверка конфигурации и статуса подов, проверка наличия сетевых политик и правильности синтаксиса переменных окружения. Если всё сделано правильно, ваше приложение должно без проблем подключаться к сервису Redis по имени.

Оцените материал
Добавить комментарий

Капча загружается...