Jaka jest różnica między typami usług ClusterIP, NodePort i LoadBalancer w Kubernetes?


230

1 - Czytam dokumentację i jestem nieco mylony z brzmieniem. To mówi:

ClusterIP : udostępnia usługę pod wewnętrznym adresem IP klastra. Wybranie tej wartości sprawia, że ​​usługa jest dostępna tylko z poziomu klastra. Jest to domyślny typ usługi

NodePort : Odsłania usługę na adresie IP każdego węzła w porcie statycznym (NodePort). Usługa ClusterIP, do której będzie kierowana usługa NodePort, jest tworzona automatycznie. Będziesz mógł skontaktować się z usługą NodePort spoza klastra, wysyłając zapytanie <NodeIP>:<NodePort>.

LoadBalancer : Odsłania usługę zewnętrznie za pomocą modułu równoważenia obciążenia dostawcy chmury. Usługi NodePort i ClusterIP, do których będzie kierowany zewnętrzny moduł równoważenia obciążenia, są tworzone automatycznie.

Czy typ usługi NodePort nadal korzysta z ClusterIPinnego portu, ale jest otwarty dla klientów zewnętrznych? Więc w tym przypadku jest <NodeIP>:<NodePort>to samo co <ClusterIP>:<NodePort>?

A może NodeIPfaktycznie znajduje się adres IP podczas uruchamiania, kubectl get nodesa nie wirtualny adres IP używany dla typu usługi ClusterIP?

2 - Również na schemacie z linku poniżej:

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

Czy jest jakiś konkretny powód, dla którego Clientjest w środku Node? ClusterZakładam, że będzie musiał znajdować się w przypadku usługi typu ClusterIP.

Jeśli ten sam schemat został narysowany dla NodePort, czy poprawne byłoby narysowanie klienta całkowicie poza Nodei Clusterczy całkowicie brakuje mi sensu?

Odpowiedzi:


217

ClusterIP ujawnia następujące elementy:

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

Dostęp do tej usługi można uzyskać tylko w klastrze. Jest dostępny z jego spec.clusterIpportu. Jeśli spec.ports[*].targetPortustawiony jest a, będzie on kierował z portu do portu docelowego. CLUSTER-IP, który otrzymujesz podczas połączenia, kubectl get servicesto adres IP przypisany do tej usługi wewnątrz klastra.

NodePort udostępnia następujące elementy:

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

Jeśli uzyskasz dostęp do tej usługi w węźle node z zewnętrznego adresu IP węzła, przekieruje żądanie do spec.clusterIp:spec.ports[*].port, które z kolei skieruje je do twojego spec.ports[*].targetPort, jeśli jest ustawione. Dostęp do tej usługi można uzyskać w taki sam sposób, jak ClusterIP.

Twoje NodeIP są zewnętrznymi adresami IP węzłów. Nie możesz uzyskać dostępu do swojej usługi z <ClusterIP>:spec.ports[*].nodePort.

LoadBalancer udostępnia następujące elementy:

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

Dostęp do tej usługi można uzyskać z adresu IP modułu równoważenia obciążenia, który kieruje żądanie do portu nodePort, który z kolei kieruje żądanie do portu IP klastra. Możesz uzyskać dostęp do tej usługi, tak jak do usługi NodePort lub ClusterIP.


3
Czy mógłbyś skomentować, jak externalIPszmienia się tutaj równanie? W szczególności można przypisać externalIPstablicę do usługi ClusterIPtypu, a następnie usługa stanie się dostępna również na zewnętrznym adresie IP? Kiedy wybrałbyś to zamiast NodePort?
Bosh,

Pytanie nie wspomina o zewnętrznych IP - myślę, że najlepiej byłoby, gdybyś opublikował je jako nowe pytanie.
kellanburket

39
Ten post jest w rzeczywistości bardziej przydatny w wyjaśnianiu tych różnic niż sama oficjalna dokumentacja Kubernetes.
adrpino

@kellanburket, jak to działa: spec.clusterIp. Czy ClusterIP można wyraźnie wymienić w service.yaml. I podobniespec.loadBalancerIp
samshers

zmarnowałeś dzień swoją odpowiedzią, dziękuję bardzo! (na marginesie, w 2020 r. nadal dokumentacja sieciowa jest nieco niejasna)
user430191

