KEIS BLOGは株式会社ケイズ・ソフトウェアが運営しています。

KEIS BLOG

Kubernetes内のPod間通信とDNSキャッシュ問題をいかに解決しているのか + 避けるべきアンチパターン

前回の記事で解説したように、Kubernetes(K8s)のクラスタ内ではPod間通信は主にDNSによって行われ、Service → Endpoints → Podという仕組みを通じてPodが入れ替わるたびにトラフィック先を動的に更新します。DNS TTLも短く設定され、Pod入れ替え時のDNSキャッシュ問題を最小化していることがポイントでした。

しかし、このメカニズムを前提にしたK8sでの運用において、Pod内部で行うべきではないことも存在します。以下はそのいくつかの例です。

1. 固定的なIPアドレスへの依存

やってはいけないこと
Pod内のアプリケーションが、特定のPod IPやNode IPをハードコーディングして接続先を決めること。まあまずはこれですよね。

なぜ問題か
Podは流動的な存在であり、再スケジュールやローリングアップデートによって簡単にIPアドレスが変わります。固定IPへの依存は、Podが入れ替わった際に接続エラーを引き起こします。

代替策
サービス名(<serviceName>.<namespace>.svc.cluster.local)や環境変数経由で動的に取得されるDNS名を用いて接続先を決定しましょう。こうすることで、Podの入れ替えがあってもトラフィック先はService経由で常に最新化され、DNSキャッシュTTLによって数秒以内に更新が反映されます。

2. DNSキャッシュの過度な保持

やってはいけないこと
アプリケーション内部で独自にDNSの結果を長時間キャッシュすること。

なぜ問題か
K8s上ではDNS TTLが短く設定されており、CoreDNSはEndpointsの変更に合わせて速やかにDNSエントリを更新します。しかし、もしアプリケーションが独自にDNSを長期間キャッシュしてしまうと、K8s側の恩恵が得られず、古いIPへアクセスし続けることになります。

代替策
アプリケーション側でのDNSキャッシュは極力行わず、OSレベルやランタイムでのキャッシュも可能なら短めにする設定を行いましょう。Javaのような言語ではnetworkaddress.cache.ttlを短くしたり、Go言語ではDNSリゾルバを標準設定に任せたりといった対策が考えられます。

3. クライアントサイドでの手動ロジックによるPod選別

やってはいけないこと
クライアントアプリケーション側で、Pod IP一覧を取得して独自にロードバランシングやフェイルオーバーを行うこと。

なぜ問題か
K8sはServiceを通じて自動的にロードバランシングとフェイルオーバーを行う設計になっています。クライアント側で複雑なロジックを組み込むと、Podsの追加・削除に追随するためのコードが増え、保守性が下がります。また、Endpoints情報の変更を追い続けるコードを書くことは手間であり、K8sが提供する恩恵(Serviceによる負荷分散、CoreDNSの動的更新など)を自ら無効化してしまいます。

代替策
Service(ClusterIPやHeadless Service)とkube-proxyの仕組みを信頼し、クライアント側はServiceのDNS名へ単純にアクセスするだけで、K8s側が自動的に適切なPodへトラフィックを振り分けるようにしましょう。

4. IPベースのアクセス制御(ACL)やSecurity Groupへの過度な依存

やってはいけないこと
特定Pod IPへのアクセスを前提としたIPベースのACLや、固定IPに紐づくセキュリティグループルールに過度に依存すること。

なぜ問題か
Pod IPは固定ではなく、スケールや再スケジュールで変わるため、IPベースのルールは頻繁な更新を余儀なくされます。

代替策
K8sのNetworkPolicyやServiceAccount、IstioなどのService Meshを用いた層でのポリシー管理を検討しましょう。また、外部アクセスの場合はLoadBalancerやIngressを経由したホスト名・パスベースの制御が有効です。


まとめ

K8sが提供するService、Endpoints、CoreDNS、kube-proxyの連携により、Podの流動的な入れ替え時でもスムーズな通信が行えるような仕組みが整っています。しかし、その前提を無視した設計(固定的なIP使用や長期間の独自DNSキャッシュ、クライアント側での過剰なPodコントロールなど)をすると、K8s本来の強みが十分に活かせなくなってしまいます。

「Podは使い捨てで動的に変わる」ことを受け入れ、ServiceとDNSを正しく活用することで、K8sのダイナミックなスケーラビリティと可用性を最大限に活かしたシンプルで堅牢なアーキテクチャを構築しましょう。

ということで、2回に渡って調査結果をまとめました。DNSが大事ってことで。何かのご参考になれば。