この記事は Nikkei Advent Calendar 2021 の 12 日目の記事です。
こんにちは。SRE チームの山崎です。 日経の SRE チームでは運用や監視の共通化を進めており、その一環として共通アプリケーション基盤「Vessel」を開発・運用しています。 例えば日経電子版の Web サイトはこの Vessel 基盤上のマイクロサービスとして稼働し、日々みなさまへニュースをお届けしております。 本エントリでは、Vessel 基盤におけるサービスメッシュ運用の現状と今後の改善に向けての検証の取り組みについてご紹介します。
TL;DR
- Anthos Service Mesh (ASM) で Google Cloud のサポートを受けて楽をする
- Managed ASM を利用することでサービスメッシュのアップグレードから解放される
- GKE Autopilot + Managed ASM ですべてがマネージドに!
はじめに
Vessel は Kubernetes をベースとしたアプリケーション基盤で、 Google Cloud の Google Kubernetes Engine (GKE) を利用して構成されています。 また、柔軟なトラフィック制御と統一的なモニタリングを実現するために、サービスメッシュを導入しています。 サービスメッシュといえば OSS である Istio がデファクトスタンダードになっていますが、Vessel では Anthos Service Mesh (ASM) を採用しています。 ASM は Google Cloud のプロダクトのひとつである Anthos ファミリーのサービスメッシュ機能で、Istio をベースとしているものです。
サービスメッシュの運用負荷
Vessel では、主にサービスメッシュの運用負荷を軽減することを目的に ASM を導入しています。
Vessel の提供以前も日経電子版の Web サイトは、GKE と OSS の Istio による専用基盤で稼働していました。 しかし、OSS の Istio をいざ運用するとなると小規模なチームでは運用負荷が高すぎる課題がでてきました。 例えば Istio の不具合に起因する障害が発生した際には、SRE チームのメンバー数人で何日もかけて原因を調査したこともありました。 さらに、原因が Istio にあることを突き止めたとしても、修正リリースをアップデートすることも困難でした。 これは、日経電子版がニュースメディアということもあり高い信頼性が要求され、サービスメッシュのようなコアコンポーネントを容易に変更することができなかったためです。 そのため、変更の適用にはさらに何週間もの追加検証が必要となっていました。
ASM を採用して Google Cloud のサポートを受ける
このような痛みを経験したこともあり、Vessel 基盤では ASM を採用しました。 ASM を導入することによるメリットは、 Google Cloud のサポートが受けられる という点が大きいです。 Vessel の開発・運用は SRE チームで行なっていますが、Vessel にかかりきりで作業できる専門のエンジニアはいません。 このようにエンジニアリングリソースが限られている中で、サービスメッシュのサポートを受けることができるのは非常に効果的でした。 Istio のトラブルシューティングやアップグレード時の懸念点など ASM の領域はもちろん、本家の Istio の領域についても Google Cloud の丁寧なサポートを受けることができます。 このようにして、サービスメッシュの運用負荷をある程度は軽減することができています。
ASM のバージョンアップも運用負荷が高い
Google Cloud によるサービスメッシュに関するサポートを受けることで、トラブルシューティングや検証などの運用負荷は下げることができました。 しがしながら、現時点で Vessel にはまだ、サービスメッシュの運用において負荷が高いものがあります。 それは、ASM のアップグレードです。
ASM は Istio をベースとした Google Cloud のプロダクトではありますが、 運用・管理自体はユーザが行なう必要があります。 バージョンのアップグレード作業もそのひとつです。 そのため、ASM のコントロールプレーン (e.g. Istiod) とデータプレーン (e.g. Ingress Gateway や Sidecar Proxy) のアップグレードは、我々ユーザが実施する必要があります。 (それらがマネージドとなる機能がリリースされてきていますが、それは後述します)
GKE クラスタ上で ASM を利用する場合の管理領域を図に示します。 ご覧の通り、GKE の Kubernetes Master ノードは Google Cloud が管理してくれますが、それ以外の Kubernetes Worker ノード、ASM のコントロールプレーン、データプレーンはユーザ自身が面倒を見る必要があります。

