NGINX PlusでDNSサービスディスカバリの動作確認をやってみた!
動的にサービスやアプリケーションのIPアドレスが変わってしまうような環境がクラウドの普及によって増えてきました。
そういった際に有効なNGINX PlusでDNSサービスディスカバリの動作確認をやってみましたので最後まで読んでいただければ幸いです!
はじめに
こんにちは、皆さんはNGINX使ってますか?
最近、NGINX Plusでしかできない機能についてご質問されることが増えたので今回はその中からDNSサービスディスカバリ機能を検証してご紹介したいと思います。
DNSサービスディスカバリとは?
DNSサービスディスカバリとは、動的なIPアドレス管理の課題を解決するための機能です。
例えば、クラウド環境やコンテナ環境では、インスタンスの起動・終了が発生するたびにIPアドレスが変動することがあります。
このような状況でDNSサービスディスカバリを利用すると、サービスごとにDNS名を登録することが可能になります。
他のサービスはそのDNS名を通じてアクセスできるため、手動でIPアドレスを管理する必要がなくなり、サービス間の通信を簡素化し、運用効率を向上させることができます。
NGINXでのDNSサービスディスカバリ
NGINXでは、リバースプロキシとして動作しながら後段にあるサーバー宛にロードバランサとして分散処理することが可能です。
こういった構成の場合に転送先のサーバーのIPアドレスが動的に変わるサーバーだった場合にDNSサービスディスカバリが活用されます。
ただし、NGINX(OSS、Plusともに)ではリクエストを転送しようとする際に初回の名前解決結果がキャッシュされるためアプリケーション側のIPアドレスが動的に変わった場合に正しくアクセスできなくなります。
(NIGNXプロセスを再起動すればキャッシュが消えるので、解決するようですが現実的ではないですよね。)
NGINXで、この課題を解決するためには、upstreamブロック内のserverディレクティブにresolveを設定することで解決ができるようなので動作を確認してみたいと思います!
確認したいこと
NGINX Plusでresolveなどの設定を実施してアプリケーションへのアクセスを実施します。
問題なくアクセスできたら、アプリケーションのIPアドレスを変更したあとに再度アクセスをして問題なくアクセスができることを確認してみます。
今回はせっかくなのでresolve設定をする前にどういう動きになるかも動作確認してみます。
構成イメージ
今回は以下の構成で動作を確認していこうと思います。
リクエストはNGINX Plusをインストールしているサーバーから実施します。
検証および動作確認
STEP1:NGINX Plusの設定
default.confを以下のように設定します。
upstream backend {
zone backend_zone 64k;
server test123.nishikawa.dev.tedlab.net;
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
NGINX Plusのプロセスを以下のコマンドで再起動して設定を反映します。
$ sudo service nginx reload
STEP2:resolveを設定する前にアプリケーションにアクセス
test123.nishikawa.dev.tedlab.netに対してcurlでアクセスを実施します。
結果としては以下の様に正常にアクセスが可能です(通常のCurlだと出力が長いので-IでHTTPレスポンスヘッダーのみ取得したものを貼り付けています)。
$ curl test123.nishikawa.dev.tedlab.net -I
HTTP/1.1 200 OK
Date: xxx
Server: Apache/2.4.62 (Debian)
X-Frame-Options: SAMEORIGIN
X-Powered-By: PHP/8.1.30
Cache-Control: max-age=0, must-revalidate, private
X-Debug-Token: dd20c3
X-Debug-Token-Link: http://test123.nishikawa.dev.tedlab.net/_profiler/dd20c3
X-Robots-Tag: noindex
Expires: xxx
Set-Cookie: maintenance_token=deleted; expires=Sun, 10 Dec 2023 02:32:27 GMT; Max-Age=0; path=/; httponly
Set-Cookie: eccube=kfgjhh56m7k7einps16sejtbf2; path=/; httponly
Vary: Accept-Encoding
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Type: text/html; charset=UTF-8
STEP3:アプリケーションのIPアドレスを変更して再度アクセス
DNSサーバーにてtest123.nishikawa.dev.tedlab.netに紐づいているIPアドレスを変更して再度Curlを実施します。
結果としてはSTEP2の時にアクセスしたDNSのキャッシュが残っているため、レコード変更前のIPアドレスに問い合わせをしてしまうため、以下の結果通り前段のNGINX Plusから504エラーが返ってきており、うまくアクセスができません。
これはNGINXがデフォルトの動作として1度しか名前解決をしないためこのような動きとなってしまいます。
$ curl test123.nishikawa.dev.tedlab.net
<html>
<head><title>504 Gateway Time-out</title></head>
<body>
<center><h1>504 Gateway Time-out</h1></center>
<hr><center>nginx/1.27.2</center>
</body>
</html>
STEP4:NGINX Plusにresolveの設定を実施
STEP1の設定にresolveの設定を追加してみます
upstream backend {
zone backend_zone 64k;
server test123.nishikawa.dev.tedlab.net resolve; #動的にホスト名をDNSで解決するようにserverのドメイン指定の後にresolveを設定
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
NGINX Plusのプロセスを以下のコマンドで再起動して設定を反映します。
$ sudo service nginx reload
STEP5:アプリケーションにアクセス
test123.nishikawa.dev.tedlab.netに対してcurlでアクセスを実施します。
結果としては以下の様に正常にアクセスが可能(通常のCurlだと出力が長いので-IでHTTPレスポンスヘッダーのみ取得したものを貼り付けています)。
$ curl test123.nishikawa.dev.tedlab.net -I
HTTP/1.1 200 OK
Date: xxx
Server: Apache/2.4.62 (Debian)
X-Frame-Options: SAMEORIGIN
X-Powered-By: PHP/8.1.30
Cache-Control: max-age=0, must-revalidate, private
X-Debug-Token: dd20c3
X-Debug-Token-Link: http://test123.nishikawa.dev.tedlab.net/_profiler/dd20c3
X-Robots-Tag: noindex
Expires: xxx
Set-Cookie: maintenance_token=deleted; expires=Sun, 10 Dec 2023 02:32:27 GMT; Max-Age=0; path=/; httponly
Set-Cookie: eccube=kfgjhh56m7k7einps16sejtbf2; path=/; httponly
Vary: Accept-Encoding
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Type: text/html; charset=UTF-8
STEP6:アプリケーションのIPアドレスを変更して再度アクセス
DNSサーバーにてtest123.nishikawa.dev.tedlab.netに紐づいているIPアドレスを変更して再度Curlを実施します。
結果としてはSTEP3の際とは異なり、問題なくアクセスができました。
$ curl test123.nishikawa.dev.tedlab.net -I
HTTP/1.1 200 OK
Date: xxx
Server: Apache/2.4.62 (Debian)
X-Frame-Options: SAMEORIGIN
X-Powered-By: PHP/8.1.30
Cache-Control: max-age=0, must-revalidate, private
X-Debug-Token: dd20c3
X-Debug-Token-Link: http://test123.nishikawa.dev.tedlab.net/_profiler/dd20c3
X-Robots-Tag: noindex
Expires: xxx
Set-Cookie: maintenance_token=deleted; expires=Sun, 10 Dec 2023 02:32:27 GMT; Max-Age=0; path=/; httponly
Set-Cookie: eccube=kfgjhh56m7k7einps16sejtbf2; path=/; httponly
Vary: Accept-Encoding
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Type: text/html; charset=UTF-8
resolveの設定をすることで、名前解決結果のキャッシュを保持し続けずに定期的に取得することができるようになりましたのでドメインに紐づいているIPアドレスが変わっても正常にアクセスをすることができるようになりました!
まとめ
今回はNGINX PlusのDNSサービスディスカバリの機能を確認してみました!
NGINX OSSの場合はプロセス再起動でしか名前解決のキャッシュを削除できませんがresolveの設定をすると、わざわざプロセス再起動をしなくて便利だなと感じました。
※本ブログを執筆中にNGINX OSSにおいてもupstreamブロック内のserverディレクティブでresolveを利用できるようになったようです。
詳細はこちら
アプリケーション側のIPアドレスが頻繁に変わる可能性のあるクラウド上のサービスでは今回のDNSサービスディスカバリの機能は非常に有効かと思います。
次回もNGINX Plusの機能について動作確認をしていきたいと思っていますのでお楽しみに!