サービスメッシュを実現するIstioをEKS上で動かす - その5 実運用中のサービスをIstioにのせてみる

山崎 雅斗
4

前回までは、サンプルアプリケーションを使った検証を進めてきました。
今回は、実運用中のサービスの一部をIstioのサービスメッシュにのせてみるということをやっていきたいと思います。

事前準備として、EKSクラスタを作成し、そこにIstioがインストールされていることを前提とします。

シリーズ一覧

mTLSの有効化

今回は、mTLSを有効にした状態でサービスを動かすことにします。
なので、まずはmTLSを有効にするための設定を入れていきます。

今回は、sample namespaceにサービスのPodをデプロイしていくことにします。
まず、sample namespaceでmTLSを有効にするため、次のPolicyを適用します。

apiVersion: v1
kind: Namespace
metadata:
  name: sample
  labels:
    istio-injection: enabled

---
apiVersion: authentication.istio.io/v1alpha1
kind: Policy
metadata:
  name: default
  namespace: sample
spec:
  peers:
    - mtls:
        mode: PERMISSIVE

上のmanifestを適用すると、sample namespaceに istio-injection labelがつくので、Istioが自動的にSidecar Proxyを配置してくれるようになります。

実運用中のサービスをデプロイする

今回は、スタディサプリENGLISHの一部分をIstioにデプロイして挙動の確認を行いたいと思います。
デプロイしたサービスは、下図のような構成になっています。

english-arch
今回デプロイしたアプリケーションの構成

Service Aが外部用のAPIを持ち、インターネットからのHTTPリクエストを受け取っています。リクエストを受け取ったService Aは、バックにいるマイクロサービス(Service B、Service C、Service D)とgRPCで通信しています。また、それぞれのマイクロサービスは、Istioのサービスメッシュ外にあるMySQLに接続するという構成となっています。

なお、前回紹介したServiceGraphやKialiといった可視化ツールを用いると、これらのサービスの関係もグラフとして表示することができます。

kiali-graph
Kialiで可視化した例(MySQLは省略されています)

sample namespaceではSidecar Proxyが自動で配置されるように設定されているので、通常通りのKubernetes manifestを使ってサービスをデプロイします。
アプリケーションをデプロイしたら、次にGatewayリソースとVirtualServiceリソースを作成します。

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: english-gateway
  namespace: sample
spec:
  selector:
    istio: ingressgateway
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - "xxxxxx.example.com"
    - port:
        number: 443
        name: https
        protocol: HTTPS
      tls:
        mode: SIMPLE
        serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
        privateKey: /etc/istio/ingressgateway-certs/tls.key
      hosts:
        - "xxxxxx.example.com"

---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: english
  namespace: sample
spec:
  hosts:
    - "xxxxxx.example.com"
  gateways:
    - english-gateway
  http:
    - route:
        - destination:
            host: xxxxxx.sample.svc.cluster.local
            port:
              number: 9000

外部サービスとの連携設定

今回デプロイしているサービスは、外部のMySQLに接続しています。特に何も設定していない場合、Istio内から外へのリクエストはうまくいきません。外部サービスへのリクエストを正常に行えるようにするためには、ServiceEntryリソースを作成する必要があります。

 apiVersion: networking.istio.io/v1alpha3
 kind: ServiceEntry
 metadata:
   name: mysql
   namespace: sample
 spec:
   hosts:
     - rds.dev.example.local
   addresses:
     - 10.0.0.1/32
   ports:
     - number: 3306
       name: mysql
       protocol: TCP
   location: MESH_EXTERNAL

サービス間の通信でmTLSを有効にする

今回適用したPolicyは、mTLSのモードを PERMISSIVE にしているため、このままでもサービス間の通信はできます。しかし、まだ何も設定を入れていないので通信は暗号化されていません。通信の暗号化を有効にするため、次のようなmanifestを適用していきます。

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: default
  namespace: sample
spec:
  host: "*.sample.svc.cluster.local"
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL

動作テスト

アプリケーションのデプロイとIstioの設定がうまくできているかをテストするため、 curl コマンドを使ってAPIを利用してみました。結果、意図している通りの挙動が確認でき、Istio上でもアプリケーションをうまくデプロイすることができていました。

まとめ

Istio上で、実運用中のサービスを正常に動かせることを検証できました。Istioにのせることで、柔軟なトラフィックルーティングやRetry、Circuit Breaker等様々な機能を使えるようになりました。次回はサービス監視によく用いられるDatadogとの連携について見ていこうと思います。