Oczekiwanie na zewnętrzny adres IP usługi Kubernetes


160

Próbuję wdrożyć nginx na kubernetes, wersja kubernetes to 1.5.2, wdrożyłem nginx z 3 replikami, plik YAML jest poniżej,

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: deployment-example
spec:
  replicas: 3
  revisionHistoryLimit: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.10
        ports:
        - containerPort: 80

a teraz chcę ujawnić jego port 80 na porcie 30062 węzła, w tym celu utworzyłem usługę poniżej,

kind: Service
apiVersion: v1
metadata:
  name: nginx-ils-service
spec:
  ports:
    - name: http
      port: 80
      nodePort: 30062
  selector:
    app: nginx
  type: LoadBalancer

ta usługa działa dobrze, jak powinna, ale jest wyświetlana jako oczekująca nie tylko na pulpicie kubernetes, ale także na terminalu. Wyjście terminalaStan tablicy rozdzielczej

Odpowiedzi:


187

Wygląda jak używasz niestandardowego Kubernetes Cluster (z użyciem minikube, kubeadmlub tym podobne). W tym przypadku nie ma zintegrowanego LoadBalancera (w przeciwieństwie do AWS czy Google Cloud). W tej domyślnej konfiguracji możesz używać tylko NodePortlub kontrolera Ingress.

Za pomocą kontrolera Ingress możesz skonfigurować nazwę domeny, która jest mapowana na Twój pod; nie musisz podawać typu swojej usłudze, LoadBalancerjeśli używasz kontrolera Ingress.


Dziękuję bardzo @javier, to jest naprawdę pomocne. Rozwiązałem swój problem z powyższego doc.
Pankaj Jackson

11
To naprawdę nie odpowiada na pytanie? Użytkownik używa LoadBalancerjako typu usługi, który jest prawidłowym typem usługi. NodePorti czy ingresssą inne sposoby na zrobienie tego, ale tak naprawdę nie rozwiązują problemu, prawda?
Raptor

2
Jest to poprawny typ usługi, ale jest używany na niekompatybilnej platformie (przynajmniej domyślnie). Aby korzystać z LoadBalancer, musisz mieć platformę, która może udostępniać zewnętrzne adresy IP do podów, co jest czymś, co robi Google Cloud lub AWS.
Javier Salmeron

2
Używam kubeadm na AWS. Czy nadal mogę LoadBalancer?
jiashenC

4
Jeśli używasz minikube, uruchom „minikube tunel”. Teraz sprawdź swoje usługi, otrzymasz publiczny adres IP. Tutaj jest dokument, aby uzyskać więcej informacji minikube.sigs.k8s.io/docs/tasks/loadbalancer
Ravi

93

Jeśli używasz Minikube, istnieje magiczne polecenie!

$ minikube tunnel

Miejmy nadzieję, że ktoś może dzięki temu zaoszczędzić kilka minut.

Link referencyjny https://minikube.sigs.k8s.io/docs/handbook/accessing/#using-minikube-tunnel


Próbowałem minikube tunneli faktycznie rozwiązuje pendingproblem, ale nowy zewnętrzny adres IP nie działa: pojawia się błąd
przekroczenia

@ a.barbieri upewnij się, że używasz tunelu ip zamiast minikube ip. „łatanie ingress-nginx za pomocą adresu IP 10.106.102.98”
Peter Zhou,

2
tak, dziękuję Peter. Spróbuję. W każdym razie, przełączając się na Docker Desktop, udało mi się przezwyciężyć ten problem dzięki gotowemu ustawieniu, które działa bezpośrednio na hoście lokalnym.
a.barbieri

3
Doskonała wskazówka oszczędzająca czas do demonstracji!
jgitter

1
To było zbyt trudne do znalezienia. Dziękuję Ci bardzo.
senfo

53

Jeśli nie używasz GCE ani EKS (używałeś kubeadm), możesz dodać externalIPsspecyfikację do swojej usługi YAML. Możesz użyć adresu IP skojarzonego z podstawowym interfejsem węzła, na przykład eth0. Następnie możesz uzyskać dostęp do usługi z zewnątrz, używając zewnętrznego adresu IP węzła.

...
spec:
  type: LoadBalancer
  externalIPs:
  - 192.168.0.10

2
Musi brakować informacji: „zewnętrzne adresy IP nie są zarządzane przez Kubernetes, a odpowiedzialność za nie ponosi administrator klastra”. ( kubernetes.io/docs/concepts/services-networking/service ). Czy jest jakiś „kontroler”, który muszę zainstalować?
Daniel Alder,

Śledzę samouczek Kubernetes ( kubernetes.io/docs/tutorials/stateless-application/guestbook ) i działał dobrze z kubeadm
Eduardo

