it-swarm.com.de

Kubernetes Ingress (GCE) gibt den Fehler 502 immer wieder zurück

Ich versuche einen Ingress in GCE Kubernetes einzurichten. Wenn ich jedoch die in Ingress definierte Kombination aus IP-Adresse und Pfad besuche, erhalte ich weiterhin den folgenden 502-Fehler:

 Ingress 502 error


Folgendes bekomme ich beim Laufen: kubectl describe ing --namespace dpl-staging

Name:           dpl-identity
Namespace:      dpl-staging
Address:        35.186.221.153
Default backend:    default-http-backend:80 (10.0.8.5:8080)
TLS:
  dpl-identity terminates
Rules:
  Host  Path    Backends
  ----  ----    --------
  *
        /api/identity/*     dpl-identity:4000 (<none>)
Annotations:
  https-forwarding-rule:    k8s-fws-dpl-staging-dpl-identity--5fc40252fadea594
  https-target-proxy:       k8s-tps-dpl-staging-dpl-identity--5fc40252fadea594
  url-map:          k8s-um-dpl-staging-dpl-identity--5fc40252fadea594
  backends:         {"k8s-be-31962--5fc40252fadea594":"HEALTHY","k8s-be-32396--5fc40252fadea594":"UNHEALTHY"}
Events:
  FirstSeen LastSeen    Count   From                SubObjectPath   Type        Reason  Message
  --------- --------    -----   ----                -------------   --------    ------  -------
  15m       15m     1   {loadbalancer-controller }          Normal      ADD dpl-staging/dpl-identity
  15m       15m     1   {loadbalancer-controller }          Normal      CREATE  ip: 35.186.221.153
  15m       6m      4   {loadbalancer-controller }          Normal      Service no user specified default backend, using system default

Ich denke, das Problem ist dpl-identity:4000 (<none>). Sollte ich nicht die IP-Adresse des dpl-identity-Dienstes anstelle von <none> sehen?

Hier ist meine Servicebeschreibung: kubectl describe svc --namespace dpl-staging

Name:           dpl-identity
Namespace:      dpl-staging
Labels:         app=dpl-identity
Selector:       app=dpl-identity
Type:           NodePort
IP:             10.3.254.194
Port:           http    4000/TCP
NodePort:       http    32396/TCP
Endpoints:      10.0.2.29:8000,10.0.2.30:8000
Session Affinity:   None
No events.

Hier ist auch das Ergebnis der Ausführung: kubectl describe ep -n dpl-staging dpl-identity

Name:       dpl-identity
Namespace:  dpl-staging
Labels:     app=dpl-identity
Subsets:
  Addresses:        10.0.2.29,10.0.2.30
  NotReadyAddresses:    <none>
  Ports:
    Name    Port    Protocol
    ----    ----    --------
    http    8000    TCP

No events.

Hier ist mein deploy.yaml:

apiVersion: v1
kind: Secret
metadata:
  namespace: dpl-staging
  name: dpl-identity
type: Opaque
data:
  tls.key: <base64 key>
  tls.crt: <base64 crt>
---
apiVersion: v1
kind: Service
metadata:
  namespace: dpl-staging
  name: dpl-identity
  labels:
    app: dpl-identity
spec:
  type: NodePort
  ports:
    - port: 4000
      targetPort: 8000
      protocol: TCP
      name: http
  selector:
    app: dpl-identity
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  namespace: dpl-staging
  name: dpl-identity
  labels:
    app: dpl-identity
  annotations:
    kubernetes.io/ingress.allow-http: "false"
spec:
  tls:
  - secretName: dpl-identity
  rules:
  - http:
      paths:
        - path: /api/identity/*
          backend:
            serviceName: dpl-identity
            servicePort: 4000
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: dpl-staging
  name: dpl-identity
kind: Ingress
metadata:
  namespace: dpl-staging
  name: dpl-identity
  labels:
    app: dpl-identity
  annotations:
    kubernetes.io/ingress.allow-http: "false"
spec:
  tls:
  - secretName: dpl-identity
  rules:
  - http:
      paths:
        - path: /api/identity/*
          backend:
            serviceName: dpl-identity
            servicePort: 4000
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: dpl-staging
  name: dpl-identity
  labels:
    app: dpl-identity
spec:
  replicas: 2
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: dpl-identity
    spec:
      containers:
      - image: gcr.io/munpat-container-engine/dpl/identity:0.4.9
        name: dpl-identity
        ports:
        - containerPort: 8000
          name: http
        volumeMounts:
        - name: dpl-identity
          mountPath: /data
      volumes:
      - name: dpl-identity
        secret:
          secretName: dpl-identity
13
Moon

Ihr Backend k8s-be-32396--5fc40252fadea594 wird als "UNHEALTHY" angezeigt.

Ingress leitet keinen Datenverkehr weiter, wenn das Backend UNHEALTHY ist. Dies führt zu dem 502-Fehler, den Sie sehen.

Es wird als UNHEALTHY gekennzeichnet, da es den Health-Check nicht besteht. Sie können die Health-Check-Einstellung für k8s-be-32396--5fc40252fadea594 überprüfen, um zu sehen, ob sie für Ihren Pod geeignet sind. Möglicherweise wird eine URI oder ein Port abgefragt das ist keine 200 Antwort. Sie finden diese Einstellungen unter Compute Engine> Health Checks.

Wenn sie richtig sind, gibt es viele Schritte zwischen Ihrem Browser und dem Container, die möglicherweise Verkehr falsch passieren. Versuchen Sie kubectl exec -it PODID -- bash (oder ash, wenn Sie Alpine verwenden). Versuchen Sie dann, localhost zu scrollen, um zu sehen, ob der Container als antwortet Wenn dies der Fall ist und die Integritätsprüfungen auch richtig konfiguriert sind, würde dies das Problem wahrscheinlich auf den Dienst einschränken. Sie könnten dann versuchen, den Dienst von einem NodePort-Typ in einen LoadBalancer zu ändern und zu sehen, ob die Service-IP direkt von dort aus getroffen wird Ihr Browser funktioniert.

23
Simon I

Ich hatte das gleiche Problem, und es blieb bestehen, nachdem ich livenessProbe sowie readinessPorbe..__ aktiviert hatte. Es stellte sich heraus, dass dies mit grundlegender auth zu tun hatte. Ich habe grundlegende Auth zu livenessProbe und der readinessPorbe hinzugefügt, aber es stellt sich heraus, dass der GCE HTTP (S) Load Balancer keine Konfigurationsoption dafür hat.

Es scheint auch ein paar andere Probleme zu geben, z. Das Festlegen des Container-Ports auf 8080 und des Service-Ports auf 80 funktionierte nicht mit dem GKE-Ingress-Controller (dennoch würde ich nicht klar sagen, was das Problem war). Im Großen und Ganzen sieht es so aus, als wäre die Sichtbarkeit sehr gering, und das Ausführen eines eigenen Ingress-Containers ist hinsichtlich der Sichtbarkeit eine bessere Option.

Ich habe Traefik für mein Projekt ausgewählt, es hat sich sofort bewährt, und ich möchte die Integration von Let's Encrypt aktivieren. Die einzige Änderung, die ich an Traefik-Manifesten vornehmen musste, bestand darin, das Service-Objekt so zu optimieren, dass der Zugriff auf die Benutzeroberfläche von außerhalb des Clusters deaktiviert und meine App über einen externen Load-Balancer (GCE TCP LB) verfügbar gemacht wurde. Außerdem ist Traefik eher in Kubernetes beheimatet. Ich habe Heptio Contour ausprobiert, aber etwas funktionierte nicht aus der Box (wird es nächstes Mal versuchen, wenn die neue Version herauskommt).

1
errordeveloper

Der "Limitations" Abschnitt der kubernetes-Dokumentation besagt Folgendes:

Alle Kubernetes-Services müssen eine 200-Seite für '/' oder den von GLBC angegebenen --health-check-path argument-Wert bereitstellen.

https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/cluster-loadbalancing/glbc#limitations

0
morgane1806

Ich hatte das gleiche Problem. Es stellte sich heraus, dass ich vor dem Eintritt einige Minuten warten musste, um die Funktionsfähigkeit des Dienstes zu überprüfen. Wenn jemand dasselbe ausführt und alle Schritte wie readinessProbe und linvenessProbe ausführt, stellen Sie sicher, dass Ihr Eindringling auf einen Dienst verweist, der entweder eine NodePort ist, und warten Sie einige Minuten, bis das gelbe Warnsymbol grün wird. Überprüfen Sie auch das Protokoll auf StackDriver, um eine bessere Vorstellung von den Vorgängen zu erhalten. Meine readinessProbe und livenessProbe befindet sich in /login für die gce-Klasse. Ich glaube nicht, dass es auf /healthz sein muss.

0
Mauricio

Ich habe das Problem durch gelöst

  1. Entfernen Sie den Dienst aus der Eingangsdefinition
  2. Ingress bereitstellen kubectl apply -f ingress.yaml
  3. Fügen Sie den Service der Ingress-Definition hinzu
  4. Stellen Sie ingress erneut bereit

Im Wesentlichen folgte ich Roys Rat und versuchte, es wieder ein- und auszuschalten.

0

Das Problem ist in der Tat eine Integritätsprüfung und schien für meine Apps "zufällig" zu sein, bei der ich namenbasierte virtuelle Hosts verwendete, um Proxy-Anforderungen vom Eingang über Domänen zu zwei separaten Backend-Services umzukehren. Beide wurden mit Lets Encrypt und kube-lego gesichert. Meine Lösung bestand darin, den Pfad für Zustandsprüfungen für alle Dienste, die einen Ingress gemeinsam nutzen, zu standardisieren und die Konfigs readinessProbe und livenessProbe in meiner deployment.yml-Datei zu deklarieren.

Ich habe dieses Problem mit der Google Cloud-Clusterknotenversion 1.7.8 konfrontiert und fand dieses Problem, das dem ähnelt, was ich erlebt habe: * https://github.com/jetstack/kube-lego/issues/27

Ich verwende gce und kube-lego und meine Backend-Service-Integritätsprüfungen waren auf / und kube-lego auf /healthz. Es scheint, dass unterschiedliche Pfade für die Funktionsprüfung mit gce ingress die Ursache sind. Daher kann es sich lohnen, die Backend-Services entsprechend dem /healthz-Muster zu aktualisieren, damit alle dasselbe verwenden (oder als Kommentator in der Github-Ausgabe angegeben, dass sie kube-lego aktualisiert haben, um / weiterzugeben).

0
Mike S.