広告

kubernetes – DNSについて

Azure

Kubernetes クラスターの外の DNS サーバーを参照する要望は、システム上でよくある話かと思います。
今回は、Kubernetes 内の名前解決や、クラスター内の Pod がクラスターの DNS 以外の DNS サーバーを参照したい時の方法について、ご紹介しようと思います。

Kubernetes 内の名前解決について

Service の A/AAAA レコード

Kubernetes クラスターでは、Service (Headless を除き) が作成されたら、AレコードがクラスターのDNSに登録されるようになっています。Aレコードの内容は FQDN と Service の ClusterIP となります。

登録された FQDN の形式は以下になります。

<ServiceName>.<Namespace>.svc.cluster.local

Headless Service について、ClusterIP が持っていないため、FQDN は 後ろにある Pod の IP 群になります。
アクセスされた際に、ラウンドロビン形式で IP が返されるようになっています。

Pod の A/AAAA レコード

Kubernetes の Pod の FQDN の形式は以下となります。

<PodのIP>.<Namespace>.pod.<クラスタードメイン名>

例:

172-17-0-3.default.pod.cluster.local

これは IP 依存しているので、そもそも IP を使えばよくない?と思いますので、Pod の名前解決はなしと考えてても過言ではないと思います。

ただし、Headless と併用した場合、Pod でも名前解決できるようになるので、この部分は以前 Headless の記事で説明しましたので、興味のある方は参考に読んでいただければと思います。

Kubernetes 内の DNS 設定について

Kubernetes の Pod の設定で、Pod が参照する DNS サーバーの設定は可能です。

Pod の DNS ポリシー

spec.dnsPolicy

Pod の定義に、DNS ポリシーを入れることによって、Pod に以下の挙動をさせることが可能です。

オプション:

  • ClusterFirstDNS ポリシーのデフォルト値。クラスター内部で名前解決できない FQDN は、ノードから継承された上流DNSサーバーにフォワーディングされます。
    • K8s内DNS → ノードの名前解決 順で名前解決する
    • 追加のstubドメインと上流のDNSサーバーはクラスターノードに設定すれば、Podでも参照できるようになります。
  • Default: Pod が稼働しているノードから名前解決の設定を継承します。
    • ノードの名前解決のみで名前解決する
  • ClusterFirstWithHostNet: hostNetwork 形式で稼働している Pod では、Pod を明示的に DNS ポリシーを"ClusterFirstWithHostNet"に設定すべき
    • spec.hostNetwork: true になっている Pod は、このポリシーにする必要がある
  • None: この設定では、Kubernetes の環境から DNS 設定を無視することができる
    • Pod の DNS 設定を完全にカスタマイズする時に使用する
    • Pod の全てのDNS設定は、Spec.dnsConfig フィールドを指定して提供することになる
    • None に設定した場合、Spec.dnsConfig フィールドは必須となる

サンプル:

apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
  - image: busybox:1.28
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
    name: busybox
  restartPolicy: Always
  hostNetwork: true
  dnsPolicy: ClusterFirstWithHostNet

Pod の DNS 設定

spec.dnsConfig

spec.dnsConfig は、DNS ポリシー以外に、さらに Pod の DNS 設定をカスタマイズするための設定となります。
また、spec.dnsPolicyNone に設定された場合、spec.dnsConfig は設定必須となります。

オプション:

  • nameservers:Pod が参照する DNS サーバー の IP アドレスのリストを指定する
    • 最大3つ指定可能
    • Pod の dnsPolicy が "None" に指定されていたとき、最低1つの IP の指定が必要
  • searches:Pod 内でホスト名を検索するための DNS サーチドメインのリストを追加する
    • このリストの内容は、選択されたspec.dnsPolicyから生成されたサーチドメインのリストにマージされる
    • 重複されているサーチドメインは削除される
    • 最大6つのサーチドメインの設定が可能
  • options:nameプロパティー(必須)とvalueプロパティー(オプション)を持つような各オプジェクトのリストを追加する
    • このリストの内容は、選択されたspec.dnsPolicyから生成されたオブジェクトのリストにマージされる
    • 重複されているオブジェクトは削除される

