GremlinでSquidプロキシにネットワーク障害注入してみた

ラージエンタープライズによくある、プロキシで出口を1つに絞ったアーキテクチャのモデルについて、Gremlinを使ってネットワーク障害を注入してみました。
2020.07.30

こんにちは。AWS事業本部のKyoです。

プロキシで会社の全拠点のインターネット出口を1つに絞る。ラージエンタープライズによくある構成ではないでしょうか。

目的としては帯域節約やアクセス高速化、セキュリティの確保等かと思います。

今回は単純化したモデルを用いて、この構成にGremlinのネットワーク系の障害注入中(レイテンシ、DNS、ブラックホール)を実施してみました。

構成

EC2二台による構成です。

proxy, clientともにAmazon Linux2、t2.microを利用しています。 proxyにはSquidとGremlinをセットアップしています。Squidのコンフィグの変更は行っていません。

SquidとGremlinのセットアップ方法は以下のブログをご参照ください。

※GremlinはSTARTER以上のライセンスが必要となります。 ライセンスについてはこちらをご参照ください。

やってみた

コントロール

コントロールとして、clientから障害注入を行わない状態proxyを経由し、本ブログDevIOにアクセスしてみます。

計測はtimeコマンドを利用しました。プログラムの呼び出しから終了までにかかった時間であるrealに注目します。

time curl -x 10.80.254.241:3128 -L https://dev.classmethod.jp/
(略)
real	0m0.147s
user	0m0.010s
sys	0m0.005s

レイテンシ

一致するすべての出力ネットワークトラフィックに遅延を挿入します。

proxy500msのレイテンシを120秒間注入してみます。

同様にclientからDevIOにアクセスしてみます。

time curl -x 10.80.254.241:3128 -L https://dev.classmethod.jp/
(略)
real	0m6.084s
user	0m0.011s
sys	0m0.005s

体感レベルでもハッキリとレイテンシが分かりました。

もう一度実行してみます。

time curl -x 10.80.254.241:3128 -L https://dev.classmethod.jp/
(略)
real	0m7.590s
user	0m0.006s
sys	0m0.011s

若干ばらつきはありますが、500ms程度のレイテンシが注入されていることが分かります。

DNS

DNSサーバーへのアクセスをブロックします。

proxyにDNSサーバへのアクセスのブロックを120秒間実施してみます。 なお本構成においては、DNSによる名前解決はproxyが担当します。

time curl -x 10.80.254.241:3128 -L https://dev.classmethod.jp/
curl: (56) Received HTTP code 503 from proxy after CONNECT

real	0m35.014s
user	0m0.000s
sys	0m0.007s

30秒程度で503エラーが発生しましました。

また、一度エラーが発生したあと再びアクセスを行うと即座にエラーが返ってくるようになりました。

time curl -x 10.80.254.241:3128 -L https://dev.classmethod.jp/
curl: (56) Received HTTP code 503 from proxy after CONNECT

real	0m0.009s
user	0m0.006s
sys	0m0.000s

ブラックホール

一致するすべてのネットワークトラフィックをドロップします。

proxyにブラックホールを180秒間実施してみます。

time curl -x 10.80.254.241:3128 -L https://dev.classmethod.jp/
curl: (7) Failed to connect to 10.80.254.241 port 3128: Connection timed out

real	2m9.609s
user	0m0.010s
sys	0m0.000s

2分程度でタイムアウトが発生しました。DNSサーバのアクセスブロックとは異なるメッセージが確認できました。

※ 参考として、2分以上のレイテンシ注入でも同様のタイムアウトが確認できました。

所感

今回はプロキシにネットワーク系の障害注入を実施してみました。

多くの場合、プロキシは冗長化されていると思いますが、 上記で注入したようなネットワーク障害が発生した際に自信をもってフェイルオーバーされると言えるでしょうか?

自信をもってイエス!とはなかなか答えづらいかと思います。

とくにレイテンシに関しては、通信が遮断されないケースもあるので、検知することもなかなか難しいのではないかと思います。

これらに対するソリューションとして、AWS Well-Architected フレームワークの一節を引用します。

信頼性、障害の管理、REL 12 どのように信頼性をテストしますか?

カオスエンジニアリングを使⽤して回復⼒をテストする: 本番稼働前および運⽤環境に定期的に障害を挿⼊してテストを実⾏します。ワークロードが障害にどのように反応するかの仮説を⽴て、その仮説をテスト結果と⽐較して、⼀致しない場合はプロセスを繰り返します。本番稼働テストがユーザーに影響を与えないようにします。

これを機にプロキシで出口を1つに絞るメリット、デメリットを見直してみてはいかがでしょうか。

構成そのものを変えることはハードルが高くても、チューニングなど出来ることがあるかもしれません。

以上、何かのお役に立てれば幸いです。

あわせて読みたい