はじめに
今回はK8s(Kubernetes)をアップデートしたさいに、突然namespace内のPodが名前解決できなくなってしまい、その原因がCoreDNSでした。
原因を探るさいにNodeのDebugでは名前解決できることを不思議に思い、K8sのDNSについて調べていく中で分かったことを備忘録として記事にしました。
Kubernetes DNS Policy(dnsPolicy)概要
そもそもKubernetes の Pod では、dnsPolicy フィールドで DNS 解決の振る舞いが複数あります。現在サポートされている主な値は以下のとおりです。
| Policy | 説明 |
|---|---|
| ClusterFirst | - dnsPolicy を指定しない場合のデフォルト値- Pod 内の DNS クエリのうち、クラスタドメイン(例: *.svc.cluster.local)にマッチしないものは、上流の名前解決サーバー(外部 DNS)へフォワードされる- クラスタ内・外部の両方への名前解決が可能 |
| Default | - ノード(ホスト)が持つ /etc/resolv.conf の設定をそのまま継承- Pod はホストと同じ DNS サーバー/検索ドメインを使う |
| ClusterFirstWithHostNet | - hostNetwork: true を設定した Pod 向け- ClusterFirst の動作(クラスタ DNS → 上流 DNS の順)をホストネットワーク下でも適用- Windows 環境ではサポートされない |
| None | - Kubernetes が提供する DNS 設定を一切無視 - Pod 側で dnsConfig フィールドを使い、nameservers/searches/options を手動指定する必要がある |
Node Debug Pod の挙動
kubectl debug node/<node-name> -it --image=<image> -- /bin/sh で起動される Pod は、以下の特徴を持ちます。
-
hostNetwork: trueにより、ホストのネットワーク名前空間をそのまま共有す:contentReference[oaicite:1]{index=1}。 -
/etc/resolv.confはホスト OS のものを参照し、外部 DNS などに直接問い合わせ - Kubernetes の CNI プラグインや CoreDNS の状態に依存せず、名前解決する
Namespace 内 Pod の挙動
通常の Pod(hostNetwork: false)は、以下のように DNS 解決を行います。
-
dnsPolicy: ClusterFirstがデフォルトで設定され、/etc/resolv.confの最上段に CoreDNS の Service IP を記載 -
DNS クエリはまず CoreDNS(例:
172.22.0.10:53)へ送られ、内部ゾーン解決後に上流の DNS へフォワード -
CoreDNS Pod の CrashLoopBackOff や、NetworkPolicy による UDP/53 の制限があると名前解決に失敗
dnsPolicy: ClusterFirst
Node debug pod とNamespace Pod 挙動比較
| 項目 | Node Debug Pod | Namespace Pod |
|---|---|---|
| ネットワーク層 | ホストのネットワーク名前空間を共有 | Kubernetes の仮想ネットワーク (CNI) 使用 |
| DNS 設定 | ホスト /etc/resolv.conf を直接参照 | CoreDNS Service IP を介して解決 |
| 名前解決依存範囲 | ホストの DNS 設定に依存 | CoreDNS + 上流 DNS に依存 |
| 障害耐性 | CoreDNS 障害や NP 制限をバイパス | CoreDNS/NetworkPolicy の影響を受ける |
まとめ
Node Debug Pod ではホストの DNS 設定やネットワーク環境を直接使っていることがわかり、Namespace 内 Pod のデバッグ時には、CoreDNS の稼働状況や NetworkPolicy の設定を合わせて確認することを念頭に入れることが大事です。
参考資料