В чем разница между типами служб ClusterIP, NodePort и LoadBalancer в Кубернетесе?


230

1 - Я читаю документацию и меня слегка смущает формулировка. Это говорит:

ClusterIP : Предоставляет сервис по внутреннему IP- адресу кластера. Выбор этого значения делает службу доступной только из кластера. Это тип сервиса по умолчанию

NodePort : Предоставляет сервис для каждого IP-адреса узла в статическом порту (NodePort). Служба ClusterIP, к которой будет направляться служба NodePort, создается автоматически. Вы сможете связаться со службой NodePort из-за пределов кластера, запросив <NodeIP>:<NodePort>.

LoadBalancer : предоставляет сервис извне, используя балансировщик нагрузки облачного провайдера. Службы NodePort и ClusterIP, к которым будет направляться внешний балансировщик нагрузки, создаются автоматически.

Использует ли тип сервиса NodePort еще ClusterIPодин порт, который открыт для внешних клиентов? Так в этом случае так <NodeIP>:<NodePort>же, как <ClusterIP>:<NodePort>?

Или NodeIPфактически IP-адрес обнаружен при запуске, kubectl get nodesа не виртуальный IP-адрес, используемый для типа службы ClusterIP?

2 - Также на схеме по ссылке ниже:

http://kubernetes.io/images/docs/services-iptables-overview.svg

Есть ли какая-то конкретная причина, почему Clientэто внутри Node? Я предположил, что это должно быть внутри Clusterв случае типа службы ClusterIP.

Если бы такая же диаграмма была нарисована для NodePort, было бы правильно нарисовать клиента полностью вне Nodeи, Clusterили я полностью упускаю точку?

Ответы:


217

ClusterIP предоставляет следующее:

  • spec.clusterIp:spec.ports[*].port

Вы можете получить доступ к этой услуге только внутри кластера. Это доступно из своего spec.clusterIpпорта. Если spec.ports[*].targetPortустановлено, он будет направлять от порта до targetPort. CLUSTER-IP, который вы получаете при вызове, kubectl get services- это IP-адрес, назначенный этой службе внутри кластера.

NodePort предоставляет следующее:

  • <NodeIP>:spec.ports[*].nodePort
  • spec.clusterIp:spec.ports[*].port

Если вы получаете доступ к этой службе на nodePort с внешнего IP-адреса узла, он направит запрос на spec.clusterIp:spec.ports[*].port, который, в свою очередь, направит его на ваш spec.ports[*].targetPort, если он установлен. К этой услуге также можно получить доступ так же, как и к ClusterIP.

Ваши NodeIP - это внешние IP-адреса узлов. Вы не можете получить доступ к своему сервису с <ClusterIP>:spec.ports[*].nodePort.

LoadBalancer предоставляет следующее:

  • spec.loadBalancerIp:spec.ports[*].port
  • <NodeIP>:spec.ports[*].nodePort
  • spec.clusterIp:spec.ports[*].port

Вы можете получить доступ к этой услуге с IP-адреса вашего балансировщика нагрузки, который направляет ваш запрос к nodePort, который, в свою очередь, направляет запрос на порт clusterIP. Вы можете получить доступ к этому сервису так же, как к сервису NodePort или ClusterIP.


3
Не могли бы вы прокомментировать, как externalIPsменяется уравнение здесь? В частности, можно назначить externalIPsмассив для ClusterIPСервиса -типа, и тогда сервис станет доступен и по внешнему IP? Когда бы вы выбрали это через NodePort?
Бош

Вопрос не затрагивает внешние IP-адреса. Думаю, вам лучше всего разместить этот вопрос как новый.
kellanburket

39
Этот пост на самом деле более полезен для разъяснения этих различий, чем сама официальная документация Kubernetes.
adrpino

@kellanburket, как это работает: spec.clusterIp. Может ли ClusterIP явно упоминаться в service.yaml. И точно так жеspec.loadBalancerIp
самшеры

Вы сделали мой день своим ответом, большое спасибо! (как примечание, в 2020 году сетевая документация все еще немного неясна)
user430191

103

Чтобы уточнить для тех, кто ищет разницу между 3 на более простом уровне. Вы можете предоставить свой сервис с минимальным ClusterIp (в кластере k8s) или с большей экспозицией с NodePort (в пределах кластера, внешнего по отношению к кластеру k8s) или LoadBalancer (внешний мир или что-то, что вы определили в вашем LB).

Экспозиция ClusterIp <Экспозиция NodePort <Экспозиция LoadBalancer

  • Служба ClusterIp
    Expose через кластер k8s сip/name:port
  • Служба NodePort
    Expose через виртуальную сеть внутренней сети, также внешнюю по отношению к k8ip/name:port
  • LoadBalancer
    Expose службы через Внешний мир или что-то, что вы определили в вашем LB.

53

ClusterIP: Службы доступны через pods / services в кластере.
Если я создаю службу myservice в пространстве имен по умолчанию типа: ClusterIP, то для службы будет создан следующий предсказуемый статический DNS-адрес:

