Der Kubernetes-Dienst antwortet auf einem anderen Port als dem zugewiesenen Port

Dec 16 2020

Ich habe nur wenige Dienste bereitgestellt und festgestellt, dass sich ein Dienst anders verhält als andere. Ich habe es so konfiguriert, dass es den 8090-Port überwacht (der intern 8443 zugeordnet ist), aber die Anforderung funktioniert nur, wenn ich an Port 8080 sende. Hier ist meine Yaml-Datei für den Dienst (auf das Wesentliche reduziert) und es gibt eine Bereitstellung, die den Dienst kapselt und Behälter

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

Nach der Installation des Helms kubectl get svcerhalte ich beim Ausführen die folgende Ausgabe

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

Wenn ich jedoch in einen der anderen laufenden Container ssh und eine Curl-Anfrage für 8090 ausstelle, wird "Verbindung abgelehnt" angezeigt. Wenn ich mich zu "http: // uisvc: 8080" bewege, erhalte ich die richtige Antwort. Auf dem Container wird eine Spring-Boot-Anwendung ausgeführt, die standardmäßig 8080 abhört. Die einzige Erklärung, die ich finden könnte, ist, dass der Port / Zielport in dieser Konfiguration irgendwie ignoriert wird und andere Pods direkt den Spring-Service im Inneren erreichen.

Ist dieses Verhalten korrekt? Warum hört es nicht auf 8090? Wie soll ich es so machen?

Bearbeiten: Ausgabe für 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>

Antworten

1 thomas Dec 16 2020 at 20:39

Dies ist das erwartete Verhalten, seit Sie es verwendet haben headless service.

Headless Services werden für den Service Discovery-Mechanismus verwendet. Anstatt einzelne zurückzugeben DNS A records, DNS serverwerden mehrere A recordsfür Ihren Service zurückgegeben, die jeweils auf die IP eines einzelnen Pods verweisen, der den Service unterstützt. Sie führen also eine einfache DNS A recordsSuche durch und erhalten die IP aller Pods, die Teil des Dienstes sind.

Da headless servicekeine iptablesRegeln erstellt dns records, sondern stattdessen erstellt werden, können Sie anstelle eines Proxys direkt mit Ihrem Pod interagieren. Wenn Sie sich also entschließen, erhalten <servicename:port>Sie <podN_IP:port>und Ihre Verbindung wird direkt zum Pod. Solange sich all dies im selben Namespace befindet, haben Sie es nicht durch den vollständigen DNS-Namen aufgelöst.

Mit mehreren Pods gibt DNS Ihnen alle und gibt sie einfach in zufälliger Reihenfolge (oder in RR-Reihenfolge) ein. Die Reihenfolge hängt von der Implementierung und den Einstellungen des DNS-Servers ab.

Weitere Informationen finden Sie unter:

  • Services-Netowrking / Headless-Services
  • Dieser Stapel enthält Fragen mit einer hervorragenden Antwort, die erklären, wie kopflose Dienste funktionieren