エンジニアHubPowered by エン転職

若手Webエンジニアのための情報メディア

Istio導入のメリットとハマりどころを、実例に学ぶ〜マイクロサービス化の先にある課題を解決する

マイクロサービス化にともなサービス間の接続の複雑化、という課題への対処としてサービスメッシュとこれをもたらす「Istio」が注目されています。Istioをいち早く導入したユーザベースの阿南さんが、導入メリットと、使って分かった「ハマりどころ」を解説してくれました。

Istioメインカット

「マイクロサービスの構築」が近年のWeb業界で大きなキーワードになっています。さまざまな企業が、さまざまなアプローチでマイクロサービス化にトライしていますが、サービスが分割していくほどに、各サービス間の接続が複雑化する、という課題も生まれています。

こうした課題を解決するソフトウェアとして「Istio」と、同ソフトがもたらす「サービスメッシュ」という概念が注目されています。Istioはまだまだリリースされて日の浅いソフトウェアですが、これをいち早く導入したのが企業・業界情報プラットフォーム「SPEEDA」を運営する株式会社ユーザベースです。

同社ではマイクロサービス化を推進していく中で、信頼性を保ちつつ、頻繁な変更に対応できるシステムを構築していくためにIstioを導入したといいます。今回はIstioのメリットやハマりどころといった、実運用に基づく貴重な知見を、同社のSRE阿南肇史(あなん・としふみ)さんに聞きました。

阿南肇史さんプロフィール
阿南肇史さん
大学卒業後、広告配信系サービスのインフラエンジニアとしてキャリアをスタート。2016年に株式会社ユーザベースにSREエンジニアとして入社。Istioに関しては『UZABASE Tech Blog』でも盛んに発信を行う。

マイクロサービスを増やしていくならサービスメッシュ化を検討すべき

──まずは、SPEEDAにIstioを導入した背景を教えてください。

阿南 マイクロサービスの運用を楽にしたいというのが一番の理由です。SPEEDAはサービス開始から10年が経っており、モノリシックな構成になっていました。その結果、開発が思うように進まなかったり、ひとつの修正が広範囲に影響を及ぼしてしまう状態になっていたため、マイクロサービスアーキテクチャを採用し、オンプレミス環境にKubernetesを構築したのです。

しかし、Kubernetesを導入後、クラスター外部からのアクセス設定やマイクロサービス間のネットワークなどが次第に複雑になっていくという課題が見えてきたんです。弊社では、今後もマイクロサービス化を推進していく方針をとっていますので、複雑化するネットワークをサービスメッシュ化する必要性も感じていました。そこでサービスメッシュを実現するためにIstioを試しに使ってみたところ、SPEEDAにマッチすると感じたので導入しました。

──導入して特にメリットに感じた部分はありますか。

阿南 マイクロサービス化された環境ではネットワークのルーティング周りに課題が多くありますが、それをIstioに集約できるので運用が楽になります。

例えばSPEEDAではブルーグリーンデプロイの複雑な設定がIstioによって解決されました。Istio導入前はサービスごとにBlue環境とGreen環境のエンドポイントを用意し、上位にあるApacheで切り替えるようにしていました。簡単な図にすると、以下のような構成です。

SPEEDAのシステム構成

しかし、この方法だとサービスごとに設定ファイルを作成し、Apacheでどちらにリクエストを送るか切り替えする必要があります。Blue/Greenでのリリースを採用しているため、常に一方の環境はクローズしておくといった状態をApacheが持つことになり、Apacheが意図せず再起動した際にBlueとGreenの環境を両方オープンしてしまう危険もありました。Istio導入のタイミングで、こういったルーティングの状態管理はIstioに任せることにしました。Istioを導入後の構成は以下のようになります。

SPEEDAの新システム構成

ApacheはIstioにリクエストをフォワードするだけでよくなるため、複雑な設定を管理する煩雑さから解放されますし、リリースのパイプラインも組みやすくなります。

──サーバの状態をIstioに任せられると安心してデプロイできそうですね。

阿南 そうですね。加えて、Istioではデプロイとリリースのタイミングを簡単に切り分けることができます。僕は、デプロイはアプリケーションを環境に配置することであり、リリースは配置したアプリケーションにアクセスがある状態と解釈しています。設定をひとつ変えれば特定のサービス(バージョン)にだけアクセスがいくようにもできるため、サービス単位で安心してリリース前に本番環境でテストができます。

──マイクロサービスでは分散トレーシングも課題視されますが、その点はいかがでしょうか。

阿南 そういった面もサービスメッシュにしておくと、課題を解決しやすくなります。Istioは送信と受信の両方向の通信をトレースできるため、ネットワークのログが追いやすいからです。また、Addonでistio-tracingを有効にしておくと、jeagerで簡単にリクエストを可視化できるので、例えば特定のブラウザからのリクエストが遅いとか、あるAPIを経由した時に遅くなっている、といった事象を簡単に発見できます。

