2017-07-18 2 views
2

Für die lokale Entwicklung habe ich einen funktionierenden Minikubus. Dort haben wir verschiedene Dienste im Einsatz. Jetzt möchte ich das Frontend mit dem Backend verbinden.Kubernetes Kommunikation zwischen Frontend und Backend

Das Frontend ist eine Winkelanwendung und lebt in einem eigenen Dienst. Das Backend ist eine node.js-Anwendung, die ebenfalls einen separaten Dienst verwendet und DNS verwendet, um eine Verbindung zu anderen internen Diensten wie mongodb herzustellen.

Jetzt möchte ich vom Frontend mit dem Backend kommunizieren. DNS funktioniert nicht, da das Frontend nicht weiß, wie die angegebene Route zu lösen ist. Das Problem besteht darin, dem Frontend mitzuteilen, an welche Back-End-URL und an welchen Port es Anfragen senden soll.

Der einzige funktionierende Zustand wurde angegangen, als ich den Backend-Dienst mit dem Typ NodePort zum ersten Mal gestartet und die URL und den Port auf die Frontends-Ziel-URL kopiert habe. Ich denke, das ist sehr unrein für mich. Gibt es einen anderen Ansatz, um die URL für Backend-Anfragen in das Frontend zu bekommen?

Ich weiß, wenn wir einen Dienst auf einem Produktionssystem mit Type = "LoadBalancer" bereitstellen, dass der Dienst durch eine externe IP verfügbar gemacht wird und ich von dort auf den Dienst zugreifen kann. Und dass die externe IP bei Pod-Aktualisierungen und so weiter permanent ist. Das Problem, das ich auch sehe, ist, dass die Backend-IP durch einen zusätzlichen Commit in den Andock-Container eingefügt werden muss.

Edit (1): Der Backend-Service

apiVersion: v1 
kind: Service 
metadata: 
    name: backend 
    labels: 
    app: some-app 
    tier: backend 
spec: 
    type: NodePort 
    ports: 
    - port: 3000 
    selector: 
    app: some-app 
    tier: backend 

Edit (2): Ich bekomme auch diese Antwort, wenn ich vom Client mit einem fqn anfordern:

OPTIONS http://backend.default.svc.cluster.local:3000/signup/ net::ERR_NAME_NOT_RESOLVED 
+0

haben Sie setzen Sie mit einem Service-Backend? Wenn ja, sollten Sie die Ports in der Service-Definition definiert haben und Sie sollten DNS-Auflösung für sagen http: // Backend: 80/

+0

@SebastienGoasguen Ich habe die Backend-Service-Definition hinzugefügt. Also habe ich Port 3000 für das Backend definiert und es ist auch nicht erreichbar. Ich denke, die eckige Anwendung weiß nicht, wie man den DNS-Namen "Backend" auflöst. – Lunero

+0

können Sie versuchen, mit FQN wie folgt 'backend.default.svc.cluster.local'. Möglicherweise müssen Sie den Standardwert durch Ihren Namensbereich ersetzen. – sfgroups

Antwort

3

Es hängt davon ab.

Sie leiten alle Back-End-Anrufe über Ihren Front-End-Server oder Angular (im Browser des Benutzers) direkt auf Ihr echtes Back-End? Verwenden Sie irgendwelche Muster wie API-Gateway?

Wenn Sie alle Ihre Microservices/Backend-Anrufe durch die Server-Seite Ihres Front-Ends routen (oder bereit sind, diese zu routen) und wenn Sie sowohl Ihr Front-End als auch Ihr Backend im selben K8s-Cluster im selben Namespace bereitstellen Sie können das KubeDNS-Add-On (falls es in Ihrem k8s-Cluster noch nicht verfügbar ist, können Sie mit dem k8s-Administrator nachfragen), um den Backend-Dienstnamen in seine IP-Adresse aufzulösen. Von Ihrem Front-End-Server wird Ihr Back-End-Dienst immer durch seinen Namen auflösbar sein.

Nur neugierig- Was dient Ihrem Front-End (welche Server-Technologie liefert Ihre index.html zu Benutzer-Browser)? ist es statische Server wie Nginx oder Apache httpd oder verwenden Sie NodeJs hier?

bearbeiten

