以前の投稿こちらで説明されているように、CoreDNSはKubernetesクラスタでのサービス検出においてKube-DNSの代わりに使用できます。CoreDNSの柔軟なアーキテクチャにより、いくつかの興味深いユースケースが可能になります。このブログでは、一般的な問題であるサービスのカスタムDNSエントリの作成方法について説明します。
ここにいくつかの可能性があります。
- 外部名のエイリアスの作成
- 別のサーバを実行せずに、別のドメインにサービスを動的に追加する
- クラスタドメイン内に任意のエントリを追加する
CoreDNSはこれらのユースケースすべてに対応できます。まず、非常に一般的な最初のユースケースから始めましょう。この状況では、クラスタの内外どちらからアクセスする場合でも、特定のサービスに対して同じ名前を使用できるようにしたいと考えています。これは、たとえば、その名前にバインドされているTLS証明書を使用する場合に役立ちます。
クラスタ外部のクライアントからfoo.example.com
としてアクセス可能なサービスfoo.default.svc.cluster.local
があるとします。つまり、クラスタ外部でルックアップされた場合、foo.example.com
はロードバランサのVIP(サービスの外部IPアドレス)に解決されます。クラスタ内では同じものになり、この名前を内部的に使用すると、トラフィックがヘアピン(クラスタから出て、外部IP経由でクラスタに戻る)されます。代わりに、内部ClusterIPに解決して、ヘアピンを回避したいと考えています。
CoreDNSでこれを行うには、rewrite
プラグインを使用します。このプラグインは、クエリを回答するバックエンドに送信する前に、クエリを変更できます。前回のブログで使用したCorefile
(CoreDNS設定ファイル)を思い出してください。
.:53 {
errors
log
health
kubernetes cluster.local 10.0.0.0/24
forward . /etc/resolv.conf
cache 30
}
必要な動作を得るには、foo.example.com
をfoo.default.svc.cluster.local
にマッピングする書き換えルールを追加するだけです。
.:53 {
errors
log
health
rewrite name foo.example.com foo.default.svc.cluster.local
kubernetes cluster.local 10.0.0.0/24
forward . /etc/resolv.conf
cache 30
}
それをkubectl edit
またはkubectl apply
を介してConfigMap
に追加したら、Corefile
が変更されたことをCoreDNSに知らせる必要があります。サービスを損失することなく、つまりgracefulに再読み込みするように指示するために、SIGUSR1
を送信できます。
$ kubectl exec -n kube-system coredns-980047985-g2748 -- kill -SIGUSR1 1
テストポッドを実行すると、これが機能していることがわかります。
$ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools
If you don't see a command prompt, try pressing enter.
/ # host foo
foo.default.svc.cluster.local has address 10.0.0.72
/ # host foo.example.com
foo.example.com has address 10.0.0.72
/ # host bar.example.com
Host bar.example.com not found: 3(NXDOMAIN)
/ #
最初の問題の解決方法は以上です。
2番目の問題は同様に簡単です。ここでは、クラスタドメインとは異なるゾーンからDNSエントリを提供できるようにしたいだけです。CoreDNSは汎用DNSサーバであるため、kubernetes
プラグインだけでなく、ゾーンを提供する多くの方法があります。簡潔にするために、このユースケースを満たすためにfile
プラグインと別のConfigMap
エントリを使用します。ただし、etcd
プラグインを使用してサービスをetcdインスタンスに直接保存したり、auto
プラグインを使用してゾーンセットを管理したりできます(git-syncと併用すると非常に便利です)。
新しいゾーンを作成するには、使用しているcoredns.yaml
を修正して、ポッドに追加のファイルを作成する必要があります。そのためには、Corefile
にfile
行を追加し、ゾーンファイルの別のキーexample.db
を追加することで、ConfigMap
を編集する必要があります。
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
log
health
rewrite name foo.example.com foo.default.svc.cluster.local
kubernetes cluster.local 10.0.0.0/24
file /etc/coredns/example.db example.org
forward . /etc/resolv.conf
cache 30
}
example.db: |
; example.org test file
example.org. IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600
example.org. IN NS b.iana-servers.net.
example.org. IN NS a.iana-servers.net.
example.org. IN A 127.0.0.1
a.b.c.w.example.org. IN TXT "Not a wildcard"
cname.example.org. IN CNAME www.example.net.
service.example.org. IN SRV 8080 10 10 example.org.
また、Pod
テンプレート仕様のvolumes
セクションも編集する必要があります。
volumes:
- name: config-volume
configMap:
name: coredns
items:
- key: Corefile
path: Corefile
- key: example.db
path: example.db
kubectl apply -f
を使用してこれを適用すると、ボリューム内の新しいファイルのために新しいCoreDNSポッドが構築されます。ファイルの後の変更では、新しいポッドは必要なく、前に行ったようにgracefulな再起動だけで済みます。見てみましょう。
$ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools
If you don't see a command prompt, try pressing enter.
/ # host foo
foo.default.svc.cluster.local has address 10.0.0.72
/ # host foo.example.com
foo.example.com has address 10.0.0.72
/ # host example.org
example.org has address 127.0.0.1
/ #
完璧です!これで、example.org
にエントリを追加したいときはいつでも、そのConfigMap
を編集してSIGUSR1
を送信できます。もちろん、前述のように、etcd
バックエンドを使用することもでき、ConfigMap
の変更とシグナルの送信の手間を省くことができます。
これで最後の問題になります。それは、kubernetes
プラグインの新しいfallthrough
サポートを使用して解決できます。この機能は最近リリースされたCoreDNSバージョン007に追加されました。使用方法については、近日中に別のブログで説明します。