103

Wyjaśnienie dla każdego, kto szuka różnicy między 3 na prostszym poziomie. Możesz udostępnić swoją usługę przy minimalnym ClusterIp (w klastrze k8s) lub większym ekspozycji za pomocą NodePort (w klastrze zewnętrznym w klastrze k8s) lub LoadBalancer (świat zewnętrzny lub cokolwiek zdefiniowano w LB).

Ekspozycja ClusterIp <Ekspozycja NodePort <Ekspozycja LoadBalancer

  • Usługa ClusterIp
    Expose za pośrednictwem klastra k8s przy pomocyip/name:port
  • Usługa NodePort
    Expose przez maszynę wirtualną sieci wewnętrznej również zewnętrzną wobec k8sip/name:port
  • Usługa LoadBalancer
    Expose przez świat zewnętrzny lub cokolwiek zdefiniowano w LB.

53

ClusterIP: Usługi są osiągalne przez pods / usługi w klastrze
Jeśli utworzę usługę o nazwie myservice w domyślnej przestrzeni nazw typu: ClusterIP, to zostanie utworzony następujący przewidywalny statyczny adres DNS dla usługi:

myservice.default.svc.cluster.local (lub po prostu myservice.default lub według pods w domyślnej przestrzeni nazw po prostu „myservice” będzie działać)

I tę nazwę DNS można rozwiązać tylko za pomocą zasobników i usług w klastrze.

NodePort: Usługi są dostępne dla klientów w tej samej sieci LAN / klientach, którzy mogą pingować węzły hosta K8s (i pods / usługi w klastrze) (uwaga dla bezpieczeństwa twoje węzły hosta K8s powinny znajdować się w prywatnej podsieci, dlatego klienci w Internecie wygrywają nie będzie w stanie uzyskać
dostępu do tej usługi) Jeśli wykonam usługę o nazwie mynodeportservice w przestrzeni nazw mynamespace typu: NodePort w 3-węzłowym klastrze Kubernetes. Następnie zostanie utworzona usługa typu: ClusterIP i będzie ona dostępna dla klientów w klastrze pod następującym przewidywalnym statycznym adresem DNS:

mynodeportservice.mynamespace.svc.cluster.local (lub po prostu mynodeportservice.mynamespace)

Dla każdego portu, który mynodeportservice nasłuchuje na porcie węzłowym w zakresie 30000 - 32767, zostanie losowo wybrany. Aby klienci zewnętrzni spoza klastra mogli trafić do usługi ClusterIP, która istnieje w klastrze. Powiedzmy, że nasze 3 węzły hosta K8 mają adresy IP 10.10.10.1, 10.10.10.2, 10.10.10.3, usługa Kubernetes nasłuchuje na porcie 80, a losowo wybrany Nodeport to 31852.

Klient, który istnieje poza klastrem, może odwiedzić 10.10.10.1:31852, 10.10.10.2:31852 lub 10.10.10.3:31852 (jak nasłuchuje NodePort przez każdy węzeł hosta Kubernetes) Kubeproxy przekaże żądanie do portu 80 mynodeportservice.

LoadBalancer: Usługi są dostępne dla wszystkich podłączonych do Internetu * (wspólna architektura to L4 LB jest publicznie dostępny w Internecie, umieszczając go w strefie DMZ lub nadając mu zarówno prywatny, jak i publiczny adres IP, a węzły hosta K8s są w prywatnej podsieci)
( Uwaga: jest to jedyny typ usługi, który nie działa w 100% implementacjach Kubernetes, takich jak Kubernetes od zera, działa, gdy Kubernetes ma integracje z dostawcą chmury.)

Jeśli wykonasz mylbservice, zostanie odrodzona maszyna wirtualna L4 LB (usługa IP klastra, a także usługa NodePort). Tym razem naszym węzłem NodePort jest 30222. Idea polega na tym, że L4 LB będzie miał publiczny adres IP 1.2.3.4 i załaduje równowagę i przekaże ruch do 3 węzłów hosta K8, które mają prywatne adresy IP. (10.10.10.1:30222, 10.10.10.2:30222, 10.10.10.3:30222), a następnie Kube Proxy prześle go do usługi typu ClusterIP, która istnieje wewnątrz klastra.


