Kubernetes: как получить доступ к сервису, если nodePort является случайным? - PullRequest
0 голосов
/ 01 февраля 2020

Я новичок в K8s и в настоящее время использую Minikube для игры с платформой. Как настроить порт publi c (т.е. вне кластера) для службы? Я следовал nginx примеру и учебным пособиям по обслуживанию K8s. В моем случае я создал службу следующим образом:

kubectl expose deployment/mysrv --type=NodePort --port=1234

Порт службы 1234 для любого, кто пытается получить к нему доступ изнутри кластера. В учебниках по мини-кубам говорится, что мне нужен прямой доступ к сервису через случайный порт узла, который работает для целей ручного тестирования:

kubectl describe service mysrv | grep NodePort
...
NodePort:                 <unset>  32387/TCP
# curl "http://`minikube ip`:32387/"

Но я не понимаю, как в реальном кластере сервис мог иметь фиксированный всемирно доступный порт. Примеры nginx описывают что-то об использовании вида сервиса LoadBalancer, но они даже не указывают порты там ...

Есть идеи, как исправить внешний порт для всей службы?

Ответы [ 2 ]

0 голосов
/ 07 февраля 2020

В учебниках по мини-кубам сказано, что мне нужен прямой доступ к сервису через случайный порт узла, который работает для целей ручного тестирования:

Когда вы создаете объект сервиса типа NodePort с $ kubectl expose команда, вы не можете выбрать свой NodePort порт. Чтобы выбрать порт NodePort, вам нужно создать его определение YAML.

Вы можете вручную указать порт в сервисном объекте типа Nodeport с приведенным ниже примером:

apiVersion: v1
kind: Service
metadata:
  name: example-nodeport
spec:
  type: NodePort
  selector:
    app: hello # selector for deployment
  ports:
  - name: example-port
    protocol: TCP
    port: 1234 # CLUSTERIP PORT
    targetPort: 50001 # POD PORT WHICH APPLICATION IS RUNNING ON 
    nodePort: 32222 # HERE!

Вы можете применить вышеприведенное определение YAML, вызвав команду : $ kubectl apply -f FILE_NAME.yaml

Вышеуказанный сервисный объект будет создан, только если доступен порт nodePort.

Но я не понимаю, как в реальном кластере служба могла бы не иметь фиксированный общедоступный порт.

In В кластерах, управляемых облачными провайдерами (например, GKE), вы можете использовать сервисный объект типа LoadBalancer, который будет иметь фиксированный внешний IP и фиксированный порт.

Кластеры, в которых есть узлы с публичными c IP-адресами, могут использовать объект службы типа NodePort для направления трафика c в кластер.

В среде minikube вы можете использовать служебный объект типа LoadBalancer, но у него будут некоторые предостережения, описанные в последнем абзаце.

Небольшое объяснение:

NodePort

Nodeport представляет службу на каждом узле IP на стати c порт. Это позволяет внешнему трафику c входить через порт NodePort. Этот порт будет автоматически назначен в диапазоне от 30000 до 32767.

Можно изменить диапазон портов по умолчанию NodePort, следуя данному руководству .

Вы можете проверить, что именно происходит при создании объекта службы типа NodePort глядя на этот ответ .

Представьте, что:

  • Ваши узлы имеют IP-адреса:
    • 192.168.0.100
    • 192.168.0.101
    • 192.168.0.102
  • Ваши модули отвечают на порт 50001 с помощью hello и имеют IP-адреса:
    • 10.244.1.10
    • 10.244.1.11
    • 10.244.1.12
  • Ваши услуги:
    • NodePort (порт 32222) с:
      • ClusterIP:
        • IP: 10.96.0.100
        • port: 7654
        • targetPort: 50001

Слово о targetPort. Это определение порта на pod , например, веб-сервере.

В соответствии с приведенным выше примером вы получите hello ответ:

  • NodeIP:NodePort (все модули могут отвечать hello):
    • 192.168.0.100:32222
    • 192.168.0.101:32222
    • 192.168.0.102:32222
  • ClusterIP:port (все капсулы могли ответить hello):
    • 10.0.96.100:7654
  • PodIP:targetPort (только модуль, на который отправляется запрос, может ответить hello)
    • 10.244.1.10:50001
    • 10.244.1.11:50001
    • 10.244.1.12:50001

Вы можете проверить доступ с помощью команды curl, как показано ниже:

$ curl http://NODE_IP:NODEPORT


В приведенном вами примере:

$ kubectl expose deployment/mysrv --type=NodePort --port=1234

Что произойдет:

  • Это назначит случайный порт из диапазона от 30000 до 32767 на вашем minikube экземпляре, направляющем traffi c, входящий в этот порт для модулей.
  • Кроме того, он создаст ClusterIP с портом 1234

В приведенном выше примере не было параметра targetPort. Если targetPort не указано, это будет то же самое, что и port в команде.

Traffi c, введя NodePort, будет перенаправлено непосредственно в стручки и не будет go в ClusterIP.

