ip netns exec と DNS: 名前空間の内側で名前が失敗する理由
名前空間は独自のインターフェースとルートを持ちますが、独自のリゾルバーファイルは持ちません。起動したプロセスがどの resolv.conf を見ているのか、そのファイルがどこから来たのかを確認します。
コマンドは VPN 名前空間の内側で 10.8.0.5 に何の不満もなく到達しますが、同じコマンドがホスト名を使った瞬間に失敗します。名前空間には独自のインターフェース、ルート、ソケットがありますが、独自のリゾルバーファイルはありません。何かがそこにファイルを置かない限り、内側のプロセスはホストの /etc/resolv.conf を読み、そのネットワークスタックからは到達できないかもしれないサーバーに問い合わせます。
これはルーティングではなくファイル選択の問題であり、数値の宛先が今も機能するのはまさにそのためです。
プロセスが実際に受け取るリゾルバーの見え方を確認する
使ったシェルが、デバッグしているプロセスと同じだと決めつけないでください。GUI アプリケーション、systemd ユニット、コンテナはそれぞれ別のマウントやネットワークのコンテキストに入ることがあります。同じ起動経路で検索を実行し、その内側からリゾルバーファイルを出力してください。
ip netns add で作成した名前空間では、読み取り専用の確認は短時間で済みます:
ip netns exec vpn cat /etc/resolv.conf結果が到達可能なアドレス、loopback スタブ、それとも到達性の異なる場所を指すシンボリックリンクのどれを示しているかに注目してください。
exec ヘルパーが実際にマウントするもの
ip-netns ツールは名前空間ごとの設定を /etc/netns/NAME/ の下に文書化しています。プロセスを起動すると、ヘルパーはマウント名前空間を作成し、それらのファイルを通常のパスの上にバインドマウントするため、プロセスは名前空間固有のコピーを見ます。これはこの特定のランチャーの利便性です。unshare やコンテナランタイムなど別の経路でネットワーク名前空間に入っても、それは自動的には再現されません。
ここでの罠は loopback リゾルバーです: 127.0.0.53 は名前空間自身の loopback を意味し、ホストのスタブではありません。ホスト名前空間でのみ待ち受けるスタブは、新しい名前空間ではサービスになりません。
名前空間が到達できるリゾルバーを選ぶ
ファイルがどのサーバーを指していても、その名前空間からのルートが依然として必要です。公開リゾルバーは公開名に答えられても、プライベートなサービスがトンネル経由でしか到達できない内部ゾーンでは失敗することがあります。ルートはアドレスと同時に確認し、検索が失敗した後では確認しないでください。
独自のリゾルバーを持つアプリケーション、たとえば DNS over HTTPS を使うものは、ファイルをまったく無視するかもしれません。ツールに独自の DNS 設定があれば、resolv.conf を変更しても影響せず、名前空間はそもそも問題ではありませんでした。
ファイルを正しい場所に書く
/etc/netns/NAME/resolv.conf の下に名前空間ごとのファイルを作成し、ランチャーにそれを提示させます。最小限に保ち、到達可能なサーバーを一、二台と、タスクが必要とする検索ドメインだけにしてください。一つのプロセス群向けの見え方を直すためにホストの生成済みリゾルバーファイルを編集しないでください。それはマシン上のすべてのアプリケーションを変えてしまうので、ホストがリゾルバーマネージャーを使っている場合は、それと格闘するのではなく、そのマネージャー経由で名前空間のパスを設定してください。
ファイルの内容をランブックに記録してください。そうしないと、次の人がホストのリゾルバーを試し、動く応答を見て、名前空間は問題ないと結論づけます。
経路全体を再テストする
名前空間の内側で、数値アドレス、内部名、公開名を使ってテストすると、到達性と解決を切り分け、内部ゾーンと公開ゾーンを切り分けられます。その後、名前空間を作り直して繰り返してください。実行中のインスタンスにしか存在しないファイルは、それと一緒に消えるからです。
ファイルを受け取っているのがシェルではなくプロセスであることを確認してください。対話的シェルからは機能し、サービスからは失敗する検索は、マウントコンテキストに関する発見であり、次のインシデントの前にゼロから再発見するのではなく書き留める価値があります。