grasys blog
grasysブログ

NGINX PlusのLB機能:DNSディスカバリー

izumi

こんにちは、エンジニアのいずみです。

先日、東京エレクトロンデバイス(TED)様、F5ネットワークスジャパン合同会社様のご協力の元、NGINX Plus の機能検証を実施させていただきました。

前回まではtsunodaさんがブログを執筆していましたが今回は私が書いていきたいと思います。

どんな検証をしたのかの一覧紹介ブログは こちら

今回は検証した項目の中から、ロードバランサー機能の一部である「DNSサービス・ディスカバリ統合」機能をご紹介させて頂きます。

NGINXをロードバランサー、リバースプロキシとして利用した際にupstreamディレクティブ、locationディレクティブ内のproxy_passへ転送先サーバをドメインとして指定することがあると思います。

例えば以下のような設定です。

upstream backend {
    server server.backend-nginx.grasys.inc
}

location / {
    proxy_pass http://server.backend-nginx.grasys.inc:80;
}

このようにドメインを用いて転送先を設定した場合、NGINXは起動時に名前解決を行いIPアドレスをキャッシュします。

今回の例だと以下の内部IPをキャッシュすることになります。

# dig server.backend-nginx.grasys.inc +short
10.146.15.235

次にNGINXのconfigを変更せず、DNSの設定のみを変更して接続先のサーバを変更した場合どうなるのかですが、、、NGINXは新しい転送先サーバではなく起動時に名前解決したサーバへ転送してしまいます。

古い転送先(ここでは10.146.15.235)がもし停止していた場合接続エラーとなってしまいます。起動していたとしても古い方に転送されてしまうので問題ですね。これはDNSのTTL設定値に関係なくNGINXでキャッシュし続けます。

これを解決するためにはNGINXのreload、restartを行う事が必要になります。

せっかく転送先を意識しないようにドメインを利用しているのになんだか本末転倒ですよね。

また、マイクロサービス化したアプリケーションの場合も他のサービスを意識しないといけないのもなんだかなぁと言ったところですね。

ここまで、NGINXの名前解決のキャッシュのデメリットを書いてきましたが、これを解決するのがNGINX Plusの「DNSサービス・ディスカバリ統合」です。

「DNSサービス・ディスカバリ統合」では、OSS版NGINXではプロセスのreload、restartでしか解決できなかった名前解決キャッシュを以下のような設定を行うことで解決することができます。

Aレコード利用した設定例

resolver 169.254.169.254 valid=10s;


upstream backends {
  zone backends 64k;
  server server.backend-nginx.grasys.inc:80 resolve;
}

server {
  location / {
    proxy_pass http://backends;
  }
}

この設定例ではresolverで指定したDNSサーバに対してupstreamディレクティブで設定したドメインをvalidで指定した間隔で名前解決するようになります。

validの設定がない場合はDNSサーバ側で設定しているTTLの時間で更新が行われます。validの指定を短くすることでDNSサーバのTTLより早く更新されます。

※今回はGoogle CloudのCompute Engineで検証を行ったので内部DNSとして名前解決を行うインスタンスのメタサーバーのIP「169.254.169.254」を指定しています。内部 DNS による VM へのアクセス

先ほどの設定はDNSのAレコードを利用しましたが、SRVレコードを指定することもできます。

SRVレコードを利用した設定例

次はSRVレコードを利用した例を見ていきたいと思います。

resolver 169.254.169.254 valid=10s;

upstream backends {
    zone backends 64k;
    server server.backend-nginx.grasys.inc service=_http._tcp resolve;
}

server {
    location / {
      proxy_pass http://backends;
    }
}

resolverの設定は先ほどと同じですが、upstreamディレクティブでSRVレコードを指定しています。

下記のようなSRVレコードが登録していた場合、このNGINXへのアクセスは転送先のサーバへ50%ずつ振り分けられることになります。

0 50 80 server1.backend-nginx.grasys.inc.
0 50 80 server2.backend-nginx.grasys.inc.

NGINXのweightの設定で重み付けをすることもできますが、SRVレコードを使うことでも同じことができるようになります。

こちらを使えば稼働中のサーバでNGINXをreloadすることなく重み付けを変更することができます。

まとめ

今回は「DNSサービス・ディスカバリ統合」の内容を紹介させて頂きました。

NGINXが稼働しているサーバとバックエンドのサーバの管理が別チームだったり、管理している台数が多く内部IPでは管理が煩雑になるなので内部DNSを利用している場合などにはかなり使えるのではないでしょうか?

また、クラウド上のサービスでIPが変更される可能性がある場合なども利用できそうです。

マイクロサービスで開発チームが違う、マルチクラウド、オンプレミスとクラウドのハイブリッド構成などなどNGINXを利用してロードバランシング、リバースプロキシを構成する場合の1つの選択肢の一つとして検討してみてはいかがでしょうか?

以上、TED様とのブログリレーgrasysパートは今回が最後となります!

それでは、次回TED様のブログ公開をお楽しみに!!

« TED×grasys×F5 ブログ一覧 »
4月27日 NGINX Plusの検証をした! (grasys)
6月02日 grasys×F5×TEDが徹底解析!NGINX Plusの仕組みがよくわかる! (TED様)
6月09日 NGINX Plusのインストール方法とLBの基本設定 (grasys)
6月16日 NGINX PlusでJWT認証をやってみた! (TED様)
6月23日 NGINX PlusのLB機能:アクティブヘルスチェック&セッション維持 (grasys)