2016-05-14 2 views
15

ある名前空間に別の名前空間で動作するPodにリンクするサービスを定義する方法を見つけようとしています。 "namespaceA"で動作するPodのコンテナは、 "serviceX.namespaceB.svc.cluster.local"という名前でクラスタDNS内で参照することによって "namespaceB"で定義された "serviceX"にアクセスできますが、コードはありませんコンテナの内部では "serviceX"の位置を知る必要があります。つまり、コードでは単に "serviceX"を検索してアクセスできるようにします。kubernetes:別のネームスペースにあるサービス

Kubernetes documentationはこれが可能であることを示唆しています。セレクタなしでサービスを定義する理由の1つは、 "サービスを別のネームスペースまたは別のクラスタ内のサービスに指定することです。"私がすべきことを私に示唆

:(私は選択したいPODは「namespaceA」ではないので)

  1. セレクタせず、「namespaceA」の「serviceX」サービスを定義します。
  2. "namespaceB"でサービス( "serviceX"とも呼ばれる)を定義してから
  3. "namespaceA"のエンドポイントオブジェクトを定義して "namespaceB"の "serviceX"を指すようにします。

これは私が達成できなかった第3のステップです。 「targetRefは」のために何であったか、「明らかに」

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 

論理的なアプローチに見え、そして:

まず、私は、エンドポイントがこのようにオブジェクトを定義してみました。しかし、これは、 "アドレス"配列の "ip"フィールドが必須であるというエラーを引き起こしました。だから私の次の試みは、 "namespaceB"内の "serviceX"に固定されたClusterIPアドレスを割り当て、それをIPフィールドに置くことでした(service_cluster_ip_rangeは192.168.0.0/16として設定され、192.168.1.1は"namespaceB" における "serviceX" のCLUSTERIP; "namespaceA" における "serviceX")は192.168.0.0/16サブネット上の異なるCLUSTERIPを割り当て、自動であった:

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 

受け入れられたが、 "serviceX" へのアクセス"namespaceA"の "namespaceB"のポッドに転送されませんでした - タイムアウトしました。 iptablesの設定を見ると、それを達成するためにNATの事前ルーティングを2回行わなければならないようです。

"namespaceB"の "serviceX"を提供するPodの実際のIPアドレスを検索し、そのアドレスを "namespaceA"のEndpointsオブジェクトに置くだけで、満足のいく解決策ではありませんでした。 。もちろん、これは満足できるものではありません。なぜなら、PodのIPアドレスは時間とともに変化するからです。それは解決すべきサービスIPの問題です。

したがって、1つのネームスペースのサービスがサービスの別の名前空間で実行されていることを文書で証明できると思われるものを満たす方法はありますか?

コメンターはこれをしたいと思う理由を疑問視 - ここに私には理にかなっているユースケースは、少なくとも、次のとおりです。

はあなたにも共通のデータ・アクセスを含むマルチテナントシステムを、持っていると言いますテナント間で共有できる機能です。今度は、共通のAPIを持つこのデータアクセス関数のさまざまな味があるが、パフォーマンス特性は異なると想像してください。一部のテナントはその1つにアクセスし、他のテナントは別のテナントにアクセスします。

各テナントのポッドはそれぞれ独自の名前空間で動作しますが、それぞれが複数のテナントからアクセスされるため、必ずしも別の名前空間にある共通データアクセスサービスのいずれかにアクセスする必要があります。しかし、サブスクリプションが変更されて高性能サービスにアクセスする場合、テナントがコードを変更する必要はありません。

データアクセスサービスの各テナントのネームスペースに、適切なエンドポイント用に構成されたサービス定義を含めることが可能なソリューション(可能性のある最もクリーンなソリューション)です。このサービス定義は、各テナントが使用する資格を持つ適切なデータアクセスサービスを指すように構成されます。

+0

あなたはservice.namespace.s」のような、サービスのfullqualifiedドメイン名を使用してみましたvc.cluster.local ' – MrE

+0

はい、質問に記載されているようにうまくいきます。しかし、コンテナ内のコードは、サービスが実際にロードされている名前空間を知っている必要はありません。 –

+0

名前空間のポイントは隔離されているので、少なくとも名前空間がどこにあるのか知る必要がある場合は、それを考える必要があると思います! – MrE

答えて

25

私は同じ問題でつまずきと任意の静的IP設定を必要としない素敵な解決策が見つかりました:servicename.namespace.svc:それはDNS name(あなたが言及したよう)のヴィアあなたがサービスにアクセスすることができます

を。 cluster.local

あなたはanother namespace via a local serviceでそれを参照するためにそのDNS名を使用することができます。

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

これは素晴らしい解決策です!私は最初に質問したときに "ExternalName"タイプがサービスで利用可能かどうかはわかりませんが、今サポートされていて問題はきちんと解決されています。ありがとう、ポール。 –

+0

これは機能しますか?私は疑う。誰かがこれが本当にうまくいくかどうかを確認することができます、私のために働かない。 – debianmaster

+0

はい、あります。これは、1つのポッドで別の名前空間のサービスに話すのには効果がありますが、入力ロードバランサでは機能しません。 – Paul

2

これは、サービスロードバランサhttps://github.com/kubernetes/contrib/tree/master/service-loadbalancerのように、名前空間を持つサービスよりも上位の層に何かを配置することで実現できます。それを単一の名前空間に制限する場合は、 "--namespace = ns"引数を使用します(デフォルトでは、すべての名前空間:https://github.com/kubernetes/contrib/blob/master/service-loadbalancer/service_loadbalancer.go#L715)。これはL7ではうまくいくが、L4ではちょっと面倒だ。

関連する問題