myservice.default.svc.cluster.local (или просто myservice.default, или модулями в пространстве имен по умолчанию, просто "myservice" будет работать)

И это DNS-имя может быть разрешено только модулями и службами внутри кластера.

NodePort: Услуги доступны для клиентов в той же локальной сети / клиентах, которые могут пропинговать узлы хоста K8s (и pods / services в кластере) (Примечание. В целях безопасности ваши узлы хоста k8s должны находиться в частной подсети, поэтому клиенты в Интернете выиграли не сможет связаться с этим сервисом)
Если я создаю сервис mynodeportservice в пространстве имен mynamespace типа: NodePort в 3-узловом кластере Kubernetes. Затем будет создана служба типа: ClusterIP, и она будет доступна клиентам внутри кластера по следующему предсказуемому статическому DNS-адресу:

mynodeportservice.mynamespace.svc.cluster.local (или просто mynodeportservice.mynamespace)

Для каждого порта, который mynodeportservice прослушивает в порте узлов в диапазоне от 30000 до 32767, будет выбран случайным образом. Таким образом, внешние клиенты, находящиеся за пределами кластера, могут использовать эту службу ClusterIP, которая существует внутри кластера. Допустим, что наши 3 узла K8 имеют IP-адреса 10.10.10.1, 10.10.10.2, 10.10.10.3, служба Kubernetes прослушивает порт 80, а выбранный случайный порт был выбран 31852.

Клиент, который существует за пределами кластера, может посетить 10.10.10.1:31852, 10.10.10.2:31852 или 10.10.10.3:31852 (так как NodePort прослушивается каждым узлом узла Kubernetes) Kubeproxy направит запрос на порт 80 mynodeportservice.

LoadBalancer: Услуги доступны всем, кто подключен к Интернету * (Общая архитектура L4 - LB общедоступна в Интернете, если поместить ее в DMZ или предоставить как частный, так и общедоступный IP-адрес, а хост-узлы k8s находятся в частной подсети)
( Примечание. Это единственный тип сервиса, который не работает в 100% реализаций Kubernetes, как, например, Kubernetes с открытым исходным кодом, он работает, когда Kubernetes имеет интеграцию с облачным провайдером.)

Если вы сделаете mylbservice, то будет создана виртуальная машина L4 LB (кластерная IP-служба и служба NodePort будут также неявно созданы). На этот раз наш NodePort - 30222. Идея состоит в том, что LB LB будет иметь публичный IP 1.2.3.4, и он будет загружать баланс и перенаправлять трафик к узлам хоста 3 K8, которые имеют частные IP-адреса. (10.10.10.1:30222, 10.10.10.2:30222, 10.10.10.3:30222), а затем Kube Proxy перенаправит его в службу типа ClusterIP, которая существует внутри кластера.


Вы также спросили: тип службы NodePort все еще использует ClusterIP? Да *
Или на самом деле NodeIP - это IP-адрес, найденный при запуске узлов kubectl get? Также Да *

Давайте проведем параллель между Основами:
Контейнер находится внутри контейнера. стручок находится внутри репликации. Репликация находится внутри развертывания.
Аналогично:
служба ClusterIP является частью службы NodePort. Служба NodePort является частью службы балансировки нагрузки.


На той диаграмме, которую вы показали, клиент будет модулем внутри кластера.


На основании ваших последующих вопросов у меня сложилось впечатление, что вы хотите знать, как трафик входит в кластер. Я взял на себя смелость ответить на этот вопрос, если вам интересно. stackoverflow.com/questions/52241501/…
neokyle

1
Эй, действительно хорошее объяснение, меня интересует LoadBalancer. LoadBalancer будет перенаправлять любой трафик на NodeIP: NodePort (тот узел, который является следующим в циклическом переборе), и как происходит вызов на этом узле? Как порт узла знает, что это вызов службы и что он должен распространять его через прокси-сервер kube на виртуальный IP-адрес службы? Сможет ли kube-proxy сделать простой порт вперед?
ItFreak

kube-proxy играет 3 основные роли: 1. заставить сервисы существовать / работать, приводя iptables на узле в соответствие с желаемым состоянием сервисов в etcd. 2. отвечает за сопоставление порта узла с сервисом для pod (насколько я понимаю, он делает это через iptables) + переназначение портов 3. убедитесь, что каждый модуль имеет уникальный ip. Порт узла может входить на 1 узле, определения служб существуют в iptables каждого узла / служб на каждом узле, модули обычно находятся в виртуальной оверлейной сети, а узлы дублируются как маршрутизаторы, поэтому, хотя трафик поступает на 1 узел, он направляется к модулю, существующему на другом узле.
Неокил

Зная, как это работает на более глубоком уровне, чем это, бессмысленно, потому что kubernetes состоит из модульных частей, и, подобно тому, как у linux есть разновидности / дистрибутивы, которые работают немного по-разному с некоторыми всеобъемлющими темами, каждый дистрибутив k8s немного отличается. Пример cilium cni стремится полностью заменить kube-proxy, что означает, что то, как он работает за кулисами, является движущейся целью, поэтому не стоит понимать, если вы на самом деле не участвуете в проекте / не пытаетесь исправить ошибку.
Неокиль