マイクロサービスは「ひとつのサービスが落ちても運用を続けられる」と言われますが、例外的なケースもあるでしょう。実際に弊社で運用している際にも、ひとつのAPI障害により上位のバランサーに負荷がかかり、広範囲の障害に繋がったケースもあります。ですので、こうした障害が発生した場合に、どのマイクロサービスに問題があるのか即座に把握する必要があります。

また、弊社のように必ずしも全てのサービスがKubernetesで運用されていなかったり、外部サービスとのAPIがあったりすると、クラスター外の通信も考慮しないといけません。Istioを導入すると、アプリケーションがレスポンスを返す際にクラスター外のAPIにアクセスする必要があった場合でも、そのAPI呼び出しにどれだけ時間がかかったか取得することができます。実際の運用でも特定のAPIが遅く原因を調査したところ、実は別のAPIと通信している部分が遅かったということがあります。istio-proxyで双方向の通信をトラックすることにより、そのような問題もすぐに見つけることができます。

Istioのボトルネック

──nginxなどでプロキシを立てるだけだと外部の通信はトラッキングしにくいですからね。

阿南 プロキシを立てて同じことを実現するのは難しいと思います。それにIstioはPrometheusやGrafanaなどのログ監視系のソフトウェアとも連携しやすいという利点もあります。ログを収集して可視化しやすいので、よくできているなと感心します。

KubernetesやIstioは今までの技術の集大成

──Istioのメリットを強く感じますが、導入で苦労した点はありますか。

阿南 そもそもサービスメッシュという概念を理解すること自体が大変でした。サイドカーパターンも実際に触ってみないと利点が理解しにくいと思います。あとは単純に概念とレイヤーが増えるので、ネットワークは複雑になります。

Istioのサイドカー図

Podの中にWebサーバ以外の補助的な機能をもつサーバを立てる構成。Istio proxyの場合は、デフォルトでEnvoyというプロキシを利用する。通信をEnvoyに任せることができ、ネットワーク構成が変わってもアプリケーション側に影響がない。ひとつのコンテナに対してEnvoyをなぜインジェクトする必要があり、それによるメリットは何であるのかというのは阿南さんの言う通りドキュメントを読んでもつかみにくい。

──ネットワークが複雑になってもIstioを導入するメリットの方が大きいと感じますか。

阿南 そこはトレードオフだと思います。SPEEDAではネットワークを複雑にする代わりにアプリケーションをシンプルにするという選択をしました。

サイドカーパターンはアプリケーションに変更を加えず設定ができるため、ネットワークの共通処理を任せることができます。アプリ側でアクセス量によって許可や拒否を実装するのは大変です。そういったネットワークの処理はサイドカーに一任することでアプリをシンプルに保つことができます。

──ネットワークの仕組みが変わるので導入は大変そうですね。

阿南 導入は大変でした。まだまだIstioも発展途上のプロダクトなのでバグも多く、自分の手順が悪いのかIstioのバグなのか分からなくなることがよくありました(笑)。

また、ネットワークが複雑になり通信の流れを把握しにくくなるため、tcpdump、iptables、netstatなどの基礎的なコマンドを使い通信の流れを整理していきました。tcpdumpのログを見て「このPodまでは通信きているな」といったように把握していったんです。導入してみて分かったのは、Istioを本格的に自分たちで管理して運用するためにはネットワークの基礎を理解している必要がある、という点です。

ひとつTips的な話ですが、Istio proxyには前述のネットワーク系のコマンドが入っているので調査はしやすいと思います。コンテナでは容量を圧縮するためにコマンドも削って「curlが入ってない」ということもありえますが、こうしたケースでは便利ですね。

──ネットワークの複雑化やバグのリスクを考えると、シンプルに「便利だから導入しよう」と判断するのは難しいかもしれませんね。

阿南 マネージドIstio等を利用するとまた状況が変わるかもしれませんが、本気で自社運用しようと思ったらネットワークの流れを理解しないとトラブルに対応できないと思います。Kubernetesもそうですが、Istioは過去から連なる技術の集大成だと感じます。理解するためにそれ相応のスキルが要求される印象があるのは事実です。

阿南さん横顔

──導入時のコツはありますか。

阿南 Istioによって作成されるコンポーネントの意味をひとつずつ理解していくことが一番の近道だと思います。インストールするだけでPodも一気に作成されるので、各Podの役割を把握して、control planeとdata planeの通信がどのように行われているのかを把握すべきでしょう。

