IstioとOnline Boutiqueでサービスメッシュとマイクロサービスを体験する

Kubernetes

この記事は、Kubernetes3 Advent Calendar 2020 22日目の記事です。

サービスメッシュが雰囲気しかわからないので自身の勉強も兼ねて、kindのKubernetesクラスターにIstioとOnline Boutiqueを導入し、サービスメッシュとマイクロサービスアプリケーションを体験してみます。

マイクロサービスアーキテクチャ

概要

マイクロサービスアーキテクチャは、ソフトウェアアーキテクチャの1つで、従来のモノリシックアーキテクチャと比較されて語られることが多いです。こちらのドキュメントがわかりやすいかもしれません。

マイクロサービスは、アプリケーション構築のアーキテクチャ・スタイルです。マイクロサービス・アーキテクチャが従来のモノリシックなアプローチと異なるのは、アプリケーションをコア機能ごとに細分化するという点です。各機能はサービスと呼ばれ、独立して構築およびデプロイすることができます。つまり、個々のサービスが正常に機能してもしなくても、他のサービスに悪影響を及ぼすことはありません。

引用元: https://www.redhat.com/ja/topics/microservices/what-are-microservices

利点

マイクロサービスでは、コンポーネントに分割し疎結合にしておき、それらをステートレスに相互通信することで、1つのアプリケーションとして機能させる構成を取ります。メリットとしては以下のものがあります。

  • 市場投入期間の短縮: マイクロサービス・アーキテクチャでは開発サイクルが短縮されるため、より俊敏なデプロイメントと更新が可能になります。
  • 優れたスケーラビリティ: ニーズの高い特定のサービスは、複数のサーバーやインフラストラクチャにわたってデプロイできるため、ニーズに対応することができます。
  • 耐障害性: これらの独立したサービスは、適切に構築されていれば、相互に影響しません。つまり、モノリシックなアプリケーション・モデルとは異なり、ある部分に障害が生じてもアプリケーション全体がダウンすることはありません。
  • 容易なデプロイ: マイクロサービスベースのアプリケーションは、従来のモノリシックなアプリケーションと異なり小型でモジュール化されるため、デプロイメントに伴う心配がありません。これにはいくらかの調整が必要ですが、大きなメリットにつながります。
  • アクセス可能: 大規模なアプリケーションを小さなパーツに分割できるため、開発者は各部をより簡単に理解、更新、強化することができ、特にアジャイル開発手法と組み合わせることによって、開発サイクルが短縮されます。
  • オープン性の向上: 多言語 API を使用するため、開発者は、必要な機能に最適な言語とテクノロジーを自由に選択することができます。
    引用元: https://www.redhat.com/ja/topics/microservices/what-are-microservices

マイクロサービス化することで、開発のアジリティや柔軟性、アプリケーションの耐障害性、スケーラビリティが向上しそうです。

課題

いいことばかりなのかというと、そういうわけではありませんです。例えば、以下の点が課題として挙げられます。

  • 構築:時間をかけてサービス間の依存関係を特定する必要があります。1 つの構築を完了すると、依存関係により、他の構築も必要になる可能性があります。また、マイクロサービスがデータに及ぼす影響についても考慮する必要があります。
  • テスト:統合テストとエンドツーエンド・テストは、これまで以上に複雑かつ重要になります。アーキテクチャの一部で障害が起きると、サービス間のサポートをどのように構築したかに応じて、少し離れた部分で障害が発生することもあります。
  • バージョン管理:新しいバージョンに更新すると、下位互換性が失われる可能性があります。下位互換性に対応する条件付きロジックを使用して構築することもできますが、扱いが困難になります。あるいは、各クライアント向けに複数のライブバージョンを立ち上げることもできますが、メンテナンスや管理が複雑化するおそれがあります。
  • デプロイメント:これもまた、少なくとも初期セットアップの段階では課題となります。マイクロサービスの複雑さから、手動でのデプロイメントは困難であるため、デプロイメントを容易にするために、まずは多くの自動化に投資しなければなりません。サービスを導入する方法と順序を考える必要があります。
  • ロギング:分散システムでは、すべてのログを一元化する必要があります。これがなければ、スケーリングを管理することができません。
  • 監視:問題の原因を突き止めるために、システムを一元的に把握することが重要です。
  • デバッグ:リモートデバッグを行うことはできず、数十、数百のサービスに対しては機能しません。残念ながら、現時点ではデバッグ方法はありません。
  • 接続性:一元型または統合型を問わず、サービスディスカバリーを検討する必要があります
    引用元: https://www.redhat.com/ja/topics/microservices/what-are-microservices



関連する情報

Online Boutique

Online Boutiqueは、マイクロサービスアーキテクチャに基づいて開発されたデモアプリケーションです。後ほどデモで使おうと思います。

Sock Shop

Sock Shopは、マイクロサービスアーキテクチャに基づくデモアプリケーションです。Weaveworksが中心となってメンテナンスされています。最新の更新が2年前らしく、もう更新しないのかな?

Bookinfo

