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 に以下の挙動をさせることが可能です。
オプション:
ClusterFirst
:DNS ポリシーのデフォルト値。クラスター内部で名前解決できない 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.dnsPolicy
が None
に設定された場合、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サーバーを指定する方法についての質問をもらったことがあったので、
調べた内容を残しておこうと思い、この記事が生まれました。
記事に書いた内容以外の方法などもあるかもしれませんが、情報入手次第更新していこうと思います。
ここまで読んでいただいて、お疲れ様でした。
コメント