С точки зрения minikube NodePort будет портом в вашем экземпляре minikube. Это IP-адрес будет зависеть от используемого гипервизора. Экспонирование за пределами вашей локальной машины будет сильно зависеть от операционной системы.


LoadBalancer

Существует разница между сервисным объектом типа LoadBalancer (1) и внешним LoadBalancer (2):

  • Объект службы типа LoadBalancer (1) позволяет предоставлять службу извне, используя поставщика облачных услуг LoadBalancer (2). Это сервис в среде Kubernetes, который через контроллер сервиса может запланировать создание внешнего LoadBalancer (2).
  • Внешний LoadBalancer (2) - это балансировщик нагрузки, предоставляемый облачным провайдером. Он будет работать на уровне 4.

Пример определения службы типа LoadBalancer (1):

apiVersion: v1
kind: Service
metadata:
  name: example-loadbalancer
spec:
  type: LoadBalancer
  selector:
    app: hello
  ports:
    - port: 1234 # LOADBALANCER PORT 
      targetPort: 50001  # POD PORT WHICH APPLICATION IS RUNNING ON 
      nodePort: 32222 # PORT ON THE NODE 

Применение выше YAML создаст службу типа LoadBalancer (1)

Определить c посмотреть на:

  ports:
    - port: 1234 # LOADBALANCER PORT 

Это определение будет одновременно:

  • указать внешний LoadBalancer (2 ) port как 1234
  • укажите ClusterIP port как 1234

Представьте, что:

  • Ваш внешний LoadBalancer (2) иметь:
    • ExternalIP: 34.88.255.5
    • port: 7654
  • Ваши узлы имеют IP-адреса:
    • 192.168.0.100
    • 192.168.0.101
    • 192.168.0.102
  • Ваши модули отвечают на порт 50001 с помощью hello, и у них есть IP-адреса :
    • 10.244.1.10
    • 10.244.1.11
    • 10.244.1.12
  • Ваши услуги:
    • NodePort (порт 32222) с:
      • ClusterIP:
        • IP: 10.96.0.100
        • port: 7654
        • targetPort: 50001
  • ExternalIP: port (все капсулы могут ответить hello ):
    • 34.88.255.5:7654
  • NodeIP:NodePort (все капсулы могли ответить hello):
    • 192.168.0.100:32222
    • 192.168.0.101:32222
    • 192.168.0.102:32222
  • ClusterIP:port (все капсулы могли ответить hello):
    • 10.0.96.100:7654
  • PodIP:targetPort (только модуль, на который отправляется запрос, может ответить hello)
    • 10.244.1.10:50001
    • 10.244.1.11:50001
    • 10.244.1.12:50001

ExternalIP можно проверить с помощью команды: $ kubectl get services

Поток трафика c: Клиент -> LoadBalancer:port (2) -> NodeIP:NodePort -> Pod:targetPort

Миникуб: LoadBalancer

Примечание: Эта функция доступна только для облачных провайдеров или сред, которые поддерживают внешние балансировщики нагрузки.

- Kubernetes.io: создание внешнего LoadBalancer

На В облачных провайдерах, которые поддерживают балансировщики нагрузки, для доступа к Сервису будет предоставлен внешний IP-адрес. В Minikube тип LoadBalancer делает Службу доступной с помощью команды minikube service.

- Kubernetes.io: Hello minikube

Minikube может создать объект службы типа LoadBalancer (1), но не будет создавать внешний LoadBalancer (2).

ExternalIP в команде $ kubectl get services будет иметь статус ожидания.

Чтобы решить, что нет внешнего LoadBalancer (2), вы можете вызвать $ minikube tunnel, который создаст маршрут от хоста до среды minikube для прямого доступа к CIDR из ClusterIP.

0 голосов
/ 03 февраля 2020

По вопросам:

  • Но я не понимаю, как в реальном кластере служба могла бы иметь фиксированный порт, доступный в мире.
  • Когда Доступ к сервису из-за пределов всего кластера без мини-куба (например, в GKE). Какое значение имеет nodePort?

В облачной среде, предоставляемой кластерами Kubernetes LoadBalancer тип сервиса будет иметь внешний IP-адрес, назначенный облачным провайдером. Желаемый сервис будет доступен по предоставленному внешнему IP. LoadBalancer также автоматически создаст тип услуги NodePort для внутренней маршрутизации трафика c. Порты NodePort не будут доступны для прямого соединения с IP-адресом узла с внешним трафиком c.

Created LoadBalancer позволит вам указать порт, на который он будет отвечать на трафик c.

Взгляните на приведенную ниже ссылку со ссылкой:

Объявление службы типа LoadBalancer предоставляет ее извне с помощью балансировщика нагрузки облачного провайдера. Облачный провайдер предоставит балансировщик нагрузки для Service и сопоставит его с автоматически назначенным NodePort.

--- Ovh.com: getting-external-traffi c -инто-кубернетес

...