Dziękuję - genialnie, działało zgodnie z oczekiwaniami. Wystawiłem usługę na węzły IP sieci eth, która jest teraz dostępna poza klastrem
Vlad Gulin


24

Utworzyłem klaster K8s z jednym węzłem przy użyciu programu Kubeadm. Kiedy próbowałem PortForward i kubectl proxy , pokazała zewnętrznego IP jako oczekujące.

$ kubectl get svc -n argocd argocd-server
NAME            TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
argocd-server   LoadBalancer   10.107.37.153   <pending>     80:30047/TCP,443:31307/TCP   110s

W moim przypadku poprawiłem usługę w ten sposób:

kubectl patch svc <svc-name> -n <namespace> -p '{"spec": {"type": "LoadBalancer", "externalIPs":["172.31.71.218"]}}'

Następnie zaczął udostępniać za pośrednictwem publicznego adresu IP

$ kubectl get svc argo-ui -n argo
NAME      TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
argo-ui   LoadBalancer   10.103.219.8   172.31.71.218   80:30981/TCP   7m50s

13
Może warto wspomnieć, skąd pochodzi „172.31.71.218”?
EuRBamarth

Wreszcie odpowiedź, która podaje, jak łatać. Dzięki za udostępnienie.
Srikant

5

Jeśli używasz minikube , nie zapomnij wspomnieć o przestrzeni nazw, jeśli nie używasz default.

usługa minikube << service_name >> --url --namespace = << namespace_name >>


4

Jeśli używasz minikube, uruchom poniższe polecenia z terminala,

$ minikube ip
$ 172.17.0.2 // then 
$ curl http://172.17.0.2:31245
or simply
$ curl http://$(minikube ip):31245

3

Po odpowiedzi @ Javier. Zdecydowałem się na „łatanie zewnętrznego adresu IP” dla mojego modułu równoważenia obciążenia.

 $ kubectl patch service my-loadbalancer-service-name \
-n lb-service-namespace \
-p '{"spec": {"type": "LoadBalancer", "externalIPs":["192.168.39.25"]}}'

Spowoduje to zastąpienie tego „oczekującego” nowym, poprawionym adresem IP, którego możesz używać dla swojego klastra.

Więcej na ten temat. Proszę zobaczyć Karthik na post na wsparcie LoadBalancer z Minikube dla Kubernetes

Nie jest to najczystszy sposób. Potrzebowałem tymczasowego rozwiązania. Mam nadzieję, że to komuś pomoże.


3

Dodanie rozwiązania dla tych, którzy napotkali ten błąd podczas pracy na .

Przede wszystkim biegnij:

kubectl describe svc <service-name>

Następnie przejrzyj eventspole w przykładowym wyniku poniżej:

