Служба Kubernetes отвечает на порт, отличный от назначенного

Dec 16 2020

Я развернул несколько служб и обнаружил, что одна служба ведет себя иначе, чем другие. Я настроил его для прослушивания порта 8090 (который внутренне соответствует 8443), но запрос работает, только если я отправляю его на порт 8080. Вот мой yaml-файл для службы (сокращенный до самого необходимого), и есть развертывание, инкапсулирующее службу и контейнер

apiVersion: v1
kind: Service
metadata:
  name: uisvc
  namespace: default
  labels:
    helm.sh/chart: foo-1
    app.kubernetes.io/name: foo
    app.kubernetes.io/instance: rb-foo
spec:
  clusterIP: None
  ports:
    - name: http
      port: 8090
      targetPort: 8080
  selector:
    app.kubernetes.io/component: uisvc

После установки руля, когда я запускаю kubectl get svc, я получаю следующий вывод

fooaccess       ClusterIP   None         <none>        8888/TCP   119m
fooset          ClusterIP   None         <none>        8080/TCP   119m
foobus          ClusterIP   None         <none>        6379/TCP   119m
uisvc           ClusterIP   None         <none>        8090/TCP   119m

Однако, когда я использую ssh в один из других работающих контейнеров и отправляю запрос curl на 8090, я получаю сообщение «В соединении отказано». Если я перейду на «http: // uisvc: 8080», то получаю правильный ответ. Контейнер запускает приложение загрузки Spring, которое по умолчанию прослушивает 8080. Единственное объяснение, которое я мог придумать, - это каким-то образом порт / targetPort игнорируется в этой конфигурации, а другие модули напрямую достигают службы Spring внутри.

Это правильное поведение? Почему не слушает 8090? Как мне заставить его работать так?

Изменить: вывод для kubectl describe svc uisvc

Name:              uisvc
Namespace:         default
Labels:            app.kubernetes.io/instance=foo-rba
                   app.kubernetes.io/managed-by=Helm
                   app.kubernetes.io/name=rba
                   helm.sh/chart=rba-1
Annotations:       meta.helm.sh/release-name: foo
                   meta.helm.sh/release-namespace: default
Selector:          app.kubernetes.io/component=uisvc
Type:              ClusterIP
IP:                None
Port:              http  8090/TCP
TargetPort:        8080/TCP
Endpoints:         172.17.0.8:8080
Session Affinity:  None
Events:            <none>

Ответы

1 thomas Dec 16 2020 at 20:39

Это ожидаемое поведение, поскольку вы использовали headless service.

Headless услуга используется для обнаружения службы механизма таким образом , вместо того , чтобы вернуться одного DNS A records, то DNS serverбудет возвращать несколько A recordsдля вашей службы каждый из которых указует на IP в индивидуальных стручках , что подпирает службу. Таким образом, вы выполняете простой DNS A recordsпоиск и получаете IP-адреса всех модулей, которые являются частью службы.

Поскольку правила headless serviceне создаются, iptablesа создается dns recordsвместо этого, вы можете напрямую взаимодействовать со своим модулем, а не через прокси. Итак, если вы решите, <servicename:port>вы получите, <podN_IP:port>а затем ваше соединение перейдет к модулю напрямую. Пока все это находится в одном пространстве имен, вы не можете разрешить его по полному имени DNS.

При наличии нескольких модулей DNS выдаст вам их все и просто разместит в случайном порядке (или в порядке RR). Порядок зависит от реализации и настроек DNS-сервера.

Для получения дополнительной информации посетите:

  • Услуги-netowrking / headless-services
  • Этот стек вопросов с отличным ответом, объясняющим, как работают безголовые службы