いまさら聞けないサービスメッシュ入門とTraffic Director

マイクロサービスやサービスメッシュという言葉を聞くけど、実は意味はよく分かっていない。そんな方も多いのではないでしょうか。

私もそんな一人でした。
今回はクラウドネイティブのトレンドに追従すべく、マイクロサービスの背景から、サービスメッシュの概要、そしてGoogle Cloud がマネージドで提供するTraffic Directorについて学んでみたので、その内容を記載します。

## モノリシックなアプリケーション
アプリケーションの実装方法にはさまざま方法があります。実装する機能が単純であれば、単一のプロセスにまとめることで、実装が早くでき、スケールもしやすいメリットがあります。

しかし、機能の追加が続いていくと、単一のプロセスでは様々な運用上の課題が生まれます。

- モジュール間の依存関係が生じ、複雑に絡み合う
- 変更による影響範囲が広くなり、関係者間調整のオーバーヘッドが増える
- スケーリングの際、不要な機能も含まれるため非効率になる
- サービスダウンや遅延などの障害が発生したときに、原因を特定するのに時間がかかる
- コードが複雑になることで、たった1行のコードを変更しただけでも、ビルド・テストの時間もかかる

このような課題から変更が容易でなくなり、ビジネスの成長に追従するためのアジリティ確保が難しくなってしまいます。

そこで考えられたのがマイクロサービスです。マイクロサービスと対比して、単一のプロセスとしての実装をモノリシックなアプリケーションと呼ばれることがあります。

## マイクロサービスとは
マイクロサービスでは機能単位でアプリケーションを分割し、独立して開発できるようにします。
各サービスはコンテナとしてデプロイされる分散型のアーキテクチャとなり、サービス間はAPIでやり取りが行われます。
マイクロサービスにより以下のようなメリットが得られます。

- 機能追加のオーバーヘッドが小さくなり、変更が容易になる
- サービスごとに独立してデプロイしたりスケーリングしたりできる
- サービスごとに新しい技術を導入することが容易になる
- 障害の影響範囲を局所化し、原因の特定が用意になることで、可用性や復旧時間が改善する

しかし、マイクロサービスにすればすべて解決するわけではありません。分散アーキテクチャならではの複雑性から、新たな課題も存在します。