Bookinfoも、マイクロサービスアーキテクチャに基づくデモアプリケーションです。Istioと同じリポジトリに入っているマニフェストを、Kubernetesにapplyしていくことで気軽に試せます。

Awesome Microservices

Awesome Microservicesは、実際にマイクロサービスのアプリケーションを開発するときに役立つ技術情報がまとめられているリポジトリです。開発言語ごとに項目が分かれていて、見やすいです。(知らない単語ばかりで頭が痛くなりました)



サービスメッシュ

概要

マイクロサービス・アーキテクチャのアプリケーションは、細かいコンポーネントに分割され、それらが相互に通信すると書きました。利点も多い一方で、細かく分かれているがゆえに、監視やロギング、サービスディスカバリーなど難しくなるという課題もあります。マイクロサービスの課題の対応策として登場したのがサービスメッシュです。

サービスメッシュとは、各マイクロサービスが互いにどのように通信するかを制御する仕組みです。各マイクロサービスにはサイドカープロキシが挿入され、そのプロキシを介して相互に連携します。こちらのドキュメントがわかりやすいかもしれません。

サービスメッシュでは、リクエストはそれぞれのインフラストラクチャ層内のプロキシを通じてマイクロサービス間を転送されます。この理由で、サービスメッシュを構成する個々のプロキシを「サイドカー」と呼ぶことがあります。各サービスの内部ではなく、並んで実行されるからです。まとめると、各サービスから切り離されたこのような「サイドカー」プロキシが、メッシュネットワークを形成します。

引用元: https://www.redhat.com/ja/topics/microservices/what-is-a-service-mesh

上の図のようにサービスを互いに線でつないでみると網目状になるので、サービスメッシュという名前がついています。

関連技術

Istio

サービスメッシュを実現するOSSはいくつかありますが、Istioが最も有名だと思います。GoogleやIBM、Lyftが関わっています。後ほどのデモで使おうと思います。

Istioのアーキテクチャは公式ドキュメントにも載っている以下の図がわかりやすいです。


引用元: https://istio.io/latest/docs/concepts/what-is-istio/

まず大きく分けて2つの要素があります。コントロールプレーンとデータプレーンです。データプレーンは、各マイクロサービスに付随するプロキシの集合です。サービス間の通信やクラスタ外部との通信を中継します。コントロールプレーンは、サービスメッシュ内の各プロキシの設定やポリシー管理を行います。またテレメトリーの収集も行います。

さらに、Istioコントロールプレーンには、主に以下のコンポーネントが含まれます。

  • Pilot: 各プロキシの設定管理を行う
  • Citadel: 各プロキシに対して、TLS証明書の作成やローテーションを行う。砦という意味
  • Galley: Istioに構成管理サービスを提供
  • Mixer: 統計情報の取得や認証を行う。「Adapter」と呼ばれるプラグイン機構を使う

Isiod

コントロールプレーンのコンポーネント、よくわからんけどたくさんありますね。ただIstioのドキュメントを眺めた限り、2020年3月ごろにリリースされたIstio 1.5あたりから状況が少し変わっているように感じました。

まずIstio 1.5のUpgrade Notesによれば、Istio 1.5からIstiodが導入されています。Istioコントロールプレーンのコンポーネントが統合されて、istiodという1つのDeploymentとして動くようになったそうで、dはおなじみのデーモンのdです。この記事の後半で後ほどIstioをインストールしますが、今回の手順だとこのIstiodがKubernetesクラスターのデプロイされます。

またAnnouncing Istio 1.8によれば、MixerくんはIstio 1.7でdeprecatedとなり、1.8では削除されたそうです。さようなら。このページの注意書きによれば、Mixerが担っていた機能は、後述のEnvoyプロキシに移行されたそうです。

Envoy

Envoyは、オープンソースで利用できる軽量なプロキシです。サービスメッシュの文脈では、先程から何度か出てきているデータプレーンの「サイドカープロキシ」として使います。IstioもKumaも、プロキシはEnvoyです。マイクロサービスを構成するPodに、サイドカーコンテナとしてEnvoyプロキシのコンテナを挿入し、サービス間やクラスタ外からのトラフィックをEnvoyがインターセプトします。

Jaeger

Jaegerは、分散サービス間のトランザクションをトレースするためのOSSです。マイクロサービスアーキテクチャのアプリケーションの監視やトラブルシューティングに使用されます。読み方はイェーガーです。巨人を駆逐する人と同じです。また、ロゴが可愛いことで知られています。

Kiali

Kialiは、マイクロサービス間のトラフィックのフローや通信状態などを可視化できるOSSです。障害時にどこのサービスがうまく動いていないか確認したりするのに役立ちそうです。GrafanaやJaegerとの連携もできるらしい。


引用元: https://kiali.io/documentation/latest/architecture/

Kuma

Kumaは、Istioと同様にサービスメッシュを実現するOSSの1つです。まったく使ったことはありませんが、名前が可愛くていいですね。Kongという会社が開発しているらしく、こちらのブログポストで概要を知ることができます。



気軽なデモ

