サービスメッシュの代表格であるIstioをKubernetesクラスタに導入する機会がありました。 それまでは、Istioとは何か、なぜサービスメッシュが支持されているのか全く知らず、IstioはDevOpsロードマップで辛うじて名前を知っている程度でした。 今ではこれらに明確な答えが得られ、自信を持ってKubernetesクラスタへのIstio導入をお勧めできるようになりました。 様々なメリットがありますが、今回は私が最も気に入っているIstioのメリットを4つ紹介したいと思います。
はじめに:Istioとは?
マイクロサービスアーキテクチャでは、アプリケーションのさまざまな部分が、個別の小さなサービスに分解されます。 これらのサービスは互いに通信し、全体としてアプリケーションの機能を提供します。 サービスメッシュとは、マイクロサービス・アーキテクチャにおけるサービス間通信を制御する、専用のインフラストラクチャー層を指します。
ただ、サービス間の通信は通常、複雑です。 高速で、信頼性が高く、安全である必要があります。 サービスディスカバリ、ロードバランシング、障害回復、メトリクス、モニタリングなどを処理する必要があります。 また、A/Bテスト、カナリアリリース、レート制限、アクセスコントロール、エンドツーエンド認証など、より複雑な運用要件があることも多いです。
そこで登場するのがIstioです。Istioはオープンソースのサービスメッシュで、既存の分散型アプリケーションに透過的にレイヤー化します。 つまり、アプリケーションのコードを変更することなく、上記のすべての問題に対する解決策を得ることができます!
Istioは、各Podにサイドカー・プロキシを注入することでこれを実現します。 Istioを有効にしたKubernetesクラスタにサービスをデプロイすると、Istioは自動的に各Pod内にサイドカー・コンテナとしてプロキシを入れ込みます(サイドカー・インジェクション)。 このプロキシは、Podに出入りするすべてのネットワークトラ フィックを仲介します。 以下、Istioのアーキテクチャを公式docから引用します。
Istioとサービスメッシュは、DevOpsエンジニアとして学ぶべき重要な概念として、DevOps Roadmapに掲載されています。
さて、Istioの基本はわかったので、私が最も気に入っているIstioの4つの機能を説明します。
1. トラフィック管理
Istio では、重み付けルーティングやダークローンチなど、高度なトラフィック戦略を設定可能です。
重み付けルーティング(別名:カナリアリリース)
この機能は、サービスの新バージョンをロールアウトしたいときに特に便利です。すべてのトラフィックをすぐに新バージョンに送るのではなく、トラフィックのごく一部(たとえば5%)を新バージョンにルーティングし、それを徐々に増やしていくことができます。このアプローチはカナリアリリースとも呼ばれ、対象を限定して新バージョンを検証するのに役立ちます。
YAMLマニフェストを直接作成するか、Kialiを使ってGUIからルーティングルールを作成し、YAMLにエクスポートすることができます。
ダークローンチ
新機能や新サービスを本番環境に導入し、一部のユーザーにだけ公開することで、本格的なローンチ前にその性能をテストすることも可能です。Istioでは、リクエストヘッダを利用して、新機能を誰に見せるかのルールを定義することができ、ダークローンチのための強力で柔軟なメカニズムを提供することができます。
以下では custom-header-dark-launch
というヘッダがv3
のときはreviews-v3
サービスにルーティングする、という設定をしています。
このように本番環境においてもテストが可能である点で便利であると感じました。
2. オブザーバビリティ
IstioはPrometheusやJaegerと統合することで、可観測性を高めることができます。 インストールは非常に簡単で、検証用のKubernetesマニフェストもIstioが公式でGitHub上に公開しています。 これらのツールは全てそのまま動きますが、Jaegerだけは例外です。 これは分散トレーシングのためのツールなのですが、どのリクエストがどのリクエストに関連しているか、というチェーンやスパンの情報を提供するいくつかのヘッダーを 伝播する必要があります。
Kiali
Kialiは、Istioベースのサービスメッシュの管理コンソールです。サービスメッシュ全体の概要を把握することができ、Istioの設定を検証することができます。 特に、新しいプロジェクトに参加する際には非常に強力なツールとなります。 Kialiを使えば、Kubernetesクラスタ全体を可視化し、どのようなサービスがデプロイされ、それらがどのように互いに接続されているか、一目瞭然です。
Prometheus
Istioは、主要なオープンソースのモニタリングソリューションであるPrometheusにメトリクスを出力します。 これらのメトリクスには、リクエスト数、リクエスト時間、リクエストサイズ、レスポンスサイズが含まれ、サービスのパフォーマンスと健全性を効果的に監視することが可能です。
Istioが提供する詳細なメトリクスについては、Istio Standard Meticsをご参照ください。
Jaeger
Istioは、分散トレーシングシステムであるJaegerとも連携しています。Jaegerは、リクエストが様々なサービスを通過する様子をトレースすることで、リクエスト単位での可観測性を提供します。 サービス間の相互作用やそれに伴うレイテンシを表示することができ、パフォーマンス問題の把握と診断に役立 ちます。
例えば、以下の画像は、リクエスト処理時間の大部分が details
サービスで消費されていることを示しています。
3. セキュリティ
Istio は、相互 TLS (mTLS) などいくつかの方法でサービスのセキュリティを強化します。
相互TLS (mTLS)
Kubernetesクラスタ内の通信を暗号化することは、一般的に、ノード間の潜在的なトラフィックの盗聴から保護し、侵入によるリスクを軽減するために、クラスタのセキュリティ姿勢を強化するグッドプラクティスと考えられています。
IstioにはデフォルトでmTLSが付属しており、Istioプロキシ間のトラフィックはすべて相互に認証され暗号化されます。 したがって、TLSを処理するためにアプリケーションコードを修正することなく、セキュリティ強化の恩恵を受けることができます。
4. レジリエンシー
Istioには、リトライやサーキットブレーカーなど、サービスの 回復力を高めるための機能がいくつか用意されています。
リトライとタイムアウト
Istioは、アプリケーションコードを変更することなく、マイクロサービスアーキテクチャーのためのリトライとタイムアウトを提供します。
サービスリクエストが失敗した場合、Istioは自動的にリクエストを再試行することができます。これにより、リクエストが最終的に成功する可能性が高くなり、サービスの信頼性が向上します。
Istioは、アプリケーションコードを変更することなく、VirtualService
カスタムリソース(CR)のマニフェストに数行追加するだけで、メッシュ内のリクエストに対するタイムアウトを簡単に設定することも可能です。
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- route:
- destination:
host: ratings
subset: v1
retries:
attempts: 3
perTryTimeout: 2s
retryOn: connect-failure,refused-stream
timeout: 10s
サーキットブレーカー
分散システムでは、障害が 1 つのサービスから別のサービスに連鎖し、システム全体の停止につながる恐れがあります。サーキットブレーカーは、障害の影響を制限することで、これを防ぐものです。あるサービスに障害が発生するとサーキットブレーカーが「開き」、障害のあるサービスへのリクエスト送信を停止し、サービスの復旧を待ちます。サービスが回復するとサーキットブレーカーは「閉じる」ので、リクエストは再びそのサービスに届くようになります。
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: httpbin
spec:
host: httpbin
trafficPolicy:
outlierDetection:
consecutive5xxErrors: 2
interval: 1s
baseEjectionTime: 3m
maxEjectionPercent: 100