ユニファ開発者ブログ

ユニファ株式会社プロダクトデベロップメント本部メンバーによるブログです。

NLBで複数AZ構成での挙動

ちゃっす。 ユニファのインフラ鈴木です。

久しぶりのブログです。

花粉がすごいらしいですね!!
最近鼻水とか出ますけど、私は花粉症ではないので関係ないでしょうね…うん

前回に引き続きNLBの事をブログに書こうと思います。
あ、NLBはなんぞやというかたは、公式のブログをどうぞ

aws.amazon.com

NLBの何を書くかというと、複数のAZで複数のターゲットグループが設定されていた場合に、1つのターゲットグループが単一AZの利用になっていた場合どういう挙動になるのかなと言うものです。
では確認していきます。

1つのターゲットグループでAZの数を変えた時の挙動

ターゲットグループにdのインスタンス(正確にはECSのタスクですが…)が割当たっている状態 f:id:mominosin:20180316091106p:plain

名前解決すると1つだけ返る

'->$ nslookup sample-7955badb69cae298.elb.ap-northeast-1.amazonaws.com
Server:     192.168.11.1
Address:    192.168.11.1#53

Non-authoritative answer:
Name:   sample-7955badb69cae298.elb.ap-northeast-1.amazonaws.com
Address: 13.114.244.161

続いて別AZのインスタンスを割り当てる f:id:mominosin:20180316092313p:plain

initialだけどなんか結果かわった…いいのかな?
AZ(a)が増えた分名前解決から返ってくるのが1つ増えます

'->$ nslookup sample-7955badb69cae298.elb.ap-northeast-1.amazonaws.com 
Server:     192.168.11.1
Address:    192.168.11.1#53

Non-authoritative answer:
Name:   sample-7955badb69cae298.elb.ap-northeast-1.amazonaws.com
Address: 13.114.244.161
Name:   sample-7955badb69cae298.elb.ap-northeast-1.amazonaws.com
Address: 13.230.61.191

試しに返ってきたIPに直接リクエストなげてみたら同じように返ってきてるので両方利用できていますね。

'->$ curl sample-7955badb69cae298.elb.ap-northeast-1.amazonaws.com
<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>
'->$ curl 13.114.244.161
<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>
'->$ curl 13.230.61.191
<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>

その状態から1つ外してみてリクエストなげてみます。
するとタイミングの問題だと思うのですが、インスタンスの居ない方にリクエストを投げると通信できないですね。 f:id:mominosin:20180316094349p:plain

'->$ nslookup sample-7955badb69cae298.elb.ap-northeast-1.amazonaws.com
Server:     192.168.11.1
Address:    192.168.11.1#53

Non-authoritative answer:
Name:   sample-7955badb69cae298.elb.ap-northeast-1.amazonaws.com
Address: 13.230.61.191
Name:   sample-7955badb69cae298.elb.ap-northeast-1.amazonaws.com
Address: 13.114.244.161
'->$ curl 13.114.244.161
<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>
'->$ curl 13.230.61.191 
^C   # 返ってこないのでキャンセル

少し置くと名前解決で返ってくる値は1つになります

リスナーとターゲットグループを一つ追加しそちらは常に複数AZにしておく

NLBのリスナーに2つ目を追加し、ポート80と9292の2つで受けれるようにしています。
適当なアプリが欲しかったのでsinatraのアプリを利用してみています。(port:9292の方) f:id:mominosin:20180316101835p:plain

sinatraの方は複数AZ構成 f:id:mominosin:20180316102113p:plain 元々のECSのサンプルアプリは単一AZ構成 f:id:mominosin:20180316102132p:plain

このような状態で名前解決してみると1つしか返ってこないですね…
つまりNLBは少ないターゲットグループの方を優先するようです、 そうなると複数AZ設定している方は片方のリソースが無駄になってしまいますね。
利用側からするとそのほうが嬉しくて、両方のリージョンの名前が返ってくるようだと、単一AZのターゲットグループにリクエスト投げた際に、ターゲットが居ない方のAZにルーティングされてしまうと通信ができなくてリクエストがエラーになってしまいます。

'->$ nslookup sample-7955badb69cae298.elb.ap-northeast-1.amazonaws.com
Server:     192.168.11.1
Address:    192.168.11.1#53

Non-authoritative answer:
Name:   sample-7955badb69cae298.elb.ap-northeast-1.amazonaws.com
Address: 13.114.244.161

その為リソースを効率よく運用するのであれば、すべてのターゲットグループで複数AZを利用する必用があるようです。

クロスゾーンのオプションを有効にするとどうなるのか?

NLBにはクロスゾーン負荷分散というオプションが存在しています。(ALBにはない) f:id:mominosin:20180316102951p:plain

これを有効にしてみて名前解決してみると2つ返ってきますね。
クロスゾーン負荷分散オプションのおかげでNLB内でリージョン間通信が行えるようになったようです。

nslookup sample-7955badb69cae298.elb.ap-northeast-1.amazonaws.com 
Server:     192.168.11.1
Address:    192.168.11.1#53

Non-authoritative answer:
Name:   sample-7955badb69cae298.elb.ap-northeast-1.amazonaws.com
Address: 13.230.61.191
Name:   sample-7955badb69cae298.elb.ap-northeast-1.amazonaws.com
Address: 13.114.244.161

複数から単体に変更したタイミングだとリクエストが返って来なかったものも返ってくるようになりました。 この機能のおかげで、片方のターゲットが障害になって通信できなくなったとしても、もう片方のターゲットへリクエストが行くので小規模でサービスを提供するなら有効にしておいて損のないオプションなのかと思います。

'->$ curl 13.114.244.161 
<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>
'->$ curl 13.230.61.191 
<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>

調べてみたら、これは最近追加された機能だったらしいですね。
恒例のごとくクラスメソッドさんのブログで詳細が書かれていました。
ご興味ある方は参照ください。

dev.classmethod.jp

今回のNLBの挙動確認は以上です。

日々新しくなっていくAWSですが情報集めが大変ですね。 そんななか、もう少しでAWS Summitが開かれますが今年は東京だけでなく大阪も開かれるようでAWSの拡大が垣間見れます。
今年は私も久しぶりに参加してみて直接情報を集めようと思っています。

以上、コメント等あればお気軽にお願いします。

すずき