物理サーバーの名前解決障害をアプリから上流まで調べる

物理サーバーの名前解決障害をアプリから上流まで調べる

物理サーバーの名前解決障害をアプリから上流まで調べる

業務プロセスで名前解決エラーが発生していても、アドレスを直接指定すればアクセスできる場合、すぐに DNS サーバーを変更すると障害発生時の状況が分からなくなりがちです。原因はアプリケーションのキャッシュ、NSS の問い合わせ順序、システムの名前解決サービスにあるかもしれませんし、上流から返されたエラーかもしれません。調査の目的は、あるコマンドをたまたま成功させることではなく、業務プロセスが実際にどの名前解決経路を使い、どの層でエラーが発生しているかを特定することです。

本記事では Ubuntu Server 24.04 LTS を使用します。AMDSSH の物理サーバーは、支払い後にコントロールパネルで認証情報を確認し、SSH でログインします。アドレスが複数ある場合は、最初のアドレスで接続してください。以下の確認では、ネットワークインターフェースのアドレス、ルーティング、ファイアウォールは変更しません。まず調査の根拠をそろえるための手順です。

1. 問い合わせ対象を固定し、元のエラーを記録する

まず、アプリケーションのエラー、問い合わせた名前、レコードタイプ、発生時刻を保存します。すべてのドメイン名で失敗するのか、特定の名前だけで失敗するのかも明確にしてください。また、ホスト上のプロセスで起きているのか、コンテナ内のプロセスで起きているのかを区別します。短い名前は検索ドメインの影響を受けるため、調査では末尾にドットを付けた完全修飾ドメイン名を優先して使います。

以下では amdssh.com. を使って問い合わせの形式を示しますが、特定のアドレスが返ることを前提にはしていません。実際の検証では、業務で必要な名前で、対応するレコードが存在すると確認できているものに置き換えてください。まずツールの有無を確認し、基本的な環境情報を保存します。

command -v getent resolvectl dig
date -Is
readlink -f /etc/resolv.conf
cat /etc/resolv.conf
grep '^hosts:' /etc/nsswitch.conf
systemctl is-active systemd-resolved
resolvectl status

dig は dnsutils パッケージに含まれています。未インストールの場合は、設定済みのパッケージリポジトリから用意してください。すでに名前解決が失敗している状況では、インストールの失敗を新たな根本原因の証拠として扱うことはできません。

アドレス宛てに通信できても、DNS の問い合わせ経路が正常とは限りません。DNS の応答を受け取れても、アプリケーションが必要なレコードを取得できたとは限らないため、応答ステータス、レコードタイプ、実際の応答内容を併せて確認する必要があります。

2. NSS とシステムの名前解決サービスを比較する

3 種類の問い合わせは同じではない

getent は NSS を通じて問い合わせるため、一般的なシステムのアドレス解決処理に近い動作をします。resolvectl は systemd-resolved に問い合わせます。dig は DNS の問い合わせを行うもので、NSS の経路全体を検証することはできません。

getent ahostsv4 amdssh.com.
resolvectl query --type=A amdssh.com.
dig amdssh.com. A +time=2 +tries=1

この 3 つの結果を照らし合わせて判断します。getent が古いアドレスを返し、DNS の問い合わせでは新しいアドレスが返る場合は、まず /etc/hosts と hosts: 行のモジュールの順序を確認してください。resolvectl は成功するのに getent が失敗する場合は、NSS モジュールが存在するか、順序が適切か、サービスが異なるファイルシステム環境で動作していないかを確認します。

/etc/resolv.conf はローカルの名前解決窓口を指している場合があり、最終的な上流サーバーが直接記載されているとは限りません。また、ネットワーク管理ツールによって生成されていることもあります。ローカルアドレスが記載されているだけで設定ミスと決めつけたり、シンボリックリンクを上書きしてから障害が解消したかを判断したりしないでください。

独自の DNS ライブラリを使い、NSS を経由しないアプリケーションもあります。そのため、getent の成功はシステム側の経路が正常であることを示すだけで、すべてのアプリケーションが復旧した証明にはなりません。

3. 上流を指定し、応答の問題と通信障害を切り分ける

resolvectl status から、失敗した問い合わせに対応するインターフェースの DNS サーバー、ルーティングドメイン、現在使用中のサーバーを記録します。複数のインターフェースを持つサーバーでは、ドメイン名に応じて異なる上流が選ばれる場合があるため、出力の最初の項目だけを使ってはいけません。以下では、実際に使用している上流のアドレスを対話形式で入力します。未確認のパブリックリゾルバーは持ち込みません。

read -r -p 'DNS server address: ' DNS_SERVER
dig @"$DNS_SERVER" amdssh.com. A +time=2 +tries=1
dig @"$DNS_SERVER" amdssh.com. A +tcp +time=2 +tries=1
dig @"$DNS_SERVER" amdssh.com. AAAA +time=2 +tries=1

