Вопрос или проблема
Я настроил кластер 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-адрес кластера работает без проблем.
Возможные причины проблемы
-
Неправильная конфигурация селектора сервиса: Убедитесь, что селектор вашего сервиса Redis правильно указывает на ваши поды Redis. Проверьте, что поды имеют метки, соответствующие селектору
app: redis
. Вы можете это сделать с помощью команды:kubectl get pods -n myapp --show-labels
Убедитесь, что метка
app: redis
присутствует на всех подах Redis. -
Ошибка в назначении пространства имён: Если ваше приложение и сервис Redis находятся в разных пространствах имён, он не будет доступен по имени, как ожидается. Проверьте, что ваше Django-приложение развернуто в пространстве имён
myapp
, и Redis также расположен в том же пространстве имен. -
Проблемы с инициализацией Redis: Если Redis под ещё не запущен или испытывает проблемы, он не сможет принимать подключения. Убедитесь, что под Redis работает корректно:
kubectl get pods -n myapp
Если под Redis не работает, посмотрите журналы, чтобы понять источник проблемы:
kubectl logs <имя-пода-redis> -n myapp
-
Политики NetworkPolicy: Если в вашем кластере настроены политики сетевой безопасности, убедитесь, что они позволяют трафик между подами вашего Django-приложения и сервисом Redis.
-
Синтаксис 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
-
Тайм-ауты: Если Redis под запускается медленно, возможно, ваш Django-приложение пытается подключиться к Redis до его полной инициализации. Это можно исправить, добавив тайм-аут или сделав повторные попытки в коде Django.
Рекомендации для решения проблемы
- Убедитесь, что все метки и селекторы правильно настроены.
- Проверьте, что оба пода находятся в одном пространстве имён и работают, используя команды для проверки подов и их журналов.
- Если использование имени сервиса продолжает вызывать ошибки, вы можете настроить
restartPolicy
для вашего пода или использовать инициализационные контейнеры, чтобы убедиться, что Redis доступен перед запуском основного приложения Django. - Проверьте, нет ли проблем с сетевыми политиками, если они применяются в вашем кластере.
Вывод
Использование имени сервиса в Kubernetes должно работать корректно при правильной настройке. Основные шаги, которые вы должны предпринять, — это проверка конфигурации и статуса подов, проверка наличия сетевых политик и правильности синтаксиса переменных окружения. Если всё сделано правильно, ваше приложение должно без проблем подключаться к сервису Redis по имени.