LINEで現役エンジニアに直接質問してみよう!登録無料

NginxでDNSの名前解決は起動時1回しか実行されないので注意!

この記事の概要

Nginxはリバースプロキシとして、Railsやwordpressなどのアプリケーションに処理を中継させる役割でよく使われます。

Nginxには、それを実現するためにデフォルトでproxy_passというディレクティブ(命令)がありますが、この時ドメイン名を使うとその名前解決は起動時の1回しか行われないというお話をします。

NginxはDNSレコードをTTLを無視する

DNSには、「この期間だけIPアドレスをキャッシュしてね!それ以降はまた問い合わせて!」という設定を書くことが出来ます。それをTTL(Time To Live: 生存時間)と言います。

本来はこの設定はDNSで同時に配信しているので、誰でも見ることができ、本来はそれに従うべきなのです。しかし、Nginxはそれを無視して、起動時の1回のみ問い合わせ後はキャッシュとして使い続けます。

そのため、IPアドレスが変わるドメイン名の場合、気が付かないタイミングで応答不能になっている場合があります。

なお、この情報はNginxのブログにしっかりと書いてありました。

NGINX caches the DNS records until the next restart or configuration reload, ignoring the records’ TTL values.
(NGINXは、次回の再起動または構成の再読み込みまでDNSレコードをキャッシュし、レコードのTTL値を無視します。)

参考: Just One POST: Enabling Declarative DNS with F5 and the NGINX JavaScript Module

解決方法の基本

解決方法があります。まずはソースコードを紹介します。

resolver 10.0.0.2 valid=10s;

server {
    location / {
        set $backend_servers backends.example.com;
        proxy_pass http://$backend_servers:8080;
    }
}

ポイントは2つあります

  1. 変数を使用してproxy_passディレクティブでドメイン名を指定
  2. resolverディレクティブでネームサーバーを明示的に指定する

この2つのポイントを押さえれば、NginxはDNSのTTLを無視して指定された頻度で再度、名前解決するようにNginxを設定出来ます。逆に、setディレクティブを使ってドメイン名を変数化しないと名前解決出来ません。

この設定では、10秒ごとに名前解決をするように指示しています。

MEMO

Linuxにはホスト名の名前解決手段として/etc/resolv.confを使うことが出来ますが、Nginxはその設定を無視します。そこに書いても機能しないので注意してください。

resolverはlocationの中にも書ける

上記の設定では、serverディレクティブの外(全てのserver)でresolverを設定していますが、server locationの中に書き、影響範囲を小さくするもできます。

このように、server内部に書いたり、、、

server {
    resolver 10.0.0.2 valid=10s;
    location / {
        set $backend_servers backends.example.com;
        proxy_pass http://$backend_servers:8080;
    }
}

location内部に書くこともできます。

server {
    location / {
        resolver 10.0.0.2 valid=10s;
        set $backend_servers backends.example.com;
        proxy_pass http://$backend_servers:8080;
    }
}

まとめ

  • nginxはDNSレコードをTTLを無視する
  • nginxは起動時の1回のみ名前解決をする
  • 動的な名前解決をするには2つのポイントを押さえよう
    1. 変数を使用してproxy_passディレクティブでドメイン名を指定
    1. resolverディレクティブでネームサーバーを明示的に指定する
  • resolverは、server location内部にも書ける

以上、NginxでDNSの名前解決は起動時1回しか実行されない問題とその解決方について、アキ(@hackablejp)が解説しました!

この記事を書いた人

自身がプログラミングを独学で勉強し始めて躓いた経験を元に、これから勉強をする人に向けに「イラスト多めでわかりやすい記事」にこだわって情報を発信しています。

現在はフルスタックエンジニアとしてサービス開発などのお仕事をしています。