もうひとつ、「何を解決したくてIstioを導入するのか」をはっきりしておくことが重要だと思います。弊社の場合、ルーティングやリリースの柔軟性、通信の透過性を高めるために導入したので、そのために必要な機能のみ適用しています。繰り返しますが、Istioはまだ発展途上のプロダクトですので、不安定な面もあります。いきなり全機能を有効にしてしまうと、どこで問題が起きているのか分からなくなってしまいます。例えば、mTLSが必須ではないケースであれば、最初は無効にしておいたほうがデバッグが簡単になります。通信のデバッグ時に、アプリケーションレベルの認証が入ってくるとさらに難易度が上がってしまいますので。

運用したからこそわかるIstioのハマりポイント

──先に「Istioはまだまだバグが多い」という話もありましたが、他にはどんなハマりどころがありましたか。

阿南 導入時も運用時もかなりハマりどころはありましたね(笑)。ぜひお伝えしておきたいのは「設定の反映が遅延する」「エンドポイント登録がnamespase単位で分かれていない」「istio-proxyの制限にひっかかる」という3つです。

ハマりどころ1:設定の反映が遅延する

──ひとつめの、設定の反映が遅延する、というポイントを教えてください。

阿南 Istioでは基本的にコントロールプレーンに分類されるIstio pilotで設定を反映しています。設定を変更したときにIstio pilotがリクエストを受けて、PodにinjectされたEnvoyに反映させます。

Istioのアーキテクチャ

Istioのサービスメッシュは大きく分けてコントロールプレーンとデータプレーンに分かれる。

しかし、この設定反映がうまくいかないときがあるのです。普段は数秒で反映されるのですが、5分くらいかかることもあって(笑)。Istioのバージョンが上がるにつれて品質は上がっていますが、一部のPodにだけ設定が反映されるという事象も散見されます。本番でこれが起きるとつらいですね。

──この問題はどのように対処したのでしょうか。

阿南 IstioではデフォルトでEnvoyというプロキシが使用されていますが、ルーティングを担当するポートと設定管理を担当するポートの2種が立ち上がります。後者の設定管理ポートに/config_dumpというエンドポイントがあり、アクセスすると現在の設定を確認することができます。

導入当初は、この設定と僕らが設定した項目を目視で見比べたりもしていました。これが結構つらい作業で、最初にIstioに触れた感動から一転、心が折れそうになりました(笑)。

──手動で全て確認するのはつらいですね……。

阿南 今はistioctl proxy-statusコマンドでIsito proxyへの設定反映が簡単に確認できようになっていて、各Podへの設定がどの程度同期されているのかがパーセンテージで表示されます。同期がなかなかされないときはIstio pilotを再起動するなど、対処がしやすくなりました。

ハマりどころ2:エンドポイント登録がnamespase単位で分かれていない

──2つ目のエンドポイント登録に関するハマりどころ、とはなんでしょうか。

阿南 Istioでは外部通信するときにエンドポイントを登録(ServiceEntry)します。例えばAWSやGCPのドメインにアクセスするためにはそれぞれを設定ファイルに記載します。この設定が現状だとnamespase単位で分かれておらず、クラスタで共通の設定になっています。これによって他のnamespaceで同じドメイン名の設定がされていた場合、意図しないエンドポイントにアクセスしてしまう可能性があります。

エンドポイント以外の設定に関してはnamespase単位で独立しているのですが、エンドポイント登録だけはクラスターごとに設定します。ここは知らないとハマるポイントだと思います。

──この仕様を理解していないと、違うアプリへのDBアクセスなど起きてしまいそうですね。どういった対策をしているのでしょうか。

阿南 今のところはサービスごとに設定ファイルを独立管理せず、共通リポジトリで管理するようにしています。機能として足りないところは運用でカバーするという形をとっています。

ハマりどころ3:istio-proxyの制限にひっかかる

──最後の「istio-proxyの制限」とはどのような注意点でしょうか。

阿南 istio-proxyの実態はEnvoyになりますので、Envoyの制限も考慮する必要があります。例えば、最大のリクエストヘッダーサイズがEnvoyの上限よりも大きくなってしまう場合は、うまくリクエストが処理されません。これは、他のパラメータについても同様のことが言えると思います。一部のエンドポイントだけが正常に動作しない時などは、istio-proxyの設定値も確認してみると良いと思います。

ちなみに、特定のistio-proxyのみに適用したい設定値がある場合はKubernetesのConfigMapに適用したいEnvoyの設定を定義した上で、Deploymentのannotationsで sidecar.istio.io/bootstrapOverride: "istio-custom-bootstrap-config" を設定することにより、適用が可能です。詳細は公式のGitHubに記載があります。

使っている人に聞いてみた「Istio-proxyを経由すると10ms遅くなる?」

ユーザベース阿南さん横顔2

──さて、「Istio-proxyを入れると10ms遅くなる」という事象も議論を呼んでいます。実際に運用されていて、この点に関してはどのように感じますか。

