エイチームフィナジーアドベントカレンダー8日目は私 @NMura3 が担当します。
概要
サービス運用していると、プログラム言語やフレームワーク、OSやライブラリーのバージョンアップがつきまといます。
その際に起きてほしくはないですが、障害が発生してサービス停止する場合があります。
どんなに入念にテストしたり、準備をしても一定数発生してしまうことはありませんか?
そんな時に便利に検証できるのがGoreplayになります。
Goreplayとは
GoReplayはGoで開発されたOSSのネットワークモニタリングツールです。
https://goreplay.org/
流れてくるリクエストをキャプチャして、他のサーバーに同じリクエストを流すことができます。
つまり、テスト環境やステージング環境に本番にくるリクエストを流して、本番のリクエストでテストが可能になります。
また、リクエスト数も本番と同様になるので、負荷テストも可能です。
インストール
GOで開発されているのでインストールは非常に簡単で、パスの通ったディレクトリに実行権限をつけてダウンロードするだけです。
インストール例
export GOREPLAY_VERSION=1.3.3
wget -q -O - https://github.com/buger/goreplay/releases/download/${GOREPLAY_VERSION}/gor_${GOREPLAY_VERSION}_x64.tar.gz | tar -xz -C /usr/local/bin
注意) バージョンによって微妙にパスが違うので注意してください。
実行例
ポート(80番)を指定して標準出力に出す
gor --input-raw ":80" \
--output-stdout
ポート(80番)を指定してテスト環境にリクエストを流す
gor --input-raw ":80" \
--output-http https://test.example.com
ポート(80番)を指定してテスト環境に50%のリクエストを流す
gor --input-raw ":80" \
--output-http "https://test.example.com|50%"
ポート(80番)を指定してテスト環境にフィルターしたリクエストを流す
gor --input-raw ":80" \
--output-http https://test.example.com
--http-allow-url /path1 \
--http-allow-url /path2
HTTPサーバーやAPPサーバーにログインできるのであれば、上記コマンドを実行すると即座にリクエストを別環境に流してくれます。
Dockerなどコンテナで運用している場合はCIと組み合わせて実行すると便利です。
AWSのECS、GCPのCloudRunで使用する例をあげます。
AWS ECS + Goreplay
まずはDockerfileにGoreplayのインストールを記述します。
# Goreplay
ARG GOREPLAY_VERSION=1.3.3
RUN wget -q -O - https://github.com/buger/goreplay/releases/download/${GOREPLAY_VERSION}/gor_${GOREPLAY_VERSION}_x64.tar.gz | tar -xz -C /usr/local/bin
ENTRYPOINT
やCMD
で実行するシェル内にGoreplayの起動コマンドを記述します。
その際に環境変数から起動の有無をしておき、環境変数をCIから設定するようにしておくと便利です。
(通常はGoreplayを起動し、リクエストを流したい時に環境変数が設定されるCIのジョブでリリースするようにしておくなど)
if [ "$GOREPLAY_LISTEN" = "true" ]; then
gor --input-raw ":80" \
--output-http https://test.example.com
--http-allow-url /path1 \
--http-allow-url /path2 &
fi
※ &
つけて非同期実行しておきます。
ECSの場合はそれほど難しくなく、導入できると思います。
GCP CloudRun + Goreplay
Goreplayの場合はECSと同様に設定して実行しても起動できません。
下記のようなエラーが出ると思います。
PCAP Activate error: Permission Denied
パケットキャプチャができないというエラーです。
Goreplayはネットワークキャプチャするので、ネットワークデバイス(eth01とか)へアクセスします。
その際に呼ばれるのがioctl
というシステムコールなのですが、これがCloudRunの場合は制限を受けています。
CloudRunはgVisorというサンドボックス環境下で動いており、そこもドキュメントに下記の記述があります。
Only a few ioctls are implemented for backing devices and file systems.
これによりCloudRunではGoreplayを使えないと思っていたのですが、10月末にCloudRunあるプレビューリリースが行われました。
これによると、CloudRunの実行環境で第二世代がリリースされ、その第二世代ではシステムコールの制限を受けないというものです。
適用
第二世代についてはまだプレビュー版なので、それで本番環境を動かすことになるのでお気をつけください。
第二世代はCloudSDKを最新にあげて、betaコマンドをインストールするとSDKから使用可能です。
また画面からも設定はできます(私はしたことがないですが。。。)
CloudSDKでdeploy する場合は gcloud beta インストールをして、--execution-environment
のオプションをつけると第二世代を使用できます。
# インストール
gcloud components install --quiet beta
# 第二世代でdeploy
gcloud beta run deploy example_service --execution-environment=gen2
注意点
Goreplayを使う上で一つ重要なことがあります。
それは本番のリクエストに個人情報や機密情報があった場合には注意が必要です。
リクエストを流す先(テスト環境)に本番のリクエストが行くので、そのログやDBに個人情報や機密情報が入ってしまいます。
プロダクトやサービスによっては情報流出の原因となるので、そこは十分にご注意ください!!
まとめ
いかがだったでしょうか?
Goreplayはプログラム言語やフレームワーク、ライブラリーのバージョンアップ時に本番リクエストでテスト可能です。
また、プラットフォームの構成を見直す際に本番のリクエストで負荷テストが可能です。
エイチームフィナジーアドベントカレンダー16日にCloudRunでリリースされた、実行環境第二世代とAlwaysCPUの検証の際にGoreplayを使用した記事を投稿するのでお楽しみに