Zapytałeś również: Czy typ usługi NodePort nadal korzysta z ClusterIP? Tak *
Czy NodeIP faktycznie znajduje adres IP po uruchomieniu kubectl get nodes? Również Tak *

Narysujmy równolegle Podstawy:
Pojemnik znajduje się w kapsule. kapsuła znajduje się w replice. replika znajduje się we wdrożeniu.
Podobnie:
usługa ClusterIP jest częścią usługi NodePort. Usługa NodePort jest częścią usługi modułu równoważenia obciążenia.


Na pokazanym diagramie klient będzie kapsułą wewnątrz klastra.


Na podstawie twoich dalszych pytań miałem wrażenie, że chcesz wiedzieć, jak ruch wchodzi do klastra. Zainteresowałem się tym, aby zadać pytanie na ten temat. stackoverflow.com/questions/52241501/…
neokyle

1
Hej, naprawdę dobre wytłumaczenie, zastanawiam się nad LoadBalancer. LoadBalancer przekieruje każdy ruch do NodeIP: NodePort (ten węzeł, który jest następny w rundzie robin) i jak przebiega wywołanie w tym węźle? Skąd port węzła wie, że jest to wywołanie usługi i że powinien rozpowszechniać je za pośrednictwem serwera proxy do wirtualnego adresu IP usługi? Czy serwer proxy kube utworzy prosty port do przekierowania?
ItFreak,

kube-proxy odgrywa 3 główne role: 1. Spraw, aby usługi istniały / działały, dostosowując iptables w węźle do pożądanego stanu usług w etcd. 2. odpowiada za mapowanie portu węzła do obsługi poda (rozumiem, że robi to za pomocą iptables) + mapowania portów 3. upewnij się, że każdy pod ma unikalny adres IP. Nodeport może wejść w 1 węźle, definicje usług istnieją w iptables każdego węzła / usługi istnieją w każdym węźle, zasobniki są zwykle w zwirtualizowanej sieci nakładek, a węzły są podwójne jako routery, więc chociaż ruch przychodzi w 1 węźle, zostaje przekierowany na pod istniejący w innym węźle.
neokyle

Wiedza o tym, jak działa na poziomie głębszym niż ten, jest bezcelowa, ponieważ kubernetes składa się z elementów modułowych i podobnie jak Linux ma smaki / dystrybucje, które działają nieco inaczej z niektórymi nadrzędnymi motywami, każda dystrybucja k8s jest nieco inna. Przykład cilium cni chce całkowicie zastąpić kube-proxy, co oznacza, że ​​sposób, w jaki działa za kulisami, jest ruchomym celem, dlatego nie warto go rozumieć, chyba że faktycznie przyczyniasz się do projektu / próbujesz naprawić błąd.
neokyle

Czy istnieje sposób, aby się z tobą skontaktować? Piszę pracę licencjacką na temat bezpieczeństwa w k8s i chciałbym dowiedzieć się o wewnętrznych funkcjach proxy, np. W jaki sposób dystrybuuje adresy IP do węzłów i
podsów

45

Załóżmy, że utworzyłeś Ubuntu VM na swoim komputerze lokalnym. Jego adres IP to 192.168.1.104 .

Zaloguj się do VM i zainstalowałeś Kubernetes. Następnie utworzyłeś kapsułę, na której działa obraz Nginx.

1- Jeśli chcesz uzyskać dostęp do tego urządzenia Nginx wewnątrz maszyny wirtualnej, utworzysz ClusterIP powiązany z tym urządzeniem na przykład:

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

Następnie w przeglądarce możesz wpisać adres IP nginxclusterip z portem 80, na przykład:

http://10.152.183.2:80

2- Jeśli chcesz uzyskać dostęp do tego urządzenia Nginx z komputera hosta, musisz ujawnić swoje wdrożenie za pomocą NodePort . Na przykład:

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

Teraz z komputera hosta możesz uzyskać dostęp do nginx, takich jak:

http://192.168.1.104:31865/

Na moim pulpicie są one wyświetlane jako:

wprowadź opis zdjęcia tutaj

Poniżej znajduje się schemat pokazujący podstawową zależność.

wprowadź opis zdjęcia tutaj


Skąd pochodzi 31865? wygenerowane?
HoaPhan,