ここで指定している 2 秒のタイムアウトと 1 回の試行は調査用の値であり、業務で使うタイムアウト設定の推奨値ではありません。出力全体を保存し、特に status、回答セクション、問い合わせ時間、実際に問い合わせたサーバーを確認してください。コマンドの終了コードだけで、業務に必要なレコードが有効かどうかを判断してはいけません。

応答ステータスに応じて対処する

NXDOMAIN は、その名前が存在しないことを示します。まず綴り、検索ドメイン、権威 DNS のレコードを確認してください。NOERROR でも回答が空の場合は、そのタイプのレコードがないだけかもしれず、ネットワーク障害として扱うべきではありません。SERVFAIL は名前解決の処理が失敗したことを示すため、上流のログと照合するか、管理者に確認を依頼します。REFUSED の場合は問い合わせの許可設定を確認してください。

UDP の問い合わせがタイムアウトし、TCP では成功する場合、両者の通信経路で挙動が異なることを示しています。関連するネットワークポリシーをさらに調べてください。両方ともタイムアウトする場合は、上流までのルーティングとアクセス制御を確認します。ただし、タイムアウトだけでサーバーが停止しているとは判断できません。上流からは応答があるのにシステムの名前解決経路では失敗する場合は、ローカル設定とキャッシュの調査に戻ります。

4. 証拠に基づいて修復し、設定管理元の出力を上書きしない

まず、DNS 設定をどの層が管理しているかを調べます。Ubuntu Server では、Netplan を通じて設定を個別のネットワークバックエンドに渡している場合もあれば、別の管理方式を使っている場合もあります。永続的な設定変更は、実際に管理している仕組みの設定ファイルに対して行う必要があります。生成された /etc/resolv.conf だけを変更してはいけません。

権威 DNS のレコードが修正済みで、systemd-resolved が古い結果を保持していると確認できた場合は、障害時の情報を記録してからキャッシュを消去できます。

resolvectl statistics
sudo resolvectl flush-caches
resolvectl query --type=A amdssh.com.
getent ahostsv4 amdssh.com.

キャッシュを消去しても、上流は変更されません。また、アプリケーション独自のキャッシュも消去されません。以前に名前が存在しないという応答が返っていた場合は、ネガティブキャッシュの影響も考えられます。応答内の SOA 情報を併せて判断し、サービスの再起動を繰り返すことを修復手段にしないでください。

NSS の順序を変更する前に元のファイルを保存し、ローカルファイル、DNS、その他の名前情報源をどのモジュールが担当しているかを明確にします。条件付きのアクションが設定されたモジュールは、問い合わせを途中で終了させる場合があるため、dns という文字列があるかどうかだけでは判断できません。

永続的な DNS 設定を変更する必要がある場合は、先に設定を保存し、構文を確認して、元のファイルへ戻す手順を用意します。リモートでネットワーク変更を適用する際は、既存の SSH セッションを維持し、設定管理ツールが提供する取り消し可能な適用方法を優先してください。DNS、ルーティング、ネットワークインターフェース名を同時に変更しないことも重要です。

5. 業務プロセスの実行環境で復旧を検証する

ホスト側が復旧した後も、コンテナや隔離されたサービスから見える名前解決用のファイルを確認する必要があります。コンテナは独立した /etc/resolv.conf を持つことがあり、プロセスが古いアドレスをキャッシュしている場合もあります。ホストの端末で同じコマンドを実行するだけでなく、実際の実行環境に入り、問い合わせを繰り返してください。

最終的な復旧確認には、以下の項目を含めます。

特定のプロセスだけで問題が起きる場合は、そのプロセスのリゾルバー、実行環境、コネクションプールを引き続き調べます。サーバー全体のネットワーク調整に範囲を広げるべきではありません。一連の調査では、元のエラーを説明し、障害が発生した層を特定したうえで、修復後の業務リクエストが想定どおりの名前解決経路を通ったことを示せる必要があります。

よくある質問

dig は成功するのにアプリの名前解決が失敗するのはなぜですか?

dig は DNS を直接問い合わせるため、NSS の経路全体は確認できません。hosts、コンテナ内の設定、アプリ独自のキャッシュが異なる可能性があります。getent と比較し、対象プロセスの実行環境でも確認します。

システムの DNS キャッシュを消せば必ず直りますか?

直るとは限りません。resolvectl flush-caches が消すのは systemd-resolved のキャッシュだけです。上流の応答異常やアプリ独自のキャッシュは残るため、先に応答状態と使用中のリゾルバーを記録します。

EPYC 7543P 専用物理サーバー月額 $450.2〜

リソースの検討からサーバー構成へ

サーバー本体とオプションは月額合計でのご請求です。構成ページで明細をご確認いただけます。接続情報は納品後、コントロールパネルで確認できます。