クックパッドのサービスメッシュ基盤を改善した話

こんにちは、技術部 SRE グループの ryojiro (@flyhigh_ro) です。今回はクックパッドでのサービスメッシュ基盤を改善した話を紹介します。クックパッドでのサービスメッシュの構成については以前の記事をご覧ください。

クックパッドでは多くのサービス間通信において Envoy を利用していますが、以下のような問題を抱えていました。

  • 改善前の Envoy のバージョンは v1.9.0 (2018/12 リリース) と古く、開発者はそれ以降に実装された機能を利用することが出来なかった。
  • CDS/RDS を cookpad/itacho によって生成しているため、 v1.9.0 で利用出来る機能であっても cookpad/itacho で実装されていなければその機能を利用できなかった。利用するためには cookpad/itacho にその設定を実装する必要があり、面倒だった。
  • cookpad/itacho で既に実装されている機能でも、ドキュメンテーションが不十分で目的の Envoy での設定に対応する itacho の設定が調べられず、cookpad/itacho の実装を調べることがあった。

上記の理由から、サービス開発者が Envoy v1.9.0 以降の機能や cookpad/itacho で実装されていない機能を利用したくても、すぐにその機能を利用することができずに、その機能を利用することを諦めることが何度かありました。SRE としては、サービス開発者にサービスメッシュを積極的に活用してもらいたいと考えていたので、サービスメッシュをもっと手軽に利用してもらうことを目的として、以下の内容でサービスメッシュ基盤を改善しました。

  • Envoy のアップデート
  • v1 xDS API の廃止
  • cookpad/itacho での itacho generate 廃止
  • xDS API の CI 整備

Envoy のアップデート

クックパッドで利用されている Envoy のバージョンは v1.9.0 と 2018/12 にリリースされた古いバージョンを利用していました。v1.9.0 でも機能としては十分でしたが、脆弱性が報告されていたり、古いバージョンを使い続けることでアップデートがどんどん大変になっていくことに懸念がありました。そのため、今回を機に最新のバージョンまで上げることにし、以降もバージョンアップしやすい環境を目指すことにしました。

段階的な移行

最初は Envoy を一気に v1.9.0 から v1.14.2 まで上げようと考えていましたが、以下の理由から一度 v1.12.0 にしてから v1.14.2 に上げることにしました。

v1.14.2 だと既に deprecated になっている設定があり、v1.9.0 と v1.14.2 で互換性のない設定があった

envoy.api.v2.route.HeaderMatcher.regex_match を例にすると、 v.1.14.2 では既に deprecated となっているため envoy.api.v2.route.HeaderMatcher.safe_regex_match へ移行する必要がありました。しかし envoy.api.v2.route.HeaderMatcher.safe_regex_match は v1.9.0 では実装されていません。一旦全ての Envoy を envoy.api.v2.route.HeaderMatcher.regex_match と envoy.api.v2.route.HeaderMatcher.safe_regex_match に対応しているバージョンへアップデートし、envoy.api.v2.route.HeaderMatcher.regex_match を envoy.api.v2.route.HeaderMatcher.safe_regex_match へと移行してから v1.14.2 にアップデートする必要がありました。

cookpad/itacho で利用しているライブラリの protobuf 定義が古く、v1.12.0 までの xDS リクエストにしか対応していなかった

cookpad/itacho で利用しているライブラリの protobuf 定義が古く、v1.13.0 以降の Envoy から送信される xDS request のデシリアライズに失敗していました。cookpad/itacho に原因があることはわかっていましたが、cookpad/itacho を開発した経験がなく、この対応にどの程度工数がかかるのか見積もることができませんでした。そこで、一旦 v1.12.0 へアップデートすることにして、その間に cookpad/itacho へ対応することにしました。

v1 xDS API の廃止

Envoy v1.10.0 で Bootstrap config の deprecated_v1 sds_config と command line config の –v2-config-only オプションが廃止、 v1.13.0 で v1 xDS API が廃止となりました。クックパッドではいくつかのアプリケーションで v1 xDS API を利用してたので、それらを全て v2 xDS API へと移行しました。Envoy 以外から v1 xDS API を利用しているアプリケーションもあったので、それらも v2 xDS API を利用するように変更しました。

cookpad/itacho での itacho generate 廃止

クックパッドでは CDS/RDS のレスポンスの生成に itacho generate を使用していました。itacho generate は指定された設定に沿って CDS/RDS を生成します。しかし、Envoy の設定名とそれを生成する itacho generate の設定名が一致していなかったり、ドキュメントが整備されていないことから、どのような記述をすればいいのかわからないとの声が上がっていました。実際に itacho generate の設定を確認するために直接実装を確認することもありました。また、新規の機能を利用する場合も cookpad/itacho へその機能を実装する必要があり、手軽に新規の機能を利用することが困難でした。これらの課題を解決するために、itacho generate で xDS API レスポンスを生成することをやめ、直接 xDS API レスポンスを記述するように変更しました。そのまま全てのレスポンスを記述すると冗長になってしまうので Jsonnet で記述するようにしました。共通の設定は関数化し、upstreams 毎に設定を libsonnet ファイルにまとめて、それらを import して利用することで簡潔に記述できるように工夫しています。以下は itacho generate での記述例とxDS API レスポンスをそのまま記述したときの例です。

