Başka bir ad alanında bulunan hizmet


109

Bir ad alanında başka bir ad alanında çalışan bir Kapsüle bağlanan bir hizmet tanımlamanın bir yolunu bulmaya çalışıyordum. İçinde çalışan bir Kapsüldeki kapsayıcıların , küme DNS'sinde olarak başvurarak tanımlanmış namespaceAerişime sahip olduğunu biliyorum, ancak kapsayıcının konumu hakkında bilgi sahibi olması gereken kapsayıcı içindeki koda sahip olmamayı tercih ederim . Yani, kodun sadece aramasını ve sonra ona erişebilmesini istiyorum.serviceXnamespaceBserviceX.namespaceB.svc.cluster.localserviceXserviceX

Kubernetes belgeleri bu mümkün olduğunu göstermektedir. Seçici olmadan bir hizmeti tanımlamanızın nedenlerinden birinin, hizmetinizi başka bir Ad Alanındaki veya başka bir kümedeki bir hizmete yönlendirmek istemeniz olduğunu söylüyor .

Bu bana şunu yapmam gerektiğini gösteriyor:

  1. Seçici olmadan serviceXiçinde bir hizmet tanımlayın namespaceA(çünkü seçmek istediğim POD içinde değil namespaceA).
  2. İçinde (benim de aradığım serviceX) bir hizmet tanımlayın namespaceBve sonra
  3. Bir Endpoints nesneyi tanımlama namespaceAiçin noktaya serviceXiçinde namespaceB.

Başaramadığım bu üçüncü adım.

İlk olarak, Endpoints nesnesini şu şekilde tanımlamayı denedim:

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

Bu mantıklı bir yaklaşım gibi görünüyordu ve açıkçası bunun targetRefiçindi. Ancak bu ip, addressesdizideki alanın zorunlu olduğunu söyleyen bir hataya yol açtı . Yani, bir sonraki deneme için sabit ClusterIP adresi atamak oldu serviceXyılında namespaceBve IP alanında koymak (O notu service_cluster_ip_rangeolarak yapılandırılır 192.168.0.0/16ve 192.168.1.1için ClusterIP olarak atandı serviceXiçinde namespaceB; serviceXin namespaceAoto farklı bir ClusterIP atandı 192.168.0.0/16alt) :

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

Yani kabul edildi ancak bunlarla erişimler serviceXde namespaceAiçinde Pod iletilir alamadım namespaceB- onlar zaman aşımına uğradı. İptables kurulumuna bakıldığında, bunu başarmak için iki kez NAT ön-yönlendirme yapması gerekecekmiş gibi görünüyor.

Ama tatmin edici bir çözüm değildir - - çalıştığım find fonksiyonu tek şey sağlayan Pod gerçek IP adresi arama olduğu serviceXiçinde namespaceBve Endpoints nesnede bu adresi koymak namespaceA. Elbette bu tatmin edici değildir çünkü Pod IP adresi zamanla değişebilir. Bu, hizmet IP'lerinin çözülmesi gereken sorun.

Öyleyse, bir ad alanındaki bir hizmeti farklı bir ad alanında çalışan bir hizmete yönlendirebileceğime dair belgelerin vaadini karşılamanın bir yolu var mı?

Bir yorumcu neden bunu yapmak isteyeceğinizi sorguladı - işte bana mantıklı gelen bir kullanım örneği, en azından:

Kiracılar arasında paylaşılabilen ortak bir veri erişim işlevi de içeren çok kiracılı bir sisteminiz olduğunu varsayalım. Şimdi, bu veri erişim işlevinin ortak API'lere sahip farklı türleri olduğunu, ancak farklı performans özellikleri olduğunu hayal edin. Bazı kiracılar bunlardan birine erişebilir, diğer kiracılar bir diğerine erişebilir.

Her kiracının bölmeleri kendi ad alanlarında çalışır, ancak her birinin bu ortak veri erişim hizmetlerinden birine erişmesi gerekir; bu, zorunlu olarak başka bir ad alanında olacaktır (çünkü birden çok kiracı tarafından erişilir). Ancak, kiracının daha yüksek performanslı hizmete erişmek için aboneliği değişirse kodunu değiştirmek zorunda kalmasını istemezsiniz.

Potansiyel bir çözüm (eğer işe yaradıysa düşünebildiğim en temiz çözüm), her bir kiracının veri erişim hizmeti için ad alanına, her biri uygun uç nokta için yapılandırılmış bir hizmet tanımı eklemektir. Bu hizmet tanımı, her bir kiracının kullanma hakkına sahip olduğu uygun veri erişim hizmetine işaret edecek şekilde yapılandırılacaktır.


ad alanlarının amacı izole etmektir, bu yüzden ad alanlarından geçmeniz gerekiyorsa, en azından nerede olduğunu bilmeniz gerektiğini düşünüyorum!
MrE