ここからはデモアプリをデプロイして、トラフィックを観察するだけの気軽なデモをやります。分散トレーシングを試したり、サービス間の通信にmTLSを適用したり、ネットワークポリシーを設定したり、A/Bテストしたり、JWT認証をつけたり、できることはいろいろありますが今回はやりません。

クラスタの用意

自宅にクラスターがないので、前回を使ったkindでKubernetesクラスタを用意します。予めDocker Desktopの設定で多めにリソースを割り当てておき、Master1台、Worker1台構成のクラスタを作りました。

Istioのインストール

Kubernetesクラスターができたので、Installation Guidesに沿って、Istioをインストールします。いくつか方法があるのですが、宗教上の理由からIstio Operatorを使ったインストール方法でやってみます。

Istioctlコマンドのインストール

こちらを見てインストールします。

Istio Operatorのデプロイ

以下のコマンドでIstio Operatorをデプロイします。必要なコントローラーとCRDに加え、ServiceやRBAC関連リソースを、名前空間istio-operatorに作成してくれます。

Istioのインストール

これもドキュメントの通り、istio-systemというNamespaceに、IstioOperatorというカスタムリソースを作成します。これをIstio Operatorのコントローラーが検知して、Istioのコンポーネントをインストールしてくれます。.spec.profiledemoを指定していますが、他にもdefaultminimalなどがあり、プロファイルによってインストールされるコンポーネントが変わるみたい)です。

何分か待つと、Podが上がってきます。

それぞれのPodはDeploymentで管理されていますが、それぞれ以下のような役割があります。

  • istiod: Istioコントロールプレーンのコンポーネントが統合されて、1つのプロセスとして動いています。dはもちろんデーモンのdです。
  • istio-ingressgateway: KubernetesのIngress機能に加え、Istioが管理する監視やルーティングルールをクラスタ外からの通信に適用します。
  • istio-egressgateway: ingressgatewayの逆です。クラスタ外へのトラフィックを対象とします。

Prometheus, Grafana, Kialiのインストール

こちらのドキュメントを参考にして、それぞれインストールしておきます。
3つ目のKialiのインストールで、no matches for kind "MonitoringDashboard" in version "monitoring.kiali.io/v1alpha1"というエラーが出る場合があるそうです。その場合は同じコマンドをもう一度実行すればよいらしいので、お試しください。

インストールできたら、istioctl dashboardコマンドで、それぞれのWebコンソールにアクセスできます。以下は、Kialiのコンソールにアクセスする例です。

Online Boutiqueのデプロイ

サービスメッシュのスタックがインストールできたので、次はマイクロサービスのデモアプリケーションOnline Boutiqueをデプロイします。Namespaceは適当に作って、あとはREADMEを見ながらやりました。5分くらいでPodが立ち上がるので気長に待ちます。

ドキュメントはGKE前提で書かれていますが、今回はkindでKubernetesクラスタを作っているので、frontend-externalというLoadBalancerタイプのServiceは機能してません。代わりにkubectl port-forwardを使ってお茶を濁します。

これで、ブラウザからhttp://localhost:7000/でアクセスできるようになります。



Envoyサイドカーの挿入

デモアプリとIstioとその仲間たちを導入したから準備完了!とはなりません。Online Boutiqueをデプロイしましたが、まだプロキシ(Envoy)がいません。この記事の前半に載せた下図でいうところのサイドカーがいないので、サービスメッシュにはなっていません。

(再掲)


引用元: https://www.redhat.com/ja/topics/microservices/what-is-a-service-mesh

サイドカープロキシを挿入するために、今回はAutomatic sidecar injectionの手順を使います。Namespaceにistio-injection=enabledとつけると、そのNamespaceに属する各PodにサイドカープロキシとしてEnvoyのコンテナが挿入されます。不思議ですね。

これは、Understanding what happenedとして丁寧に書いてある通り、Istioが提供するMutatingAdmissionWebhook istio-sidecar-injectorによるものです。よって、Podを作成するタイミングにEnvoyサイドカーコンテナが追加されます。今回は一度デモアプリ用のPodをすべて削除してから再作成し、kubectl get podしたときのREADY列を改めて見ると、Pod内のコンテナが1つ増えている事がわかります。

トラフィックの観察

KialiでOnline Boutiqueのトラフィックを眺めて終わりたいと思います。まずkialiのWebコンソールを開きます。

[Graph]を押して、Namespace demo-appを選んだらそれっぽい図が現れます。Online Boutiqueを構成する11個のマイクロサービスが表示されています。さらにTraffic Animationにチェックを入れます。このOnline BoutiqueにはloadgeneratorというDeploymentがいて、その名の通り、いい感じにデモアプリに負荷をかけ続けてくれるので、すぐにトラフィックの流れを観察できます。フロントエンドへ入るトラフィックがHTTPで、その他のサービス間はgRPCで通信していることもわかります。その他、毎秒のリクエスト数やレスポンスタイムの表示もできます。

では、今日は疲れたのでこの辺で。

皆さまよいお年を。2021年もどうぞよろしくお願いいたします。

Reference

以上.

コメント