ここから少々具体的な話になります。 ASM のインストールやアップグレードには、Google Cloud から提供されている asmcli というスクリプトを利用します。 これを利用することで ASM のコントロールプレーンのインストールやアップグレードを行なうことができます。 しかしながら、データプレーンのアップグレードは私たち運用者が実施する必要があります。
ASM を導入した場合のおおまかなアップグレードプロセスは次のようになります。
asmcli
スクリプトを実行して、コントロールプレーンのアップグレードを行なう- Ingress Gateway や Sidecar Proxy をインジェクションする namespace のラベルを変更し、利用する ASM のバージョンを指定する
- ラベルを設定した namespace の deployment を再起動 (
kubectl rollout restart deployment
) することで、データプレーンコンポーネントが入れ変わる
asmcli
コマンドは以下のようなイメージです。(あくまでイメージです)
$ asmcli install \
--project <PROJECT_ID> \
--cluster_location asia-northeast1 \
--cluster_name managed-asm-cluster \
--fleet_id <PROJECT_ID> \
--verbose \
--output_dir managed-asm-cluster \
--enable-all
このように Google Cloud によりスクリプトが提供されており、 比較的容易にコントロールプレーンのアップグレードを実施することは可能 なのですが、 データプレーンは手動でオペレーション を行います。
そのためには、データプレーンコンポーネントを含む namespace の istio.io/rev
ラベルを指定して、ワークロードを再起動することが必要です。
$ kubectl label namespace <NAMESPACE> istio.io/rev=asm-1104-14 --overwrite
$ kubectl rollout restart deployment -n <NAMESPACE>
現状のサービスメッシュ運用と課題
ここまでで Vessel におけるサービスメッシュ運用の現状を説明しました。 簡潔にまとめると次のようになります。
現状の運用
- サービスメッシュには Anthos Service Mesh を採用している
- Google Cloud のサポートを利用することで、調査や検証などの負荷をある程度軽減している
- Google Cloud から提供されるスクリプトにより、アップグレード作業の一部を自動化できている
OSS の Istio を運用していた頃と比較すると、運用負荷はかなり軽減されました。 しかしながら依然として次のような課題があります。
現状の課題
- スクリプトが提供されているとはいえ、まだまだ運用負荷が残っている
- 人間によるオペレーションにはミスが発生してしまうものであり、心理的安全性が高いとは言えない
- サービスメッシュのオペレーションにおいてミスが発生してしまうと、 サービスの信頼性にも大きな影響を与える可能性がある
そこで SRE チームではこれらの課題を解消するために改善を進めています。 それらの検証の取り組みについて続けて紹介します。
Google-managed Control Plane で楽をする
ASM の Google-managed Control Plane という機能が 2021 年 6 月に GA になりました。 これはその名の通り、コントロールプレーンを Google Cloud が管理してくれる というものです。 つまり、コントロールプレーン (istiod) の管理から私たちは解放され、アップグレードも自動で行なわれるということです。すばらしい!

