この記事では マイクロサービス (Microservices Architecture)と呼ばれるアプリケーション構築の考え方、およびその構築に欠かせないツールであるKubernetesとIstioについて、その概要を説明いたします。
マイクロサービスとは
マイクロサービスとは「アプリケーションを単一の機能を行う小さな単位(サービス)に分割し、それぞれを独立して開発、デプロイする考え方」を指します。これはあくまで考え方で、特定の技術や開発言語を指すものではありません。
NGINX社のブログにより詳しい記事があります。長編なのでお時間がある方はどうぞ。
これに対して、全ての機能を単一のアプリケーションに統合して開発する従来の方法をモノリシック(Monolithic:一枚岩の)と呼びます。
モノリシックなアプリケーションの実行イメージ。全ての機能が統合されたアプリケーションが起動しています。データベースへの接続も、アプリケーションが直接行います。
それに対してマイクロサービスのアプリケーション実行イメージがこちら。それぞれの機能が独立したサービスとして起動し、相互に通信することでユーザーに機能を提供しています。また、データベースへの接続は専用のAPIを通じて行います(サービスごとに独立したデータベースを作成することも可能です)。
マイクロサービスで構築されたWebサービスは私達の身近なところにもたくさんあります。
- Amazon
- クックパッド
- Netflix
- LINE
- メルカリ
- Spotify
少しはマイクロサービスに親しみを感じることができるのではないでしょうか?
なぜ マイクロサービス なのか?
一言で言ってしまうと「大規模なアプリケーションを安全かつスピーディに開発するため」です。
運用を開始したアプリケーションは、運用の中で改修を繰り返していきます。モノリシックなアプリケーションは、改修を繰り返すことで巨大かつ複雑になっていきます。
こうなると、改修のスピードを速めることは難しくなります。というのも
- 巨大になりすぎて誰も全体像を理解できなくなる。
- 誰も全貌を理解していないので、事前調査に時間がかかる。
- 複数の機能が密接に関わり合っているので、1つの改修の影響が多岐にわたる(当然ながら改修とテストにも時間がかかる)。
- ソースコードが膨大なので、ビルドにも時間がかかる。
- できあがったアプリケーションが巨大なので、起動にも時間がかかる。
といったことになるからです。余談ですが、このブログを書くために英語の記事を何件か読むと、巨大化して手に負えなくなったモノリシックなアプリケーションを「Monster」や「Beast」と表現していました。
その点マイクロサービスは、アプリケーションを独立したサービスに小さく分割して実装するので、以下のようなアドバンテージが得られます。
- それぞれのサービスはコンパクトなので全体像を理解しやすい。
- コンパクトなので少人数のチームで開発ができる
- 自サービスの改修が他のサービスに影響を与えることが少ない。
- 当然ながら他のサービスの改修が自サービスに影響を与えることも少ない。
結果として、開発→ビルド→デプロイのサイクルをスピーディに回すことができるのです。今はユーザーからのフィードバックを受けてアプリケーションを頻繁に更新する手法が一般的なので、マイクロサービスによって得られるこれらのアドバンテージは非常に大きいと言えます。
繰り返しになりますが、マイクロサービスは一つ一つのサービスが独立して実装されます。そのため、サービスごとに最適な開発基盤を使うことができます。つまり、AというサービスはJavaで開発し、BというサービスはPythonで開発するといったことが可能です。また、運用中にスケールアウトが必要になったときも、対象のサービスだけをスケールアウトすることができます。
マイクロサービス のデメリット
いいことばかりを書いてきましたが、マイクロサービスは決して万能ではありません。モノリシックなアプローチとは異なる点で注意が必要になります。
- サービス同士が通信する仕組みを構築する必要がある。
→これについては、すべてのサービスが一ヶ所にメッセージを送受信する仕組みを構築するケースが多いです。(イベントストア、メッセージバスなど複数の呼び方があります) - 全てのサービスに共通の処理を実装しなければならない。
→プログラムごとに実装するのではなく、オーケストレーター(後述)で管理することが一般的です。
マイクロサービス とコンテナ
コンテナとは仮想化技術の1つで、アプリケーションと必要なライブラリ一式を1つの独立した環境として構築するものです。「コンテナを展開するホストOSの影響を受けにくい」「異なる環境への展開が容易」といったメリットがあり、今となっては必須の技術とも言えます。メジャーなコンテナサービスとして、Dockerがあります。
コンテナとマイクロサービスは、以下の点から非常に相性がいいです。
- マイクロサービスではサービスごとに異なる開発基盤を使用しているケースが多いですが、それぞれのサービスをコンテナとして実行すれば、お互いの環境に影響されることがありません。
- サービスごとにアプリケーションと必要なライブラリをパッケージ化しておけば、それを使ってどのホストにも展開し実行することができます。
とは言いながら、実際に運用するとなると「コンテナを手動で展開するのは大変」「1つのホストでたくさんコンテナを実行させると、リソースの管理が面倒」といった問題が出てきます。そういった問題を解決するのが「オーケストレーション」です。
オーケストレーションとは?
オーケストレーション(Orchestration)とは「編成化」「組織化」という意味ですが、ITの世界ではコンテナ化された環境を自律的に構成、維持してくれる機能のことを言います。
オーケストレーション機能を提供するツールをオーケストレーターといいます。オーケストレーターにはいくつか種類がありますが、一番使われているのはKubernetesです。読み方は「クーバネティス」が正しいようですが、長いので「k8s(ケーエイツ)」と表記することも多いようです。
Kubernetesの仕組み
Kubernetesは以下の要素で構成されています。
- クラスター(Cluster)
Kubernetesが1つの環境として取り扱う単位です。それぞれのクラスターには1台のマスターと1台以上のノードが存在します。 - マスター(Master)
クラスタ全体の管理を担当します。ユーザーが設定した内容を受け、その内容を維持するようにそれぞれのノードに指示を出します。 - ノード(Node)
アプリケーションの実行環境を提供する物理/仮想マシンを指します。それぞれのノードは、マスターとの通信を行うKubeletとコンテナエンジン、そして後述のPodで構成されます。 - ポッド(Pod)
Kubernetesが処理する最小の単位で、コンテナ化されたアプリケーションを1つ以上持ちます。同じポッド内のコンテナはストレージとIPアドレスを共有し、常に同じタイミング、同じノードにスケジュール(配置)されます。
Kubernetesでできること
クラスター化
複数台のホストマシンで構成される実行環境をクラスターという単位で結合し、1台の実行環境のように扱うことができます。Dockerだけではホスト間の連携が煩雑になるという問題があります。そのためホストのリソースを超えたスケールアウトが難しくなりますが、Kubernetesでクラスター化することでこの問題を解決することができます。
- スケジューリング
オペレーターは起動するコンテナのスペック(コンテナイメージと台数)をマスターに指示さえするだけです。そのコンテナをどのノードに配置するかはKubernetesがよしなに取り計らってくれます。
- 耐障害性
万が一運用中にコンテナに不具合が発生してサービスがダウンしたとします。Kubernetesはこれを「スペックと違う状態になっている」と判断し、スペックで指定された状態となるようにそのコンテナを自動的に再起動します。
- サービス
複数のノードおよびポッドを抽象化し、外部との通信で使用する単一のエンドポイントを提供します。
マイクロサービスを提供するポッドはそれぞれIPアドレスを持ち、複数のノードに点在しています。また、ノード(とその中にあるポッド)にはライフサイクルがありIPアドレスは変化する可能性があります。そのため、ポッドのIPアドレスを指定してサービスにアクセスすることは非常に不安定になります。
この問題を解決するために、ノードやポッドのIPアドレスを意識することなくマイクロサービスにアクセスする方法が必要となりますが、この方法を提供するのがKubernetesのサービスと呼ばれる機能です。サービスはクラスターIPとポート番号を持ち、外部からのリクエストを受けます。リクエストを受けたサービスは、そのリクエストを任意のポッドに配信します。
- ローリングアップデート
複数のポッドで構成されているアプリケーションを、段階的に更新します。これにより、アプリケーションを停止することなく更新することが可能です。
Istioとは?
Kubernetesを使うことでマイクロサービスの運用をラクにすることができるようになります。さらに便利にするために使いたいのが、Istioです。Istioはマイクロサービス間のトラフィックをコントロールしてくれます。このようなソフトウェアを「サービスメッシュ」と呼びます。マイクロサービス間で行われる大量の通信がメッシュ(編み目)のようであることに由来します。
Kubernetesはインフラレベルで動きますが、Istioはアプリケーションレベルで動くと考えると分かりやすいと思います。
Istioはコントロールプレーンとデータプレーンに分けられます。コントロールプレーンはさらに「パイロット(トラフィックを管理)」「ミキサー(アクセス制御を担当)」「シタデル(セキュリティを管理)」の3機能に分けられます。データプレーンはKubernetesのポッドごとに配置されたエンボイを指します。エンボイはLyft社が開発したプロキシで、アプリケーションに替わってマイクロサービス間のトラフィックを制御したりログを出力したりします。
1つ注目したいのは、エンボイがアプリケーションの開発言語に依存せず機能するということです。これにより、マイクロサービスで共通のトラフィック処理を簡単に実装することができます。ちなみに、エンボイのようにアプリケーションの補助的な役割を持つアプリケーションを「サイドカー」といいます。
Istioでできること
Istioができることのうち、もっとも大きなものはトラフィックの制御です。Istioの設定を変更するだけで、アプリケーションの変更なしに次のようなことができます。
- トラフィック全体の○%だけが新しいバージョンのアプリケーションにアクセスするようにし、新旧の両バージョンを並行して実行する。(カナリア・リリース)
- 特定の条件(ユーザー名など)を満たすトラフィックを別バージョンのアプリケーションにアクセスするようにし、実行環境とテスト環境を並行して実行する。
- トラフィックの一定割合に遅延を発生させたり意図的にエラーを返すようにすることで、障害発生時の動きを検証する。(フォールトインジェクション)
- エラーの回数がしきい値を超えた場合に即座にエラーを返し、システムがタイムアウトしないようにする。(サーキットブレーカー)
また、アクセス管理としてトラフィック情報(メトリクス、ログ)を収集し、バックエンドの監視システムと連携することもできます。
最後に
マイクロサービスによるアプリケーション構築は、DockerやKubernetesといった現在では必須とも言えるアーキテクチャと深いつながりを持っています。両者の知識をまとめて学習することで、大きくスキルアップできればいいと思います。
なお、Kubernetes環境上でマイクロサービスのアプリケーションを構築するワークショップが、AWSで公開されています。この記事を読んで気になった方はぜひ体験してみてください。
技術者ブログに戻る
あなたも、Avintonでこのような最先端技術を習得し活用してみませんか?
社員の成長を導きながら、AIやビッグデータなどの最先端技術をプロジェクトに活用していくことが私たちのビジョンです。Avintonの充実した技術研修でスキルアップを図り、あなたのキャリア目標を一緒に達成しませんか?