2016-05-14 9 views
15

Próbuję znaleźć sposób zdefiniowania usługi w jednej przestrzeni nazw, która łączy się z działem działającym w innym obszarze nazw. Wiem, że kontenery w podsiebie działającej w "namespaceA" mogą uzyskać dostęp do "serviceX" zdefiniowanego w "namespaceB" przez odniesienie go w DNS klastra jako "serviceX.namespaceB.svc.cluster.local", ale wolałbym nie mieć kodu wewnątrz kontenera trzeba wiedzieć o lokalizacji "serviceX". To znaczy, chcę, aby kod po prostu sprawdzał "serviceX", a następnie był w stanie uzyskać do niego dostęp.kubernetes: Usługa znajdująca się w innej przestrzeni nazw

The Kubernetes documentation sugeruje, że jest to możliwe. Mówi, że jednym z powodów, dla których zdefiniowałbyś usługę bez selektora, jest "Chcesz skierować swoją usługę do usługi w innym obszarze nazw lub w innym klastrze."

Sugeruje mi się, że powinien:

  1. Zdefiniuj „serviceX” usługę w „namespaceA”, bez selektora (ponieważ POD Chcę wybrać nie jest w „namespaceA”).
  2. Zdefiniuj usługę (którą również nazwałem "serviceX") w "namespaceB", a następnie
  3. Zdefiniuj obiekt Endpoints w "namespaceA", aby wskazać "serviceX" w "namespaceB".

Jest to trzeci krok, którego nie mogłem wykonać.

Najpierw próbowałem definiowanie punktów końcowych sprzeciw ten sposób:

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 

które wydawały się logiczne podejście, a „oczywiście” co „targetRef” był za. Doprowadziło to jednak do błędu mówiącego, że pole "ip" w tablicy "adresy" było obowiązkowe. Tak więc, moją kolejną próbą było przypisanie stałego adresu ClusterIP do "serviceX" w "namespaceB" i umieszczenie go w polu IP (zauważ, że service_cluster_ip_range jest skonfigurowany jako 192.168.0.0/16, a 192.168.1.1 został przypisany jako ClusterIP dla "serviceX" w "namespaceB", "serviceX" w "namespaceA" został przydzielony inny auto ClusterIP na 192.168.0.0/16 podsieci):

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 

to zostało przyjęte, ale dostęp do "serviceX" w "namespaceA" nie został przekazany do kapsuły w "namespaceB" - upłynął limit czasu. Patrząc na konfigurację iptables, wygląda na to, że musiałoby wykonać dwukrotnie wstępne trasowanie NAT, aby to osiągnąć.

Jedyną rzeczą, którą udało mi się znaleźć, która działała - ale nie jest zadowalającym rozwiązaniem - jest wyszukanie rzeczywistego adresu IP Pod podajnika "serviceX" w "namespaceB" i umieszczenie tego adresu w obiekcie Endpoints w "namespaceA" . Oczywiście nie jest to satysfakcjonujące, ponieważ adres IP Pod może zmieniać się z czasem. To jest problem, który adresy IP usługi są do rozwiązania.

Czy istnieje sposób, aby spełnić obietnicę dokumentacji, że mogę wskazać usługę w jednej przestrzeni nazw na usługę działającą w innym obszarze nazw?

commenter wątpliwość dlaczego chcesz to zrobić - o to przypadek użycia, który ma sens dla mnie, co najmniej:

Say masz system multi-tenant, który obejmuje również wspólne dostępu do danych funkcja, która może być dzielona między lokatorów. Teraz wyobraź sobie, że istnieją różne smaki tej funkcji dostępu do danych z typowymi interfejsami API, ale różnią się charakterystyką wydajności. Niektórzy lokatorzy mają dostęp do jednego z nich, inni lokatorzy mają dostęp do drugiego.

Każda kapsuła lokatora działa we własnej przestrzeni nazw, ale każda z nich musi uzyskać dostęp do jednej z tych powszechnych usług dostępu do danych, które z konieczności będą znajdować się w innym obszarze nazw (ponieważ dostęp do niej ma wielu najemców). Ale nie chciałbyś, aby najemca musiał zmienić kod, jeśli jego subskrypcja zmieni się, aby uzyskać dostęp do usługi o wyższej wydajności.

Potencjalne rozwiązanie (najczystsze, o jakim mogę myśleć, jeśli tylko zadziałało) to włączenie definicji usługi do przestrzeni nazw każdego lokatora dla usługi dostępu do danych, z których każdy jest skonfigurowany dla odpowiedniego punktu końcowego. Ta definicja usługi będzie skonfigurowana tak, aby wskazywała na właściwą usługę dostępu do danych, z której może korzystać każdy lokator.

+0

nie spróbować użyć fullqualified nazwy domeny dla usługi, jak „service.namespace.s vc.cluster.local ' – MrE

+0

Tak, jak wspomniano w pytaniu, to działa dobrze. Ale celem jest, aby kod w kontenerze nie musiał znać przestrzeni nazw, w której usługa jest faktycznie ładowana. –

+0

Punktem przestrzeni nazw jest izolacja, więc myślę, że jeśli chcesz przejść przez przestrzenie nazw, musisz przynajmniej wiedzieć, gdzie się znajduje! – MrE

Odpowiedz

25

Natknąłem się na ten sam problem i znaleźć rozwiązanie, które miło nie potrzeba żadnej konfiguracji statycznego IP:

można uzyskać dostęp do usługi poprzez to DNS name (jak wspomniany przez ciebie): servicename.namespace.svc. cluster.local

Możesz użyć tej nazwy DNS, aby odwoływać się do niej w another namespace via a local service:

kind: Service 
apiVersion: v1 
metadata: 
    name: service-y 
    namespace: namespace-a 
spec: 
    type: ExternalName 
    externalName: service-x.namespace-b.svc.cluster.local 
    ports: 
    - port: 80 
+1

To świetne rozwiązanie! Nie jestem pewien, czy typ "ExternalName" był dostępny dla usług, gdy pierwotnie zadałem pytanie, ale jest teraz obsługiwany i starannie rozwiązuje problem. Dzięki, Paul. –

+0

Czy to działa? wątpię. Czy ktoś może potwierdzić, czy to naprawdę działa, nie działa dla mnie. – debianmaster

+0

Tak, to prawda. Działa na jednym strączku, aby porozmawiać z usługą w innym obszarze nazw, ale nie dla mechanizmu równoważenia obciążenia. – Paul

2

Można to osiągnąć, wdrażając coś na wyższej warstwie niż usługi o podziale nazw, takie jak usługa loadbalancer https://github.com/kubernetes/contrib/tree/master/service-loadbalancer. Jeśli chcesz ograniczyć go do pojedynczego obszaru nazw, użyj argumentu "--namespace = ns" (domyślnie jest to wszystkie przestrzenie nazw: https://github.com/kubernetes/contrib/blob/master/service-loadbalancer/service_loadbalancer.go#L715). Działa to dobrze na L7, ale jest trochę brudny dla L4.

Powiązane problemy