OpenShift Service MeshをQuarkusアプリケーションに適用してみる

# はじめに
OpenShiftでは、IstioをベースとしたサービスメッシュSWとして「OpenShift Service Mesh」が提供されています。OpenShift Service MeshはOpenShift(OpenShift Container Platform)を利用していれば無料で使用することが可能です。OpenShift Service Meshには、Istio以外に、分散トレースシステムの「Jaeger」、サービスメッシュの可視化を担当する「Kiali」が含まれており、OpenShift Service Meshを導入することでこれらも利用可能となります。

当記事では、「[OpenShift Service Meshを使ってみた！](https://qiita.com/strada/items/578d0b552da1e9d2a1f1)」の記事に沿ってOpenShift Service Meshが導入された状態から、Quarkusのサンプルアプリケーションに対してサービスメッシュを適用する手順について記載します。


# 環境
- Red Hat OpenShift on IBM Cloud 4.7.12 (VPC Gen 2環境に作成)
- OpenShift Service Mesh 2.0.6-2
- Quarkus 1.13.6


# 前提
- 「[OpenShift Service Meshを使ってみた！](https://qiita.com/strada/items/578d0b552da1e9d2a1f1)」の記事に沿い、「[ServiceMeshControlPlaneの作成](https://qiita.com/strada/items/578d0b552da1e9d2a1f1#servicemeshcontrolplane%E3%81%AE%E4%BD%9C%E6%88%90)」まで完了していること。
- IBM Cloud Container RegistryにQuarkusアプリケーションのコンテナイメージが登録済みであること(コンテナイメージの作成・登録手順は、別記事「[IBM Cloud Code EngineにQuarkusのサンプルアプリケーションをデプロイしてみる](https://qiita.com/hisato_imanishi/items/45c83963fa44c34e0255#quarkus%E3%81%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%82%92%E4%BD%9C%E6%88%90%E3%81%97ibm-cloud-container-registry%E3%81%AB%E7%99%BB%E9%8C%B2%E3%81%99%E3%82%8B)」内の記述を参照ください)


# 実施手順
サービスメッシュを適用するQuarkusアプリケーション用のプロジェクトを作成します。

```bash
oc new-project quarkus-servicemesh
```

作成したプロジェクトでIBM Cloud Container Registryからイメージをpullできるよう、defaultプロジェクトからimagePullSecret(all-icr-io)をコピーします。

```bash
oc get secret all-icr-io -n default -o yaml | sed 's/default/quarkus-servicemesh/g' | oc create -n quarkus-servicemesh -f -
```

次に、サービスメッシュに参加させるプロジェクトを、ServiceMeshMemberRollリソースを作成して指定します。「servicemeshmemberroll-default.yaml」というファイルを作成し、以下の内容を記述します。

```yaml:servicemeshmemberroll-default.yaml 
apiVersion: maistra.io/v1
kind: ServiceMeshMemberRoll
metadata:
  name: default
  namespace: istio-system
spec:
  members:
    - quarkus-servicemesh   # サービスメッシュに参加させるプロジェクトの一覧
```

ServiceMeshMemberRollリソースを作成します。

```bash
oc create -n istio-system -f servicemeshmemberroll-default.yaml
```

既にServiceMeshMemberRollを作成済みの場合、上記のYAMLの適用に代わり、OpenShiftのWebコンソールでServiceMeshMemberRollのYAMLを編集し、プロジェクトの一覧に追加します。手順は以下の通りです。

1. OpenShift Webコンソールにアクセス
1. Operator -> インストールされたOperatorを選択
1. 「istio-system」プロジェクトを選択
1. (Operatorの一覧の中から)Red Hat OpenShift Service Meshをクリック
1. Istio Service Mesh Member Roll タブを選択
1. 「default」の右側の「︙」をクリックし、「ServiceMeshMemberRollの編集」を選択
1. spec.members[] にサービスメッシュを適用するプロジェクトを追加し、「保存」ボタンをクリック

※上記手順2〜6
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/337d6cd0-7538-e23e-8373-d785c9960abf.png)

※上記手順7
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/15f83513-3f62-80d5-5020-41a7eaa75f1c.png)


quarkus-servicemeshプロジェクトにサービスメッシュを適用できたので、あとはQuarkusアプリケーションをデプロイします。以下の3つのマニフェストファイルを作成し、``oc apply``します。

Deploymentでは、Podのアノテーションに``sidecar.istio.io/inject: "true"``を指定し、Podへのサイドカーコンテナの挿入を有効にします。

```yaml:quarkus-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: quarkus-getting-started
spec:
  selector:
    matchLabels:
      app: quarkus-getting-started
  replicas: 1
  template:
    metadata:
      annotations:
        sidecar.istio.io/inject: "true"  # サイドカーコンテナの挿入を有効にする
      labels:
        app: quarkus-getting-started
    spec:
      containers:
      - name: quarkus-getting-started
        image: <IBM Cloud Container Registry上のQuarkusアプリケーションのコンテナイメージ> # 要書き換え
        resources:
          limits:
            memory: "256Mi"
            cpu: "100m"
        ports:
        - containerPort: 8080
      imagePullSecrets:
          - name: all-icr-io
```

```yaml:quarkus-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: quarkus-getting-started
spec:
  selector:
    app: quarkus-getting-started
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
```

Istio Ingress Gatewayを設定するリソースとして、「Gateway」と「VirtualService」を作成します。

```yaml:quarkus-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: quarkus-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "quarkus-servicemesh/*"  # バインド対象をquarkus-servicemeshプロジェクトに限定
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: quarkus-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - quarkus-gateway
  http:
  - match:
    - uri:
        prefix: /hello  # Quarkusアプリケーションの /hello エンドポイントに適用
    route:
    - destination:
        host: quarkus-getting-started.quarkus-servicemesh.svc.cluster.local  # ルーティング対象のServiceのFQDNを指定
        port:
          number: 8080
```

これらを以下のコマンドで適用します。

```bash
oc apply -f quarkus-deployment.yaml
oc apply -f quarkus-service.yaml
oc apply -f quarkus-gateway.yaml
```

稼働確認のため、Ingress GatewayのRouteを取得します。

```bash
oc get route istio-ingressgateway -n istio-system
```

以下のURLにアクセスし、Quarkusアプリケーションによりhelloメッセージが表示されることを確認します。

``http://<上記で取得したIngress GatewayのHOST:PORT>/hello``

以上です。