1
@HoaPhan Możesz jawnie określić swój port w zakresie 30000-32767 lub pozwolić, aby został wybrany losowo przez Kubernetes w tym zakresie
Mohammad Torkashvand

20

Nawet jeśli to pytanie ma już odpowiedź, przedstawię jeszcze jedno, może jeszcze kilka zdjęć, aby lepiej zrozumieć.

1. ClusterIP to domyślny typ usługi w Kubernetes i ten typ zapewnia usługę wewnątrz klastra. Dzięki temu inne aplikacje z klastra mogą uzyskać dostęp do usługi za pośrednictwem serwera proxy Kubernetes.

Powinienem wspomnieć, że tego rodzaju usług nie należy wykorzystywać do udostępniania usług produkcyjnych. Można go jednak użyć do

  • debugowanie integracji między usługami;
  • dostęp do usług wewnętrznych, które ujawniają dane niezwiązane z działalnością gospodarczą (panele kontrolne monitorowania).

Sposób realizacji żądania jest następujący: ruch -> serwer proxy K8s -> usługa K8s (ClusterIP) -> zasobniki i jest wyświetlany na poniższym obrazku.

wprowadź opis zdjęcia tutaj

2. NodePort jest najbardziej prymitywnym sposobem na akceptację ruchu zewnętrznego i przekazanie go do usług kubernetes. Jak sama nazwa wskazuje, typ usługi NodePort otwiera określony port na wszystkich maszynach wirtualnych, które w rzeczywistości są węzłami Kubernetes, aby umożliwić przesyłanie ruchu do tego konkretnego portu do usługi.

Typ usługi NodePort ma kilka wad:

  • konieczna jest tylko jedna usługa na port;
  • jeśli ip maszyny wirtualnej zostanie zmieniony, niektóre zmiany muszą zostać wprowadzone w klastrze;
  • można użyć tylko portu między 3000-32767.

Sposób realizacji tego żądania jest następujący: ruch -> port udostępniony na maszynie wirtualnej -> usługa K8s (NodePort) -> zasobniki i jest wyświetlany na poniższym obrazku:

wprowadź opis zdjęcia tutaj

3. LoadBalancer to standardowy sposób na ujawnienie usługi w Internecie. Jeśli pragniesz bezpośrednio ujawnić usługę i cały ruch na określonym porcie, który ma zostać przekazany do usługi, to jest to sposób, aby to zrobić. Ponadto typ usługi LoadBalancer nie wymaga żadnego filtrowania ani routingu. Ponadto możesz wysyłać do niego ruch TCP, UDP, HTTP gRPC.

Wada: każda usługa ujawniona za pośrednictwem LoadBalancer będzie miała własny adres IP, a każda usługa zostanie ujawniona za pośrednictwem jednego LoadBalancer, co może stać się kosztowne.

Żądanie ma następującą ścieżkę: ruch -> LoadBalancer -> Usługa K8s -> zasobniki i jest wyświetlane na poniższym obrazku.

wprowadź opis zdjęcia tutaj


7
  1. klasterIP: adres IP dostępny w klastrze (między węzłami w klastrze d).
nodeA : pod1 => clusterIP1, pod2 => clusterIP2
nodeB : pod3 => clusterIP3.

pod3 może rozmawiać z pod1 za pośrednictwem sieci klastrIPIP.

  1. nodeport: aby udostępnić kapsułki spoza klastra za pośrednictwem nodeIP: nodeport, utworzy / utrzyma klasterIP powyżej jako swoją sieć klastrIPIP.
nodeA => nodeIPA : nodeportX
nodeB => nodeIPB : nodeportX

możesz uzyskać dostęp do usługi na pod1 albo przez nodeIPA: nodeportX LUB nodeIPB: nodeportX. Tak czy inaczej, zadziała, ponieważ kube-proxy (zainstalowany w każdym węźle) otrzyma twoje żądanie i roześle je [przekieruje (termin iptables)] między węzłami za pomocą sieci klasterIP.

  1. Moduł równoważenia obciążenia

po prostu umieszczając LB na pierwszym planie, aby ruch przychodzący był rozprowadzany do węzła IPA: nodeportX i węzła IPB: nodeportX, a następnie kontynuuj przepływ procesu nr 2 powyżej.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.