Kubernetes 集群 DNS 解決机制与 CoreDNS 実装ガイド

Kubernetes における DNS の役割と概要

Kubernetes 集群内では、Pod やサービスの IP アドレスが動的に変更されるため、固定されたエンドポイントによる通信机制が不可欠です。DNS サービスは、アプリケーションが IP アドレスを直接指定することなく、論理的な名前を通じてサービスにアクセスできるようするための基盤となります。これにより、マイクロサービスアーキテクチャにおけるサービス発見(Service Discovery)が標準化され、システム全体の柔軟性と保守性が向上します。

CoreDNS アーキテクチャと構成要素

Kubernetes 1.11 以降、デフォルトの DNS アドオンとして CoreDNS が採用されています。以前の kube-dns に比べ、プラグインベースの設計により拡張性が高まっています。CoreDNS の主要構成要素は以下の通りです。

  • CoreDNS Pod:DNS サーバープロセスを実行し、通常は kube-system 名前空間に配置されます。
  • ConfigMap:DNS の挙動を定義する Corefile 設定を保持します。
  • Service:集群内の他の Pod から CoreDNS にアクセスするための稳定的な ClusterIP を提供します。
  • API Server 連携:Watch 机制を通じて、サービスや Pod の追加・削除をリアルタイムで検知し、DNS ゾーン情報を更新します。

ドメイン解決規則とフロー

Kubernetes 内部では、サービスおよび Pod に対して固有の Fully Qualified Domain Name (FQDN) が割り当てられます。

  • サービス名:<サービス名>.<名前空間>.svc.cluster.local
    • 例:名前空間 productionapi-gateway サービスは api-gateway.production.svc.cluster.local となります。
  • Pod 名:<Pod-IP-ハイフン区切り>.<名前空間>.pod.cluster.local
    • 例:IP 10.244.2.8 の Pod は 10-244-2-8.default.pod.cluster.local として解決可能です。

解決プロセスは、Pod 内の /etc/resolv.conf に設定された Nameserver(通常は CoreDNS の ClusterIP)へ問い合わせが行われ、CoreDNS が Kubernetes API の情報を参照して IP アドレスを返却する流れになります。

DNS ポリシーの設定

Pod の DNS 解決挙動は、spec.dnsPolicy によって制御できます。主なポリシーは以下の通りです。

ポリシー名 挙動 推奨ユースケース
ClusterFirst 集群内ドメインを優先し、外部ドメインは上位 DNS へフォワード(デフォルト) 標準的なアプリケーション Pod
Default ノードの /etc/resolv.conf を継承 ノードと同じ DNS 環境が必要な場合
ClusterFirstWithHostNet HostNetwork 使用時でも集群 DNS を優先 ホストネットワークモードの Pod
None K8s DNS を使用せず、dnsConfig で手動設定 特殊な DNS 構成が必要な場合

CoreDNS のデプロイと設定例

CoreDNS は Deployment リソースとして管理され、設定は ConfigMap を通じて注入されます。以下に構成例を示します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: coredns-controller
  namespace: kube-system
spec:
  replicas: 2
  selector:
    matchLabels:
      app.kubernetes.io/name: coredns
  template:
    metadata:
      labels:
        app.kubernetes.io/name: coredns
    spec:
      containers:
      - name: coredns
        image: coredns/coredns:v1.11.1
        args:
        - -conf
        - /etc/coredns/Corefile
        volumeMounts:
        - name: config-volume
          mountPath: /etc/coredns
          readOnly: true
      volumes:
      - name: config-volume
        configMap:
          name: coredns-config
          items:
          - key: Corefile
            path: Corefile

設定ファイル Corefile では、プラグインの順序とパラメータを定義します。

.:53 {
    errors
    log
    health {
        lameduck 10s
    }
    ready
    kubernetes cluster.local in-addr.arpa ip6.arpa {
        pods insecure
        fallthrough in-addr.arpa ip6.arpa
        ttl 60
    }
    prometheus :9153
    forward . 1.1.1.1 {
        max_concurrent 1000
    }
    cache 60
    loop
    reload
    loadbalance
}

主要なプラグイン機能:

  • kubernetes:集群内のサービスおよび Pod 情報を解決。
  • forward:集群外ドメインの問い合わせを外部 DNS(例:1.1.1.1)へ転送。
  • cache:DNS 応答をキャッシュし、 TTL を 60 秒に設定してパフォーマンスを向上。
  • loadbalance:複数 IP を持つサービスに対してラウンドロビン分散を実施。

高度なカスタマイズ

独自ドメインの解決

集群外の特定ドメインを独自に解決したい場合、Corefile にゾーン定義を追加できます。

internal.lab:53 {
    forward . 8.8.8.8
}

静的 DNS レコードの追加

ConfigMap を利用して、固定的な A レコードを定義することも可能です。

apiVersion: v1
kind: ConfigMap
metadata:
  name: custom-dns-records
  namespace: kube-system
data:
  static-records: |
    internal.lab:53 {
        a db.internal.lab 10.0.0.50
    }

これを Corefile で import static-records として読み込むことで有効化します。

運用管理と最適化

トラブルシューティング

DNS 関連の問題を調査する際には、以下のコマンドが有用です。

  • Pod の DNS 設定確認:kubectl exec <pod> -n <ns> -- cat /etc/resolv.conf
  • 名前解決テスト:kubectl exec <pod> -n <ns> -- nslookup <service>
  • CoreDNS ログ確認:kubectl logs -n kube-system -l k8s-app=kube-dns

パフォーマンスチューニング

  • キャッシュ TTL の調整:頻繁に変更されないサービスの場合、cache プラグインの TTL を延長し負荷を低減。
  • レプリカ数の増加:集群規模拡大に伴い、CoreDNS Pod の副本数を増やし可用性を確保。
  • アフィニティ設定:CoreDNS Pod を高性能ノードにスケジューリングし、解決遅延を最小化。
  • 監視:Prometheus 経由で dns_request_duration_seconds メトリクスを収集し、遅延を可視化。

ベストプラクティス

  • kube-dns から CoreDNS への移行を完了し、プラグイン機能を活用。
  • 生産環境では ClusterFirst ポリシーを維持。
  • 外部依存サービスには ExternalName またはカスタム DNS 記録を利用。
  • CoreDNS の権限を最小限に抑え、セキュリティリスクを低減。
  • 障害に備え、複数ノードに CoreDNS Pod を分散配置。

タグ: Kubernetes coredns service-discovery dns-policy cluster-networking

7月6日 18:58 投稿