Ich habe versucht, einen Weg zu finden, um einen Dienst in einem Namespace zu definieren, der mit einem Pod verknüpft ist, der in einem anderen Namespace ausgeführt wird. Ich weiß, dass Container in einem Pod, in dem ausgeführt wird, namespaceA
auf serviceX
definierten Zugriff zugreifen können , namespaceB
indem sie im Cluster-DNS als referenziert werden serviceX.namespaceB.svc.cluster.local
, aber ich möchte lieber nicht, dass der Code im Container über den Speicherort von informiert wird serviceX
. Das heißt, ich möchte, dass der Code nur nachschlägt serviceX
und dann darauf zugreifen kann.
Die Kubernetes-Dokumentation legt nahe, dass dies möglich ist. Einer der Gründe, warum Sie einen Dienst ohne Selektor definieren würden, besteht darin, dass Sie Ihren Dienst auf einen Dienst in einem anderen Namespace oder in einem anderen Cluster verweisen möchten .
Das legt mir nahe, dass ich:
- Definieren Sie einen
serviceX
Dienst innamespaceA
ohne Selektor (da der POD, den ich auswählen möchte, nicht in istnamespaceA
). - Definieren Sie einen Dienst (den ich auch angerufen habe
serviceX
) innamespaceB
und dann - Definieren Sie ein Endpunktobjekt
namespaceA
, auf dasserviceX
in gezeigt werden sollnamespaceB
.
Es ist dieser dritte Schritt, den ich nicht ausführen konnte.
Zuerst habe ich versucht, das Endpunktobjekt folgendermaßen zu definieren:
kind: Endpoints
apiVersion: v1
metadata:
name: serviceX
namespace: namespaceA
subsets:
- addresses:
- targetRef:
kind: Service
namespace: namespaceB
name: serviceX
apiVersion: v1
ports:
- name: http
port: 3000
Das schien der logische Ansatz zu sein und offensichtlich, wofür das targetRef
war. Dies führte jedoch zu einem Fehler, der besagte, dass das ip
Feld im addresses
Array obligatorisch war. Also, mein nächster Versuch war eine feste ClusterIP Adresse zuweisen serviceX
in namespaceB
und umsetzen , die in dem IP - Feld (beachten Sie, dass das service_cluster_ip_range
so konfiguriert ist 192.168.0.0/16
, und 192.168.1.1
wurde als ClusterIP für zugewiesen serviceX
in namespaceB
, serviceX
in namespaceA
wurde automatisch einen anderen ClusterIP auf dem zugewiesenen 192.168.0.0/16
Subnetz) ::
kind: Endpoints
apiVersion: v1
metadata:
name: serviceX
namespace: namespaceA
subsets:
- addresses:
- ip: 192.168.1.1
targetRef:
kind: Service
namespace: namespaceB
name: serviceX
apiVersion: v1
ports:
- name: http
port: 3000
Das wurde akzeptiert, aber die Zugriffe auf serviceX
in namespaceA
wurden nicht an den Pod in weitergeleitet namespaceB
- sie haben eine Zeitüberschreitung. Wenn man sich das iptables-Setup ansieht, sieht es so aus, als hätte es zweimal NAT-Pre-Routing durchführen müssen, um dies zu erreichen.
Das einzige , was ich gefunden haben , das funktionierte - aber keine befriedigende Lösung - ist die tatsächliche IP - Adresse der Pod Bereitstellung Nachschlag serviceX
in namespaceB
und diese Adresse in dem Endpoints Objekt setzen namespaceA
. Das ist natürlich nicht zufriedenstellend, da sich die Pod-IP-Adresse im Laufe der Zeit ändern kann. Das ist das Problem, das Service-IPs lösen müssen.
Gibt es also eine Möglichkeit, das Versprechen der Dokumentation zu erfüllen, dass ich einen Dienst in einem Namespace auf einen Dienst verweisen kann , der in einem anderen Namespace ausgeführt wird?
Ein Kommentator fragte, warum Sie dies tun möchten - hier ist ein Anwendungsfall, der zumindest für mich sinnvoll ist:
Angenommen, Sie haben ein System mit mehreren Mandanten, das auch eine gemeinsame Datenzugriffsfunktion enthält, die von Mandanten gemeinsam genutzt werden kann. Stellen Sie sich nun vor, dass es verschiedene Varianten dieser Datenzugriffsfunktion mit gemeinsamen APIs gibt, aber unterschiedliche Leistungsmerkmale. Einige Mieter erhalten Zugang zu einem von ihnen, andere Mieter haben Zugang zu einem anderen.
Die Pods jedes Mandanten werden in seinen eigenen Namespaces ausgeführt, aber jeder muss auf einen dieser allgemeinen Datenzugriffsdienste zugreifen, die sich notwendigerweise in einem anderen Namespace befinden (da mehrere Mandanten darauf zugreifen). Sie möchten jedoch nicht, dass der Mandant seinen Code ändern muss, wenn sich sein Abonnement ändert, um auf den leistungsstärkeren Dienst zuzugreifen.
Eine mögliche Lösung (die sauberste, die ich mir vorstellen kann, wenn sie nur funktioniert) besteht darin, eine Dienstdefinition in den Namespace jedes Mandanten für den Datenzugriffsdienst aufzunehmen, wobei jede für den entsprechenden Endpunkt konfiguriert ist. Diese Dienstdefinition würde so konfiguriert, dass sie auf den richtigen Datenzugriffsdienst verweist, zu dessen Nutzung jeder Mandant berechtigt ist.
quelle
Antworten:
Ich bin über das gleiche Problem gestolpert und habe eine nette Lösung gefunden, die keine statische IP-Konfiguration benötigt:
Sie können über den DNS-Namen (wie von Ihnen angegeben) auf einen Dienst zugreifen : servicename.namespace.svc.cluster.local
Sie können diesen DNS-Namen verwenden, um ihn über einen lokalen Dienst in einem anderen Namespace zu referenzieren :
quelle
Es ist so einfach, es zu tun
Wenn Sie es als Host verwenden und auflösen möchten
Wenn Sie Ambassador für ein anderes API-Gateway für Dienste verwenden, die sich in einem anderen Namespace befinden, wird immer Folgendes empfohlen:
es wird sein wie:
servicename.namespacename.svc.cluster.local
Dadurch wird eine Anfrage an einen bestimmten Dienst innerhalb des von Ihnen erwähnten Namespace gesendet.
Beispiel:
Hier ersetzen Sie das
<servicename>
und<namespace>
durch den entsprechenden Wert.In Kubernetes werden Namespaces verwendet, um eine virtuelle Umgebung zu erstellen, aber alle sind miteinander verbunden.
quelle
.svc.cluster.local
standardmäßig die interne Lösung des Dienstes unterstützt wird.Sie können dies erreichen, indem Sie etwas auf einer höheren Ebene als namespaced Services bereitstellen, z. B. den Service Loadbalancer https://github.com/kubernetes/contrib/tree/master/service-loadbalancer . Wenn Sie es auf einen einzelnen Namespace beschränken möchten, verwenden Sie das Argument "--namespace = ns" (standardmäßig alle Namespaces: https://github.com/kubernetes/contrib/blob/master/service-loadbalancer/service_loadbalancer.go) # L715 ). Dies funktioniert gut für L7, ist aber für L4 etwas chaotisch.
quelle