asmcli
を利用することで、以下のように Google-managed Control Plane の ASM をインストールすることができます。 --managed
オプションを追加しています。
$ asmcli install \
--project <PROJECT_ID> \
--cluster_location asia-northeast1 \
--cluster_name managed-asm-cluster \
--fleet_id <PROJECT_ID> \
--managed \ # managed オプションを追加
--verbose \
--output_dir managed-asm-cluster \
--enable-all
インストールが完了したら、istio-system
namespace を覗いてみます。
$ kubectl get pod -n istio-system
No resources found in istio-system namespace.
istiod が存在しませんね。やはり、我々の管理下にはないようです。
Google-managed Control Plane では、3 つのリリースチャネルが用意されています。
リリースチャネルとは、ASM の自動アップグレードの戦略でありユーザごとの要求により選択することができます (GKE のリリースチャネルと同じ考え方です!)。
Rapid
, Regular
, Stable
の 3 つが用意されています。
Rapid はバージョンアップのリリースが早く最新の機能をいち早く試すことができ、逆に Stable は他のリリースチャネルで十分な検証がなされた安定性の高いバージョンが利用できます。
利用したいリリースチャネルは、データプレーンの namespace に isito.io/rev
ラベルで指定します。
例えば、Rapid チャンネルを利用したい場合は、 サービスや Ingress Gateway が稼働する namespace に istio.io/rev=asm-managed-rapid
ラベルを付与します。
それぞれのリリースチャネルと namespace に付与するラベルは次のようになっています。
リリースチャネル | istio.io/rev ラベル | 説明 |
---|---|---|
Rapid | asm-managed-rapid | ASM の新機能をいち早く利用できる。パッチアップデートが頻繁に行なわれ、コントロールプレーンが最新に保たれる。 |
Regular | asm-managed | ほとんどのユーザにおすすめ。最新機能が利用可能になる速度と安定性のバランスが取れている。 |
Stable | asm-managed-stable | 新機能よりも安定性が優先される。 Rapid, Regular に続いてリリースされるため、安定性が十分に検証されている。 |
詳細については Google Cloud のドキュメント を確認してください。
実際には以下のようなコマンドで namespace にラベルを付与することができます。
# For ingress gateway
$ kubectl label namespace ingressgateway-ns istio.io/rev=asm-managed-rapid --overwrite
# For services
$ kubectl label namespace service-ns istio.io/rev=asm-managed-rapid --overwrite
これにより、各サービス Pod には指定されたリリースチャネルに対応するバージョンの Sidecar Proxy が自動でインジェクションされます (Ingress Gateway は最初は自分でデプロイしますが、アップグレードなどは自動で行なってくれます)。
また、同じクラスタ内で namespace ごとに異なるリリースチャネルを同時に利用することもできるようです。
内部動作としては、istio.io/rev
ラベルに応じてそれぞれ異なるエンドポイントへ Mutation Webhook を飛ばして、対応するバージョンの Sidecar Proxy がインジェクションされるようです。
リリースチャネルに登録しておくことで、Google Cloud が自動でコントロールプレーンをチャネルに応じたバージョンに常にアップグレードしていってくれます。
我々が asmcli
スクリプトを実行する必要がなくなります。
一方で、データプレーンはというと、これまでの ASM (In-cluster の ASM) と同様で手動で再起動をする必要があります。
データプレーンのバージョンをコントロールプレーンのバージョンに追従するために、定期的に Ingress Gateway や Sidecar Proxy の再起動が必要になるわけです。
つまり、ASM のアップグレードに関してデータプレーンまわりのオペレーションが残ってしまいます。
Google-managed Data Plane でもっと楽をする
そこで Google-managed Data Plane の登場です。 こちらは 2021 年 8 月に Preview として公開されたばかりの機能で、 本エントリの執筆時点の 2021 年 12 月ではまだ GA にはなっていません。 GA となるまでに本エントリの内容から変更となる可能性がありますので、十分に注意してください。
Google-managed Data Plane は、 Google-managed Control Plane ではユーザが実施しなければならない データプレーンのアップグレードも Google Cloud が実施してくれる というものです。 (執筆時点では Stable チャネルでは利用できないようです。)

Google-managed Data Plane は、Google-managed Control Plane が有効なクラスタにおいて、データプレーンの namespace に annotation mesh.cloud.google.com/proxy='{"managed":"true"}'
を付与することで有効化できます。
# For ingress gateway
$ kubectl annotate namespace ingressgateway-ns mesh.cloud.google.com/proxy='{"managed":"true"}' --overwrite
# For services
$ kubectl annotate namespace service-ns mesh.cloud.google.com/proxy='{"managed":"true"}' --overwrite
Google-managed Data Plane では、コントロールプレーンがアップグレードされた後に、Ingress Gateway や各サービス Pod の Sidecar Proxy などのデータプレーンコンポーネントが自動で再起動・アップグレードされます。 アップグレードは、Pod Disruption Budget (PDB) を考慮しながら Pod を Eviction することにより実施されます。 通常のサービス運用においてもそうですが、PDB を正しく設定しておかないと意図しないサービス断が発生する可能性がありますので注意しましょう。
このように、Google-managed Control Plane と Google-managed Data Plane の両方を採用することにより、サービスメッシュのアップグレードという現在も残っている運用負荷の大部分を解消することができそうです。 ただし、Google-managed Data Plane がまだ現時点で Preview 段階であるため、すぐに採用!!とすることは難しいかもしれません。 また、PDB が考慮されてアップグレードが行なわれますが、できるならばユーザトラフィックが少ないオフピーク帯に実施されると嬉しいところです。 GKE においてメンテナンスの時間枠が指定可能であるように、Managed ASM でもある程度アップグレードが実施される時間がコントローラブルになることを期待しています。 これらは今後も継続的にウォッチして検証を継続したい機能ですね。
GKE Autopilot + Managed ASM で究極的に楽をする
最後はおまけ程度ですが。。。
つい最近の 2021 年 11 月に Managed ASM が GKE Autopilot クラスタで利用可能となりましたので早速試してみました。 こちらもまだ Preview 段階であり、 Rapid リリースチャネルのみで利用可能なので注意してください。
GKE Autopilot について簡単に補足しておくと、(誤解を恐れず言えば) フルマネージドな Kubernetes サービスで、GKE の実行モードの一つです。 Standard GKE クラスタでは、コントロールプレーン (Master ノード) は Google Cloud が管理しますが、Worker ノードなどは利用者管理となります。 一方で Autopilot モードの GKE クラスタでは、Worker ノードも含めて Google Cloud 管理となります。 そのため、Worker ノードのサイジングなど Kubernetes の運用上の Worker ノードに関する部分を意識する必要がなくなります。 詳しくは、GKE Autopilot の公式ドキュメント をご確認ください。
話を戻すと、Autopilot クラスタで Managed な ASM が利用可能となったということは、 Kubernetes の管理も ASM の管理も全部 Google Cloud が行なってくれる ということです。 デファクトともいえる Istio によるサービスメッシュを最小限の運用コストで実現でき、そして Kubernetes と Istio は常に最新の状態に保たれます。これはアツいですね!

