マルチテナント環境において、OpenShift Service Meshを利用する場合の外部公開はどうすればいいか疑問を感じたので、OpenShift Service Meshを利用した場合の外部公開を検証しました。
- OpenShiftのマルチテナント環境における外部公開(想定)
- OpenShift Service Meshのマルチテナント環境における外部公開(想定)
- OpenShift Service Meshの検証
- メンバーロールの作成
- Routeの作成
- Gatewayの作成
- 注意点
OpenShiftのマルチテナント環境における外部公開(想定)
マルチテナントプラットフォームにOpenShiftを採用する場合、Routeリソースを使って、それぞれのシステムを外部に公開することが想定されます。
マルチテナント管理チームがProjectリソースを作成・管理し、プロジェクトチームが各自でRouteリソースを作成することが考えられます。

※ベストプラクティスではなく、あくまでも想定です。要件・環境に応じて設計は変わることご認識いただければ幸いです。
OpenShift Service Meshのマルチテナント環境における外部公開(想定)
OpenShift Service Meshを利用する場合、Istio外部から受け付けるServiceリソースがService MeshのコントロールプレーンProjectにあります。Routeを利用して外部に公開するには、そのServiceに紐づいたRouteを作成する必要があります。
従って、RouteリソースをService MeshのコントロールプレーンProject内に作成し、各ProjectでService Meshのリソース(Gateway・VirtualService・DestinationRule)を作成する形が想定されます。

※ベストプラクティスではなく、あくまでも想定です。要件・環境に応じて設計は変わることご認識いただければ幸いです。
OpenShift Service Meshの検証
上記で想定した役割を踏まえて、実装してみました。
※VertualService/DestinationRule/Service/アプリケーションの作成は、通常のIstioと変わらないので省略しています。istio関連の操作については、Istio関連記事に投稿しています。
※OpenShift Service Meshのインストールは省略しています。インストール方法については、OpenShift Service Meshをインストールする方法に記載しています。
メンバーロールの作成
OpenShift Service Meshでは、ServiceMeshMemberRollというリソースに、Service Meshの対象プロジェクトを定義する必要があります。
以下のように、membersブロックにプロジェクト名を定義します。
apiVersion: maistra.io/v1 kind: ServiceMeshMemberRoll metadata: name: default namespace: istio-system ownerReferences: - apiVersion: maistra.io/v1 kind: ServiceMeshControlPlane name: basic-install finalizers: - maistra.io/istio-operator spec: members: - project-a - project-b
Routeの作成
OpenShift Service MeshをOperatorHubからインストールすると、Istioが外部からの通信を受け付けるためのistio-ingressgateway
Serviceリソースが作成されます。このServiceをRouteで外部に公開することで、クラスター外のユーザーからアクセスできるようになります。
以下のコマンドで、istio-ingressgateway
に紐づくProjectAとProjectBのRouteリソースを作成します。
$ oc expose svc istio-ingressgateway --hostname=example-a.test.com --port=8080 --name=project-a --generator=route/v1 route.route.openshift.io/project-a exposed $ oc expose svc istio-ingressgateway --hostname=example-b.test.com --port=8080 --name=project-b --generator=route/v1 route.route.openshift.io/project-b exposed
当然ながらhostnameは外部から名前解決できる必要があります。本記事ではローカルホストにexample-a.test.com, example-b.test.com
を登録しました。
Gatewayの作成
各Projectで作成するGatewayを作成します。
project-aにexample-a.test.com
の80番ポートで受け付けるa-gwを作成します。
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: a-gw namespace: project-a spec: selector: istio: ingressgateway # use Istio default gateway implementation servers: - port: number: 80 name: http protocol: HTTP hosts: - "example-a.test.com"
同様にproject-bにexample-b.test.com
の80番ポートで受け付けるb-gwを作成します。
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: b-gw namespace: project-b spec: selector: istio: ingressgateway # use Istio default gateway implementation servers: - port: number: 80 name: http protocol: HTTP hosts: - "example-b.test.com"
example-a.test.com, example-b.test.com
の名前でhttpリクエストを飛ばすと、それぞれのプロジェクトのアプリケーションに割り振られることが確認できました。
注意点
Gatewayリソースにおけるhostnameをワイルドカードにすると、期待していないアプリケーションに通信が飛んでしまうのでご注意ください。

名前解決や証明書のコントロールを考慮すると、RouteやGatewayはマルチテナント管理チームで作成・管理するのがいいのかもしれないなと感じました。


以上です。