itacho generate での記述例

https://gist.github.com/ryojiro/baac94ceb615949c7ea54e36ba94b70a

xDS API をそのまま記述した例

https://gist.github.com/ryojiro/cde4f0024cd29b6ed4ee10467519f1fb

このような記述にすることで、upstreams の設定を1箇所で管理しつつ、サービス毎に独自に upstream の設定を上書きすることも可能となっています。また、新しい設定を記述する時にも Jsonnet へ設定を追加するだけなので、手軽に Envoy の機能を利用できるようになりました。

xDS API の CI 整備

これまでは xDS API レスポンスを itacho generate によって生成していたので、正しい xDS API の形式となっていることが保証されていました。しかし Jsonnet で xDS API レスポンスを生成するように変更したことで、生成される xDS API レスポンスが正しいことが保証されなくなってしまいました。そこで、CI を整備して生成される xDS API レスポンスが正しい形式となっていることを事前に検証するようにしました。Envoy のドキュメントを読むと mode オプションvalidate を渡して起動することで、Envoy の設定が正しいかを検証できそうでしたが、ネットワーク通信が発生しないので xDS API サーバーを立てて生成した xDS API レスポンスを検証することはできませんでした (静的な設定ファイルのみ検証されます) 。検証したいのは CDS/RDS のレスポンスで、Envoy の static_resources との設定はほとんど同じだったので、CI では設定した xDS API レスポンスを静的な設定ファイルに変換し、その設定ファイルで Envoy を起動することで、設定した xDS API レスポンスが正しい形式で記述されているかを検証するようにしました。クックパッドでは現在 v1.12.0 と v1.14.2 の Envoy が混在しているので、どちらも valid な設定のみ追加できるように、それぞれのバージョンで検証するようにしています。

最後に

今回はサービスメッシュをサービス開発者により手軽に利用してもらうために、サービスメッシュ基盤を改善した話を紹介させていただきました。この改善によって、実際にサービス開発者が新しい Envoy の設定を追加して利用する事例も生まれています。Envoy は比較的新しいアプリケーションでまだ知見も少ないと思うので、これからサービスメッシュ基盤の改善を考えている方の参考になれば嬉しいです。

このエントリを読んで興味を持った方や、数千の規模で Envoy が利用されているサービスメッシュ基盤を改善したい方はぜひ以下のサイトよりご応募ください。

クックパッド採用サイト: https://cookpad.jobs

/* */ @import "/css/theme/report/report.css"; /* */ /* */ body{ background-image: url('https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527163350.png'); background-repeat: repeat-x; background-color:transparent; background-attachment: scroll; background-position: left top;} /* */ body{ border-top: 3px solid orange; color: #3c3c3c; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; line-height: 1.8; font-size: 16px; } a { text-decoration: underline; color: #693e1c; } a:hover { color: #80400e; text-decoration: underline; } .entry-title a{ color: rgb(176, 108, 28); cursor: auto; display: inline; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; font-size: 30px; font-weight: bold; height: auto; line-height: 40.5px; text-decoration: underline solid rgb(176, 108, 28); width: auto; line-height: 1.35; } .date a { color: #9b8b6c; font-size: 14px; text-decoration: none; font-weight: normal; } .urllist-title-link { font-size: 14px; } /* Recent Entries */ .recent-entries a{ color: #693e1c; } .recent-entries a:visited { color: #4d2200; text-decoration: none; } .hatena-module-recent-entries li { padding-bottom: 8px; border-bottom-width: 0px; } /*Widget*/ .hatena-module-body li { list-style-type: circle; } .hatena-module-body a{ text-decoration: none; } .hatena-module-body a:hover{ text-decoration: underline; } /* Widget name */ .hatena-module-title, .hatena-module-title a{ color: #b06c1c; margin-top: 20px; margin-bottom: 7px; } /* work frame*/ #container { width: 970px; text-align: center; margin: 0 auto; background: transparent; padding: 0 30px; } #wrapper { float: left; overflow: hidden; width: 660px; } #box2 { width: 240px; float: right; font-size: 14px; word-wrap: break-word; } /*#blog-title-inner{*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-position: left 0px;*/ /*}*/ /*.header-image-only #blog-title-inner {*/ /*background-repeat: no-repeat;*/ /*position: relative;*/ /*height: 200px;*/ /*display: none;*/ /*}*/ /*#blog-title {*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-image: url('https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527172848.png');*/ /*background-repeat: no-repeat;*/ /*background-position: left 0px;*/ /*}*/