Eine Lösung: Da Sie kubeDNS in Ihrem K8S Cluster und die beiden Front-End und Back-End-Dienste befindet sich in derselben K8S Cluster und gleichen Namensraum haben, können wir den Einsatz von K8S' integrierte Service-Discovery-Mechanismus machen; Der Back-End-Dienst und der Front-End-Dienst sollten sich gegenseitig anhand des Namens erkennen können. Das heißt, Sie können einfach den DNS-Namen "Backend" verwenden, um Ihren Backend-Service von Ihren Frontend-Pods zu erreichen. Probieren Sie also einfach alle Backend-Anfragen über Ihr Front-End-Nginx an Ihren Upstream-Backend-Service aus. In den Frontend-Nginx-Pods ist die IP des Backend-Dienstes für den Domainnamen "Backend" auflösbar. Das erspart Ihnen auch den CORS-Kopfschmerz. Dieses Setup ist portabel, dh es spielt keine Rolle, ob Sie es in einem Dev- oder Stage- oder Prod-System bereitstellen, der Name "Backend" wird immer in das entsprechende Backend aufgelöst.

Ein potenzieller Nachteil dieses Ansatzes ist, dass Ihr Backend möglicherweise nicht in der Lage ist, unabhängig vom Frontend zu skalieren. Was meiner bescheidenen Meinung nach keine große Sache ist; In einer k8s-Umgebung ist es nur eine Frage von mehr Pods, wenn nötig.

+0

Entschuldigung, ich habe nicht erwähnt, dass es momentan einen Nginx-Dienst gibt, der das Backend und Frontend behandelt. Also mein Backend, Frontend und Nginx sind im selben Namespace. Und Kubedns ist auch definiert. – Lunero

+0

Keine Sorge. Es ist also sehr einfach für Sie, die gesamte Backend-Anfrage über Ihr Front-End-Nginx an Ihren Upstream-Backend-Service zu übertragen. Im Frontend nginx ist die IP des Backend-Dienstes für den Domain-Namen "backend" auflösbar.Das erspart Ihnen auch den CORS-Kopfschmerz. Dieses Setup ist portabel, dh es spielt keine Rolle, ob Sie es in einem Dev- oder Stage- oder Prod-System bereitstellen, der Name "Backend" wird immer in das entsprechende Backend aufgelöst. –

+0

Danke das hat sehr geholfen. In Kombination mit der Antwort von Marc Sluiter habe ich es zur Arbeit gebracht. Danke im Voraus. – Lunero

0

Ich würde sugest mit Kubernetes eigene Art der flexiblen Taffic-Aufnahme mit Ingress/IngressController. Havin Ingress-Controller in Ihrem Cluster bereitgestellt, können Sie leicht erstellen Ingress-Definition den Controller zu erklären, Service unter bestimmten URL verfügbar machen. Alles, was Sie dann tun müssen, ist diesen Namen in DNS auf den Loadbalancer von Ingress Controllers zu zeigen (in den meisten Cloud-Setups, die mit einem CNAME zu dem LB-FQDN gehören).

https://kubernetes.io/docs/concepts/services-networking/ingress/ https://github.com/kubernetes/ingress

2

Wir verwenden einen anderen Ansatz als in der Antwort von so-random-dude (was eine nette Lösung): wir lassen den Backend-Server die Frontend-Dateien bedienen. Wir haben Docker Images für beide getrennt, aber nur 1 Pod. Das Frontend wird als Init-Container ausgeführt und kopiert die Dateien in ein leeres Volume. Das Back-End hängt dieses Volume ebenfalls an und stellt es unter / bereit (alle Back-End-Ressourcen werden auf anderen Pfaden bereitgestellt). Auf diese Weise werden das Frontend und das Backend auf demselben Host bedient.

Sie können den aktuellen Host (der jetzt auch der Backend-Host ist) im Angular-Code mit window.location.protocol + '//' + window.location.host abrufen.

Während der Entwicklung auf der lokalen Dev-Maschine betreiben wir das Frontend und Backend auf eigenen Servern. So haben wir eine kleine Hilfsfunktion für das Erhalten der korrekten URL im Backend in allen Fällen:

public getBackendUrl(): string { 
    return this.getBackendUrlInternal(window.location.protocol, window.location.host); 
} 

private getBackendUrlInternal(protocol: string, host: string): string { 
    if (host === 'localhost:3000') { 
    // running in local dev server, connect to local dev backend 
    return 'http://localhost:8585'; 
    } else { 
    // running in docker compose or on k8s, backend is on same host and port as we are 
    return protocol + '//' + host; 
    } 
} 

(Es sind 2 Methoden, weil wir einige Tests für die 2. eine haben)

Verwandte Themen