阿南 1リクエストに対して細かい通信が大量に発生するような種類のアプリでは問題になるケースがありました。例えば、APIに対してリクエストを送ると、10回のDBアクセスが発生する場合、DBのPodにistio-proxyがinjectされていると明らかに速度が遅くなることがあります。その場合は、Deploymentのannotationでsidecar.istio.io/inject: "false"を設定しておくと対象Podはistio-proxyをinjectしないように設定を変更することができますので、検討すると良いと思います。

また、僕が以前担当していた広告系のプロダクトでは、リクエストに対して100ms以内でレスポンスする必要がありました。そういったプロジェクトにおいて、もしも10msの遅延が発生するとしたら、無視できない問題でしょう。複数のマイクロサービスを経由することによりIstio-proxyを複数経由すれば、もっと時間がかかると考えられますから。

──速度を保ちつつ、アーキテクチャを変えるのはやはり難しいのでしょうか。

阿南 そこはトレードオフかなと思っています。レイテンシをあげても全体的にリクエストを透過的にするというのがIstioのメリットです。

通信がクリアな状態を優先し数msの速度低下を許容するのか、速度優先にするのか、その判断基準はサービスの特性によると思います。ただ、Istioのデフォルトの機能をオフにして、ある程度の機能を犠牲にする、というチューニングもひとつの方法だと思います。公式でもIstio-proxyのレイテンシーは以前10msだったものが8ms(90th percentile)になっていますし、速度の改善はもっと追求していきたいですね。

Istioの導入はアーキテクチャだけでなく、組織の動きも変わる

──Istioを導入してネットワークが変わっていくと、会社内のチームの動きも変わっていきそうですね。

阿南 おっしゃる通りで、1チームだけで導入しようしても上手く活用できないと思います。ネットワーク含め、インフラ基盤に精通しているSREチームと、アプリケーションのアーキテクチャに精通する開発チームが協力し合う組織体制が必要になると思います。マイクロサービスやサービスメッシュを導入することにより、組織自体も変わっていくのではないかと思います。

──実際に導入して社内の動きは変わりましたか。

阿南 SREチームと開発チームが近くなった感覚はあります。弊社の場合、基盤構築等を担当しているSREチームと各マイクロサービスの開発・運用を担当している開発チームがありますが、今までのSREチームの業務は開発チームからの依頼を受けて、環境を構築、整備するということが多く、アクションが受け身になりがちでした。

しかし、弊社ではIstioを導入のタイミングでSREチームのメンバーが各マイクロサービスの開発に参加して、環境構築やCI/CDのパイプライン作成などを共同で実施するように動き方を変えました。その結果、SREチームはただ基盤を整えるチームではなく、共同でサービスを開発しているんだという意識に変わりつつあるように感じます。システム設計と組織設計は交互に影響する、「コンウェイ(逆コンウェイ)の法則」がぴったり当てはまっていると思います。

──なるほど、アーキテクチャだけでなく社内の意識も変わっていったのですね。そういった点を踏まえて、どのようなサービスだとIstioの導入を検討したほうがいいでしょうか。

阿南 まずはサービスの特性ありきだと思うので、一言で回答するのは難しいですね……(笑)。個人的には、特にオブザーバビリティ(可観測性)は重要だと考えていて、ここに貢献するのがIstioであり、サービスメッシュという概念だと思います。

  • マイクロサービスを運用していて、どこにボトルネックがあるのか分からない
  • マイクロサービス間の通信が把握できなくなってきた
  • リリースをシンプル・柔軟にしたい

今回お話した観点で言うと、こういった課題や要望があれば、導入を検討する価値はあると思います。

──では、逆にIstio導入を検討する必要がない、というのはどんなケースだと思いますか。

阿南 そもそもマイクロサービス化を実施する必要がなかったり、マイクロサービスだとしても今後サービスが増えていく予定がない場合などが該当すると思います。また先にお話したレイテンシーがサービス要件に合わないようなケースではサービスメッシュやIstioの導入はコスト面を考慮すると見合わないと思います。

ユーザーベース阿南さん横顔3

──Istioにおいて今後作業をしていきたい点や、手をつけていきたい箇所などはありますか。

阿南 やはりまずはKubernetesとIstioで運用ができるようにマイクロサービスを増やしていきたいですね。モノリシックになってしまっているサービスが多いので少しずつ移行したいと思っています。

Istio自体がまだまだベストプラクティスがない状態です。Web上でも情報が少ないですし、どう扱ったらいいのかまだまだ知見も足りない部分もあります。DevOps的な観点から、どのような方法であればキレイに運用ができるのか突き詰めていきたいですね。

【修正履歴】図版中の文言をご指摘により修正しました。〔2019年6月5日〕

関連記事

取材:megaya megayaのブログ