### サービスをどこで分割するか
サービスの適切な分割は正解がありません。[ドメイン駆動設計（DDD）](https://ja.wikipedia.org/wiki/%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E9%A7%86%E5%8B%95%E8%A8%AD%E8%A8%88)や[Sagaパターン](https://medium.com/google-cloud-jp/gcp-saga-microservice-7c03a16a7f9d)などのプラクティスもありますが、自チームのアプリケーションの特性やコンテキストに合わせて、自分たちで考えて適切な分割を決めていかなければいけません。

### テストが難しい
すべてのサービスを揃えて結合テストを行うことはどのようにすればよいのでしょうか。
サービスが細かく分割され数が増えるほど難しくなります。

### 他のサービスと互換性を保つ
マイクロサービスだからといって、他のサービスを無視して良いわけではありません。
自チームのサービスは他のサービスから呼び出されており、その互換性を勝手に崩したり、他のサービスにダウンタイムを発生させてはいけません。

### サービス間の信頼性
マイクロサービスは分散システムであり、ネットワーク経由の通信となります。
よって、ネットワーク状況による失敗や対向サービスの不具合・停止による失敗を前提に、以下のような防御的実装を行うことが必要になります。

- サービスディスカバリ
    - 呼出先サービスの位置は一定ではないため、どこにいるのかを探せる仕組みが必要です。
- リトライ
    - 一時的に呼び出しが失敗した場合、もう一度呼び出しを試行する仕組みが必要です
- サーキットブレイカー
    - 継続して呼び出しが失敗する場合、対向サービスに障害が起きている可能性があります
    - 復旧するまで呼び出しをやめて、障害の影響範囲を広げないようにします
- タイムアウト
    - 対向サービスのパフォーマンスが悪化するとレスポンスタイムがユーザの期待値よりも大きくなってしまうリスクがあります
    - 他のサービスへの待ち時間を適宜してタイムアウトを設定します
- スロットリング
    - 呼び出し元がAPIの仕様に乗っ取らないリクエストを投げてくる場合に対し、一定のレートを超えたら受け付けないなど、防御的機構が必要です

### サービス間通信の可観測性
マイクロサービスに障害が起きたときに、復旧するためにその障害が「どこで」「なぜ起きたのか」を把握する必要があります。
そのためにシステムを観測できる実装が必要です。

- メトリクス
    - 数値で表せる情報
- トレース
    - あるトランザクションにおいて、マイクロサービスにおけるコンポーネント間の連鎖を追跡します
    - サービス間の関係を考慮したり、ボトルネックとなっているサービスを特定したりするのに役立てます
- ログ
    - アプリケーションが出力するテキスト行
    - トラブルシューティングに非常に役立ちます

### 信頼性と可観測性に対するアプローチを考える
これらの課題のうち、信頼性と可観測性にフォーカスして考えます。
各サービスで個別に対応していては、マイクロサービス全体の信頼性や可観測性を保つことはできません。一貫性のあるアプローチが必要になります。
そこで登場するのがサービスメッシュという概念です。

## サービスメッシュ
マイクロサービスの信頼性や可観測性に関する難しさは、ネットワーク経由で相互に通信することに起因して、対処が必要なことでした。
そこで、ネットワーク管理機能をアプリケーションから分離し、アプリケーションの実装をシンプルにしようというものがサービスメッシュです。
### サービスメッシュでできること
マイクロサービスにおける信頼性と可観測性の課題であげた防御的実装や指標の収集、サービスの認証認可などの機能を担います。

### サービスメッシュのアーキテクチャ
サービスメッシュは個々のサービスのトラフィックを管理する**データプレーン**と、データプレーンへ指示を行いマイクロサービス全体を管理する**コントロールプレーン**の2層から構成されます。

### データプレーン
データプレーンには代表的なアプローチとして以下の2つがあります。

##### サイドカープロキシ
サービスの横に常駐し、プロキシとしてネットワーキングを仲介します。サービスへのリクエストを受信または送信すると、そのリクエストはサイドカープロキシに入り、目的の宛先に送信するなどの処理を行います。

サイドカープロキシとして広く浸透しているOSSが[Envoy](https://www.envoyproxy.io/)です。Envoyは[CNCF](https://www.cncf.io/)における
graduated project となっています。

##### プロキシレス型
トラフィック管理に関する実装をライブラリとして提供し、アプリケーションコードから分離します。
プロキシを用いないため、サイドカープロキシに比較して以下のメリットが挙げられます。

- プロキシ実行のためのリソースが不要となり、リソース使用効率が向上する
- レイテンシを短縮できる場合があります。1ミリ秒のレイテンシが問題となるようなユースケースではプロキシレスが有効です。
- 環境によってはサイドカープロキシを追加プロセスとして実行できないことがあります。この場合、プロキシレス型が有効です。

プロキシレス型で注目を集めているのが[gRPC](https://grpc.io/)です。gRPCは昨日豊富なオープンソースのRPCフレームワークで、多言語に対応し、マイクロサービスに必要となる高性能なトラフィック管理機能を提供します。

### コントロールプレーン
データプレーンの制御や、CA（認証局）として鍵管理や証明書の発行を担当します。
サービスディスカバリのためのxDS APIを提供し、EnvoyやgRPCはxDS APIを使用してコントロールプレーンに接続し、動的にトラフィック管理の設定を取得します。

コントロールプレーンの代表的なオープンソースは[Istio](https://istio.io/)です。

## Traffic Director
以上の通り、サービスメッシュはマイクロサービスにおけるトラフィック管理を実現する有力な概念で、広く普及しつつあります。
しかし、サービスメッシュ自体を運用するにもコストがかかります。

そこでサービスメッシュのコントロールプレーンをフルマネージドで提供するのが[Traffic Director](https://cloud.google.com/traffic-director)です。

Traffic Director は Google が管理するサービスで99.99%のSLAが適用されるほか、通常のサービスメッシュに加えて高度な機能を利用できます。
詳細は[こちら](https://cloud.google.com/traffic-director/docs/traffic-director-concepts)のドキュメントをご覧ください。一例を紹介します。

### マルチクラスタKubernetes
複数のKubernetesクラスタにまたがってマイクロサービスを構成できます。
これにより異なるリージョン間でトラフィックをルーティングすることも可能になります。

![cloud.google.com_traffic-director_docs_traffic-director-concepts.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194749/bf56c194-7dcf-5fa0-75ce-8f49a62cbadb.png)
引用元：[Traffic Director を使用したマルチクラスタ Kubernetes の例](https://cloud.google.com/traffic-director/docs/traffic-director-concepts#multi-cluster_kubernetes)

### 仮想マシンのワークロードにも適用できる
[Google Compute Engine](https://cloud.google.com/compute) ではインスタンステンプレートにフラグを追加することで、簡単にVMインスタンスにプロキシをセットアップすることができます。
これにより、Traffic Director を用いてKubernetesベースのワークロードとVMベースのワークロードの相互運用が可能になります。

![cloud.google.com_traffic-director_images_vms-kubernetes.svg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194749/521c0c1b-6cac-a45e-82fb-fc83d8a99b91.png)
引用元：[Traffic Director を使用した VM と Kubernetes の例](https://cloud.google.com/traffic-director/docs/traffic-director-concepts#virtual_machines)

### サイドカープロキシとプロキシレスが混在する環境も管理できる
Traffic Director は、プロキシレス gRPC サービスをサポートしています。
次の図のようにあるサービスにはサイドカープロキシがあり、他のサービスにはプロキシレスである環境でも、相互にトラフィックをルーティングすることができます。

![cloud.google.com_traffic-director_images_proxyless-grpc.svg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194749/d9c53928-dd26-4751-eca4-44515bfc69b7.png)
引用元：[Traffic Director を使用したプロキシレス gRPC アプリケーションの例](https://cloud.google.com/traffic-director/docs/traffic-director-concepts#proxyless_grpc)

## 終わりに
マイクロサービスが求められる背景からサービスメッシュ、そしてコントロールプレーンをマネージドで提供する Traffic Director を紹介しました。
今後は Traffic Director を使用して実際にマイクロサービスを構成し、より理解を深めたいと思います。

サービスメッシュのような新しい概念は高度な知識が必要で、自力で構築していくことはなかなか大変ですが、
マネージドサービスとして簡単に使えるのはクラウドの魅力ですね。

先端テクノロジーの敷居を下げ、民主化しているとも言えると思います。
積極的に試してみて、その価値を学び、自分のサービスへの適用を考えてみることが大切かもしれませんね。

## 参考
[Cloud OnAir 番組レポート : Google Cloud で実践するマイクロサービスアーキテクチャ](https://cloud.google.com/blog/ja/products/gcp/cloud-onair-20190221-microservice)
[サービスメッシュは本当に必要なのか、何を解決するのか | AWS Summit Tokyo 2019](https://www.youtube.com/watch?v=ZwfdLAClzsc)
[GKE、Traffic Director、CA サービスによるゼロトラスト ワークロード セキュリティ](https://cloud.google.com/blog/ja/products/identity-security/workload-credentials-for-gke-via-cas)