Autopilot クラスタへ ASM をインストールするには、 asmcli
コマンドを利用します。
さらに experimental な機能であることから asmcli x
サブコマンドを用いてインストールするようです。
$ asmcli x install \
--projectp <PROJECT_ID> \
--cluster_location asia-northeast1 \
--cluster_name managed-asm-autopilot \
--managed \
--verbose \
--output_dir managed-asm-autopilot \
--use_managed_cni \
--channel rapid \
--enable-all
あとは、これまで同様に namespace に istio.io/rev=asm-managed-rapid
ラベルを付与すれば利用できます。
# For ingress gateway
$ kubectl label namespace ingressgateway-ns istio.io/rev=asm-managed-rapid --overwrite
# For services
$ kubectl label namespace service-ns istio.io/rev=asm-managed-rapid --overwrite
(ASM に慣れていれば) 20 分ほどで簡単にセットアップができます。 これだけで、すべてがマネージドな Istio 環境が手に入るのは驚きです。
試しに、Ingress Gateway をデプロイしてから、Google Cloud 製のマイクロサービスサンプルアプリ Online Boutique をデプロイして動作を確認しました。 Online Boutique は、10 個のマイクロサービスによるサンプルアプリケーションで、ASM の動作確認には最適です。 LoadGenerator もデプロイされるので、わざわざ自分でアクセスしなくても動作が確認できます。

Anthos Service Mesh のダッシュボードを確認します。 サービスのメトリクスが収集されているので、問題なく動作しているようです。 ASM のサービスメッシュのダッシュボードは、特に何もせずともサービスメッシュ上のアプリケーションの状態を可視化してくれて大変便利ですね。 また、簡単に SLO の設定などもできます。

GKE Autopilot クラスタ上で Managed ASM が利用できることを確認しました。 こちらもまだ Preview ですので、日経でプロダクション環境に導入するのは難しいですが、社内ツールなどでサービスメッシュが使いたくなった場合などに使ってみるのはアリだと思いました。 「サービスメッシュを使ってみたいけど、運用コストが...」とお考えの方は、ぜひ検討してみるとよいかもしれません。 今後の動向を要チェックです!
まとめ
いかがだったでしょうか。
日経の共通アプリケーション基盤 Vessel における、サービスメッシュの運用負荷を軽減する取り組みについてご紹介しました。 過去に Istio を運用した際の運用負荷の課題について、 Anthos Service Mesh (ASM) を導入することで改善を続けています。 ASM は新機能が続々とリリースされており、SRE チームでは運用負荷の軽減や新機能の導入にむけて検証を積極的に行なっています。
このように日経の SRE チームでは Anthos Service Mesh をはじめ、さまざまな先進的な技術を積極的に検証し取り入れています。 Kubernetes やサービスメッシュなどの最新の技術に触れながら、アプリケーション基盤の開発・運用を行なうことに興味のある仲間を募集しております。 ご興味を持たれた方、まずは話だけでも聞いてみたい方でも、カジュアル面談から実施しておりますので、ぜひ JOBS ページから気軽にご連絡ください!
明日は清水さんの「GKE Workload Metricsが実現する柔軟なメトリクス収集の世界」です。お楽しみに!