サンプル:

apiVersion: v1
kind: Pod
metadata:
  namespace: default
  name: dns-example
spec:
  containers:
    - name: test
      image: nginx
  dnsPolicy: "None"
  dnsConfig:
    nameservers:
      - 1.2.3.4
    searches:
      - ns1.svc.cluster.local
      - my.dns.search.suffix
    options:
      - name: ndots
        value: "2"
      - name: edns0

CoreDNS の設定(DNS フォワード)

kind: ConfigMap

CoreDNS アドオン

As of Kubernetes v1.12, CoreDNS is the recommended DNS Server, replacing kube-dns. Document

現在、Kubernetes クラスター DNS の管理と解決に CoreDNS アドオン(add-on)を使用することをが推奨となっています。そのため、DNS 設定をカスタマイズするには、システム Pod である kube-dns(CoreDNSアドオン) をカスタマイズすることで、可能となります。

AKS での CoreDNS のカスタマイズ

Azure の AKS も勿論そう合わせるようになっていますので、AKS のドキュメントではカスタマイズの方法を紹介されています。

AKS はマネージド サービスであるため、CoreDNS のメイン構成 (CoreFile) を変更することはできません。 代わりに、既定の設定をオーバーライドするには、Kubernetes ConfigMap を使用してください。Document

上記の説明通り、AKS の システム Pod はフルマネージドになっているため、カスタマイズはできません。
ただし、既定の AKS CoreDNS ConfigMaps を上書きすることで、設定が可能となっています。

AKS CoreDNS ConfigMaps の確認コマンド:

kubectl get configmaps --namespace=kube-system coredns -o yaml

マニフェスト(yaml)を書いて、以下のコマンドを実行することで、適用が可能です。

# 指定のマニフェスト ファイルを適用
kubectl apply -f <yamlファイルのパス>

# 適用結果を確認
kubectl get configmaps --namespace=kube-system coredns-custom -o yaml

# システム Pod の更新 ※ 停止時間は発生しません
kubectl delete pod --namespace kube-system -l k8s-app=kube-dns

AKS CoreDNS カスタマイズのシナリオ

公式ドキュメント で紹介されたシナリオは、DNS フォワード設定を活用するものが多いです

シナリオの抜粋:

  • DNS 名の書き換え
  • ネットワーク トラフィックの転送サーバーの指定
  • 内部的にしか解決できないカスタム ドメインの構成(フォワード)
  • スタブ ドメイン(stub domain)の構成
  • その他の CoreDNS のプラグインの導入

※ スタブ ドメインの表現はあんまり見当たらないので、恐らくDNS スタブ ゾーンのことかと思います。DNS スタブゾーンは、DNS サーバーが別のドメインのレコードを解決できるようにするために使用されます。

サンプル:内部的にしか解決できないカスタム ドメインの構成例のマニフェスト(yamlファイルの中身)

apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns-custom
  namespace: kube-system
data:
  puglife.server: | # you may select any name here, but it must end with the .server file extension
    puglife.local:53 {
        errors
        cache 30
        forward . 192.11.0.1  # this is my test/dev DNS server
    }

この例では、puglife.local ドメインへの名前解決は 192.11.0.1 サーバーを使用するようになっています。

最後に

ちょうど最近 kubernetes (AKS) でDNSサーバーを指定する方法についての質問をもらったことがあったので、
調べた内容を残しておこうと思い、この記事が生まれました。

記事に書いた内容以外の方法などもあるかもしれませんが、情報入手次第更新していこうと思います。

ここまで読んでいただいて、お疲れ様でした。

参考サイト

コメント

タイトルとURLをコピーしました