1. ホーム
  2. kubernetes

[解決済み] 別のネームスペースにあるサービス

2022-04-13 21:27:47

質問

あるネームスペースで、別のネームスペースで動作しているPodにリンクするサービスを定義する方法を探しています。 で動作しているPodのコンテナが、他のネームスペースで動作しているPodにリンクしていることは知っています。 namespaceA にアクセスすることができます。 serviceX で定義された namespaceB としてクラスタDNSで参照することにより serviceX.namespaceB.svc.cluster.local の場所をコンテナ内のコードが知る必要はありません。 serviceX . つまり、コードは単に serviceX で、アクセスできるようにする。

は、その Kubernetes ドキュメント は、これが可能であることを示唆しています。 セレクタなしでサービスを定義する理由の1つは、次のようなものだそうです。 別のNamespaceや別のクラスタにあるサービスを指すようにしたい場合 .

ということを示唆していますね。

  1. を定義します。 serviceX のサービスを namespaceA にあるため)、セレクタを使用せずに(選択したいPODは namespaceA ).
  2. サービスを定義する(これも serviceX の中にある namespaceB を、そして
  3. でEndpointsオブジェクトを定義します。 namespaceA を指すように serviceXnamespaceB .

私が達成できていないのは、この3番目のステップです。

まず、このようにEndpointsオブジェクトを定義してみました。

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

それは論理的なアプローチに思えたし 明らかに というのは targetRef はそのためのものでした。 しかし、これによってエラーが発生し ip フィールドを addresses の配列は必須でした。 そこで、次に試したのは、固定のClusterIPアドレスを serviceXnamespaceB を、IPフィールドに入力してください(ただし service_cluster_ip_range として設定されています。 192.168.0.0/16 であり、かつ 192.168.1.1 の ClusterIP として割り当てられていました。 serviceXnamespaceB ; serviceXnamespaceA に別の ClusterIP が自動的に割り当てられました。 192.168.0.0/16 サブネット)。

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

それは受け入れられましたが serviceXnamespaceA のPodに転送されなかった。 namespaceB - タイムアウトしてしまいました。 iptablesの設定を見ると、NATの事前ルーティングを2回行わないと達成できないようです。

しかし、満足のいく解決策ではありません。 serviceXnamespaceB にある Endpoints オブジェクトにそのアドレスを入れてください。 namespaceA . もちろん、それでは満足できません。なぜなら、Pod IPアドレスは時間の経過とともに変化する可能性があるからです。 サービスIPは、この問題を解決するためにあるのです。

では、あるネームスペースにあるサービスを サービス は、別のネームスペースで実行されているのですか?

コメントで、なぜこのようなことをしたいのか、という質問がありました。

例えば、マルチテナントシステムを構築し、テナント間で共有できる共通のデータアクセス機能を搭載したとします。 ここで、このデータアクセス機能に、共通のAPIを持ちながら、異なる性能特性を持つものが存在するとします。 あるテナントはそのうちの1つにアクセスし、他のテナントは別のものにアクセスします。

各テナントのポッドはそれぞれのネームスペースで実行されますが、それぞれがこれらの共通データ・アクセス・サービスの1つにアクセスする必要があり、それは必然的に別のネームスペースになります(複数のテナントからアクセスされるため)。 しかし、より高性能なサービスにアクセスするためにサブスクリプションが変更された場合、テナントがコードを変更しなければならないようなことは避けたいでしょう。

可能性のある解決策(私が考える最もクリーンな方法、それが機能すればの話ですが)は、データアクセスサービス用のサービス定義を各テナントのネームスペースに含め、それぞれが適切なエンドポイントに設定されることです。 このサービス定義は、各テナントが使用する権利を持つ適切なデータアクセスサービスを指すように構成されます。

解決するには?

私は同じ問題につまずき、静的なIP設定を必要としない素晴らしい解決策を見つけました。

サービスにアクセスするには、そのサービスの DNS名 (ご指摘の通り)です。 サービス名.名前空間.svc.cluster.local

そのDNS名で参照できるのは ローカルサービス経由で別の名前空間 :

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