Name:                     some-service
Namespace:                default
Labels:                   <none>
Annotations:              kubectl.kubernetes.io/last-applied-configuration:
                            {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"some-service","namespace":"default"},"spec":{"ports":[{"port":80,...
Selector:                 app=some
Type:                     LoadBalancer
IP:                       10.100.91.19
Port:                     <unset>  80/TCP
TargetPort:               5000/TCP
NodePort:                 <unset>  31022/TCP
Endpoints:                <none>
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type     Reason                  Age        From                Message
  ----     ------                  ----       ----                -------
  Normal   EnsuringLoadBalancer    68s  service-controller  Ensuring load balancer
  Warning  SyncLoadBalancerFailed  67s  service-controller  Error syncing load balancer: failed to ensure load balancer: could not find any suitable subnets for creating the ELB

Przejrzyj komunikat o błędzie:

Failed to ensure load balancer: could not find any suitable subnets for creating the ELB

W moim przypadku przyczyną braku odpowiednich podsieci do utworzenia ELB były:

1: Klaster EKS został wdrożony w niewłaściwej grupie podsieci - podsieci wewnętrzne zamiast publicznych.
(*) Domyślnie usługi typu LoadBalancertworzą publiczne moduły równoważenia obciążenia, jeśli nie service.beta.kubernetes.io/aws-load-balancer-internal: "true"podano adnotacji).

2: Podsieci nie zostały oznaczone zgodnie z wymaganiami wymienionymi tutaj .

Tagowanie VPC za pomocą:

Key: kubernetes.io/cluster/yourEKSClusterName
Value: shared

Oznaczanie podsieci publicznych za pomocą:

Key: kubernetes.io/role/elb
Value: 1

3

Użyj NodePort:

$ kubectl run user-login --replicas=2 --labels="run=user-login" --image=kingslayerr/teamproject:version2  --port=5000

$ kubectl expose deployment user-login --type=NodePort --name=user-login-service

$ kubectl describe services user-login-service

(Zanotuj port)

$ kubectl cluster-info

(IP-> Get the IP, gdzie master jest uruchomiony)

Twoja usługa jest dostępna pod adresem (IP) :( port)


2

ten sam problem:

os> kubectl pobierz svc right-sabertooth-wordpress

NAZWA TYP
KLASTER -IP PORT (S) ZEWNĘTRZNY-IP prawy-szablasta-wordpress LoadBalancer 10.97.130.7 „pending” 80: 30454 / TCP, 443: 30427 / TCP

os> lista usług minikube

| ------------- | ---------------------------- | ------ -------------------------- |

| NAMESPACE | NAZWA | URL |

| ------------- | ---------------------------- | ------ -------------------------- |

| domyślnie | kubernetes | Brak portu węzła |

| domyślnie | right-sabertooth-mariadb | Brak portu węzła |

| domyślnie | right-sabertooth-wordpress | http://192.168.99.100:30454 |

| | | http://192.168.99.100:30427 |

| kube-system | kube-dns | Brak portu węzła |

| kube-system | tiller-deploy | Brak portu węzła |

| ------------- | ---------------------------- | ------ -------------------------- |

Jest jednak dostępny pod adresem http://192.168.99.100:30454 .



1

LoadBalancer ServiceType będzie działać tylko wtedy, gdy podstawowa infrastruktura obsługuje automatyczne tworzenie Load Balancerów i ma odpowiednią obsługę w Kubernetes, tak jak w przypadku Google Cloud Platform i AWS. Jeśli żadna taka funkcja nie jest skonfigurowana, pole adresu IP LoadBalancer nie jest wypełnione i nadal znajduje się w stanie oczekiwania, a Usługa będzie działać tak samo, jak usługa typu NodePort


1

Możesz załatać adres IP węzła, na którym hostowane są pody (prywatne IP węzła), jest to łatwe obejście.

Biorąc pod uwagę powyższe posty, następujące działały dla mnie:

usługa poprawki kubectl nazwa-usługi-usługi-obciążenia-obciążenia \ -n przestrzeń-nazw-usługi-lb \ -p '{"spec": {"type": "LoadBalancer", "externalIPs": ["xxx.xxx.xxx.xxx Private IP serwera fizycznego - węzeł - gdzie wdrażanie jest wykonywane "]}} '


1

Jeśli jest to Twój prywatny klaster K8s, MetalLB byłby lepszym rozwiązaniem. Poniżej znajdują się kroki.

Krok 1: Zainstaluj MetalLB w swoim klastrze

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/metallb.yaml
# On first install only
kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"

Krok 2: Skonfiguruj go za pomocą configmap

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 172.42.42.100-172.42.42.105 #Update this with your Nodes IP range 

Krok 3: Utwórz usługę, aby uzyskać zewnętrzny adres IP (byłby to jednak prywatny adres IP).

FYR:

Przed instalacją MetalLB: wprowadź opis obrazu tutaj

Po instalacji MetalLB: wprowadź opis obrazu tutaj

wprowadź opis obrazu tutaj


1

Korzystając z Minikube, możesz uzyskać adres IP i port, przez który możesz uzyskać dostęp do usługi, uruchamiając:

minikube service [service name]

Na przykład:

minikube service kubia-http

0

Sprawdź dzienniki kontrolera Kube. Udało mi się rozwiązać ten problem, ustawiając tagi clusterID na instancję ec2, w której wdrożyłem klaster.


0

Istnieją trzy typy udostępniania usługi Nodeport ClusterIP LoadBalancer

Kiedy używamy loadbalancera, zasadniczo prosimy naszego dostawcę usług w chmurze o podanie nam nazw DNS, do których można uzyskać dostęp online. Uwaga: nie nazwa domeny, ale DNS.

Więc typ loadbalancera nie działa w naszym lokalnym środowisku minikube.


0

Usunięcie istniejącej usługi i utworzenie tej samej nowej usługi rozwiązało moje problemy. Moje problemy polegają na tym, że zdefiniowany przeze mnie adres IP równoważenia obciążenia jest używany tak, że zewnętrzny punkt końcowy oczekuje. Kiedy zmieniłem nowy adres IP równoważenia obciążenia, nadal nie mógł działać.

Na koniec usuń istniejącą usługę i utwórz nową, rozwiązując mój problem.


0

W przypadku, gdy ktoś używa MicroK8: Potrzebujesz modułu równoważenia obciążenia sieciowego.

MicroK8s jest dostarczany z metallb, możesz go włączyć w następujący sposób:

microk8s enable metallb

<pending> powinien zmienić się w rzeczywisty adres IP.

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.