Имеется Redis, для которого создан Service типа ClusterIP.
К этому Редису должны ходить поды этого неймспейса (Gorush).
Проблема в том, что поды с Gorush подключиться к Redis по адресу gorush-server-redis-svc:6379 не могут — отваливаются с ошибкой «Can’t connect redis server: connection refused«:
Проверяем наличие сервиса:
Содержание
Ошибка «no endpoints available for service»
Попробуем подключиться к сервису напрямую, с рабочей машины, как описывалось в посте Kubernetes: ClusterIP vs NodePort vs LoadBalancer, Services и Ingress — обзор, примеры.
Запускаем прокси:
И пробуем curl
:
Хотя под с Redis запущен, работает, и подключения принимает — проверяем с помощью port-forwadrd
, запускаем его:
И проверяем:
Всё хорошо, но почему не работает через Service?
И почему ругается на отсутствующий ендпоинт?
Проверяем ендпоинты:
В самом деле — <none>
.
Причина #1: labels mismatch
Проверяем какие лейлбы использует Сервис для выбора подов — находим его selector
Или вот как он выглядит в манифесте:
apiVersion: v1 kind: Service metadata: name: {{ .Chart.Name }}-redis-svc labels: application: {{ .Chart.Name }}-redis-svc spec: ports: - port: 6379 selector: applicaton: {{ .Chart.Name }}-redis
И проверяем какие лейлбы заданы самому поду:
Деплоймент пода выглядит так:
--- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: {{ .Chart.Name }}-redis spec: replicas: 1 template: metadata: labels: application: {{ .Chart.Name }}-redis spec: containers: - name: redis-master image: redis ports: - containerPort: 6379
А теперь сравниваем:
- селектор Сервиса:
applicatonmap[
:gorush-server-redis]
- и тег у пода:
applicationmap[
:gorush-server-redis]
И видим опечатку — applicaTOn и applicaTIOn.
Соответственно, сам Service создавался, потому что сам манифест синтактически верен, но из-за того, что искал по неправильному тегу — не мог найти поды, которые стали бы бекендом для ендпоинта этого сервиса, и Service некуда было перенаправлять трафик, что и приводило к ошибке 503.
Исправляем селектор, передеплоиваем, проверяем сервис:
Или:
Endpoints: 10.3.47.94:6379
появился — готово, всё завелось.
Причина #2: named port
Аналогичная же ошибка может возникнуть при использовании именованных портов:
apiVersion: v1 kind: Service metadata: name: gorush labels: app: gorush tier: frontend spec: selector: app: gorush tier: frontend type: LoadBalancer ports: - name: gorush protocol: TCP port: 80 targetPort: 8088
ports: — name: gorush
При этом сам endpoint создаётся:
Но при обращении к API-серверу — он возвращает нам всё ту же ошибку «message»: «no endpoints available for service \»gorush\»»:
В данном случае причина в том, что в API-запросе не указано имя порта, которое указывается через «:
» :
services/gorush:gorush — теперь всё работает.