Öyleyse, bir ad alanında tanımlanmış bir hizmeti, bir seçici tanımlamadan ve dolaylı olarak bir uç nokta tanımlayarak farklı bir ad alanındaki bir hizmete erişmeye yönlendirebileceğinizi önerdiğinde, dokümantasyon ne anlama geliyor? Bunun için kesinlikle geçerli kullanım durumları var - bunlardan birini soruya ekledim. Belgeler yanıltıcı mı yoksa bunu yapmanın henüz anlamadığım bir yolu var mı?
David McKinley

emin değilim üzgünüm Bildiğim şey, fqdn'lerini kullanarak birden çok ad alanındaki hizmetlere eriştiğim. Bunu özellikle vpn ile yapıyorum, çünkü 1 vpn podum var ve ondan tüm servisler üzerinden bağlanıyorum. ancak ad alanını bilmeniz ve fqdn sağlamanız gerekir. gevşek kanalda sormanızı öneririm.
MrE

Şu anda kullandığım çözüm fqdn kullanmaktır. Yine de, gerekli olmasaydı benim kullanım durumum (şimdi soruya eklendi) daha iyi sunulacaktı.
David McKinley

Belgelerin de neye atıfta bulunduğunu merak ediyorum, ancak fqdn'yi kullanım durumum için tatmin edici bir çözüm olarak kullanabilirim.
Vincent De Smet

Yanıtlar:


225

Aynı sorunla karşılaştım ve statik ip yapılandırmasına ihtiyaç duymayan güzel bir çözüm buldum:

Bir hizmete DNS adı aracılığıyla erişebilirsiniz (sizin belirttiğiniz gibi): hizmetadı.namespace.svc.cluster.local

Bu DNS adını yerel bir hizmet aracılığıyla başka bir ad alanında başvurmak için kullanabilirsiniz :

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

2
Bu harika bir çözüm! Soruyu ilk sorduğumda "ExternalName" türünün hizmetler için mevcut olup olmadığından emin değilim, ancak şu anda destekleniyor ve sorunu düzgün bir şekilde çözüyor. Teşekkürler Paul.
David McKinley

1
Bu çalışıyor mu? şüpheliyim. Bunun gerçekten işe yarayıp yaramadığını herkes onaylayabilir mi, benim için çalışmıyor
debianmaster

2
Evet öyle. Bir kapsülün başka bir ad alanındaki bir hizmetle konuşması için çalışır, ancak bir giriş yük dengeleyicisi için geçerli değildir.
Paul

kubernetes küme içi CNAME aramasını düzeltmesi nedeniyle eski sürüm çalışmayabilir.
赵浩翔

1
Bu, kube-sistem ad alanındaki hizmetler için de çalışır mı / çalışmalı mı?
Nabheet

10

Bunu yapmak çok basit

ev sahibi olarak kullanmak ve çözmek istiyorsanız

Başka bir ad alanında bulunan hizmet için başka herhangi bir API ağ geçidine yönelik büyükelçiyi kullanıyorsanız, her zaman kullanmanız önerilir:

            Use : <service name>
            Use : <service.name>.<namespace name>
            Not : <service.name>.<namespace name>.svc.cluster.local

şöyle olacak: servicename.namespacename.svc.cluster.local

bu, bahsettiğiniz ad alanı içindeki belirli bir hizmete istek gönderecektir.

misal:

kind: Service
apiVersion: v1
metadata:
  name: service
spec:
  type: ExternalName
  externalName: <servicename>.<namespace>.svc.cluster.local

İşte değiştirmek <servicename>ve <namespace>uygun değerle.

Kubernetes'te, ad alanları sanal ortam oluşturmak için kullanılır ancak tümü birbirine bağlıdır.


6
Bu yanıtın Paul'ün yaklaşık 2 yıl önce verdiği yanıttan ne kadar farklı olduğunu açıklayabilir misiniz?
Oliver

2
@Oliver bir fark yok, ancak hizmet adını ve ad alanını hangi belirli yerde değiştireceğimi belirttim. o ad alanını kullanırken-a bu yüzden kafa karıştırıcı görünüyor.
Sert Manvar

7
SO'da kullanışlı bir numara, cevaba bir yorum eklemek ve gerekli açıklamayı yapmaktır.
Oliver

4
Bunu en iyi çözüm olarak adlandırırım çünkü .svc.cluster.localhizmeti dahili olarak çözmek için varsayılan olarak desteklenir.
DrKNa

1
benim için de uyandı. teşekkür ederim
vimal prakash

0

Bunu, hizmet yük dengeleyici gibi, ad alanlı Hizmetlerden daha yüksek bir katmanda dağıtarak başarabilirsiniz. https://github.com/kubernetes/contrib/tree/master/service-loadbalancer . Bunu tek bir ad alanıyla sınırlandırmak istiyorsanız, "--namespace = ns" bağımsız değişkenini kullanın (varsayılan olarak tüm ad alanları içindir: https://github.com/kubernetes/contrib/blob/master/service-loadbalancer/service_loadbalancer.go # L715 ). Bu, L7 için iyi çalışıyor, ancak L4 için biraz dağınık.


3
Bu proje artık kullanımdan kaldırıldı (ağustos 2018)
Nicola Ben

1
@ Prashanth B: Cevabınızı buna göre güncelleyebilir misiniz?
chaosguru
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.