Есть ли способ связаться с вами? Я пишу дипломную работу о безопасности в k8s и хотел бы узнать о функциях интерна прокси, например, как он распределяет IP-адреса по узлам и модулям и как сервисы получают свой виртуальный IP
ItFreak

45

Предположим, вы создали виртуальную машину Ubuntu на локальном компьютере. Это IP-адрес 192.168.1.104 .

Вы входите в ВМ и устанавливаете Kubernetes. Затем вы создали модуль, на котором запущено изображение nginx.

1. Если вы хотите получить доступ к этому модулю nginx внутри вашей виртуальной машины, вы создадите ClusterIP, связанный с этим модулем, например:

$ kubectl expose deployment nginxapp --name=nginxclusterip --port=80 --target-port=8080

Затем в вашем браузере вы можете ввести IP-адрес nginxclusterip с портом 80, например:

http://10.152.183.2:80

2- Если вы хотите получить доступ к этому модулю nginx с вашего хост-компьютера, вам нужно будет показать свое развертывание с помощью NodePort . Например:

$ kubectl expose deployment nginxapp --name=nginxnodeport --port=80 --target-port=8080 --type=NodePort

Теперь с вашего хост-компьютера вы можете получить доступ к nginx, например:

http://192.168.1.104:31865/

На моей панели они выглядят так:

введите описание изображения здесь

Ниже приведена схема основных отношений.

введите описание изображения здесь


Откуда пришел 31865? генерируется?
HoaPhan

1
@HoaPhan Вы можете явно указать свой порт в диапазоне 30000-32767 или разрешить его случайным образом выбирать Кубернетес в этом диапазоне
Мохаммад Торкашванд

20

Даже если на этот вопрос уже есть ответ, я предоставлю еще один, может быть, еще несколько картинок для лучшего понимания.

1. ClusterIP - это сервис по умолчанию в Kubernetes, и этот тип предоставляет вам сервис внутри кластера. Используя это, другие приложения из кластера могут получить доступ к службе через прокси Kubernetes.

Я должен упомянуть, что этот тип услуг не должен использоваться для демонстрации производственных услуг. Тем не менее, он может быть использован для

  • отладка интеграции между сервисами;
  • доступ к внутренним сервисам, которые предоставляют не связанные с бизнесом данные (панели мониторинга).

Способ выполнения запроса следующий: трафик -> прокси K8s -> служба K8s (ClusterIP) -> pods, и это показано на следующем рисунке.

введите описание изображения здесь

2. NodePort - самый примитивный способ принимать внешний трафик и пересылать его сервисам kubernetes. Как следует из названия, тип службы NodePort открывает определенный порт на всех виртуальных машинах, которые на самом деле являются узлами Kubernetes, чтобы позволить трафику, который он отправляет на этот конкретный порт, перенаправляться в службу.

Тип сервиса NodePort имеет некоторые недостатки:

  • необходимо иметь только один сервис на порт;
  • если ip виртуальной машины будет изменен, некоторые изменения должны быть сделаны в кластере;
  • можно использовать только порт между 3000-32767.

Этот запрос выполняется следующим образом: трафик -> порт , отображаемый на виртуальной машине -> служба K8s (NodePort) -> pods, и он отображается на следующем рисунке:

введите описание изображения здесь

3. LoadBalancer - это стандартный способ предоставления услуги Интернету. Если вы хотите напрямую предоставить сервис и весь трафик через определенный порт для перенаправления в сервис, то это способ сделать это. Кроме того, тип сервиса LoadBalancer не предусматривает никакой фильтрации или маршрутизации. Также вы можете отправлять на него TCP, UDP, HTTP gRPC трафик.

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

Запрос имеет следующий путь: трафик -> LoadBalancer -> Сервис K8s -> pods, и он отображается на следующем рисунке.

введите описание изображения здесь


7
  1. clusterIP: IP, доступный внутри кластера (через узлы в кластере d).
nodeA : pod1 => clusterIP1, pod2 => clusterIP2
nodeB : pod3 => clusterIP3.

pod3 может общаться с pod1 через их кластерную сеть IP.

  1. nodeport: чтобы сделать модули доступными снаружи кластера через nodeIP: nodeport, он создаст / сохранит clusterIP выше в качестве своей кластерной сети IP.
nodeA => nodeIPA : nodeportX
nodeB => nodeIPB : nodeportX

Вы можете получить доступ к службе на pod1 либо через узел IPA: узел порта X ИЛИ узел IPB: узел порта X. В любом случае будет работать, потому что kube-proxy (который установлен на каждом узле) получит ваш запрос и распределит его [перенаправить (термин iptables)] по узлам, использующим сеть clusterIP.

  1. Балансировщик нагрузки

в основном, просто помещая LB вперед, чтобы входящий трафик распределялся между nodeIPA: nodeportX и nodeIPB: nodeportX, а затем продолжайте с потоком процесса номер 2 выше.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.