CoreDNSとは
Go言語によるDNSサーバ。
その機能のほとんどがプラグインで制御されているため高い柔軟性を持つ。
Cloud Native Computing Foundation(CNCF)のGraduated Projectであり、KubernetesにおけるデフォルトのDNSサーバとしても使用されている。
(ただし今回はそれとは別の用途を想定し構築している)
実装
最小構成であれば、デプロイする必要があるリソースはPod(Deployment)とConfigMapのみのため、その2種のリソース、合計4マニフェストの例を示す。
(ただしこれだとPodのIPに直接アクセスできないとリクエストを投げられないので、実際には外部公開するためのServiceも必要になりそう)
なお今回は下記3ドメインのゾーン情報を管理し、それ以外をGoogle Public DNSにフォワーディングすることを要件とする。
- example.com
- example.net
- example.org
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: coredns
namespace: coredns
spec:
replicas: 3
selector:
matchLabels:
k8s-app: coredns
template:
metadata:
labels:
k8s-app: coredns
spec:
containers:
- name: coredns
image: coredns/coredns:latest
args:
- -conf
- /etc/coredns/Corefile
volumeMounts:
- name: coredns-config-volume
mountPath: /etc/coredns/Corefile
subPath: Corefile
readOnly: true
- name: coredns-example-com-zone-volume
mountPath: /etc/coredns/example.com
subPath: example.com
readOnly: true
- name: coredns-example-net-zone-volume
mountPath: /etc/coredns/example.net
subPath: example.net
readOnly: true
volumes:
- name: coredns-config-volume
configMap:
name: coredns-config
- name: coredns-example-com-zone-volume
configMap:
name: coredns-example-com-zone
- name: coredns-example-net-zone-volume
configMap:
name: coredns-example-net-zone
/etc/coredns/Corefileがメインの設定ファイル。
/etc/coredns/example.comと/etc/coredns/example.netはゾーンファイルである。
これらのファイルは後述するConfigMapを3種それぞれ、データボリュームとしてマウントする。
(なおexample.orgは別の方式でゾーン情報を持たせてみる)
Configmap
Corefile
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns-config
namespace: coredns
data:
Corefile: |
example.com:53 {
file /etc/coredns/example.com
}
example.net:53 {
file /etc/coredns/example.net
}
example.org:53 {
log
hosts {
192.168.1.1 hoge.example.org
192.168.1.2 fuga.example.org
fallthrough
}
}
.:53 {
forward . 8.8.8.8 8.8.4.4
}
要件を実現するためのほぼ最小構成。
実運用上ではlogやerrors、healthやreadyといった各種プラグインを追加で使用することになると思う。
example.comとexample.netへの問い合わせ(それぞれ53番ポート)はfileプラグインによりゾーンファイルを参照させている。
example.orgはhostsプラグインで直書きしてみた。なおfallthroughオプションが無いと、一致するものがない場合にリクエストが下流に流れず打ち切られてしまうので注意。
また、後述するが、hostsプラグインで名前解決を行った場合はAレコードとして返ってくる模様。
example.com
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns-example-com-zone
namespace: coredns
data:
example.com: |
$TTL 3600
@ IN SOA ns1.example.com. admin.example.com. (
2024032101
7200
3600
1209600
3600
)
@ IN NS ns1.example.com.
ns1 IN A 10.0.0.100
server1 IN A 10.0.0.1
server2 IN A 10.0.0.2
example.net
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns-example-net-zone
namespace: coredns
data:
example.net: |
$TTL 3600
@ IN SOA name.example.net. adm.example.net. (
2024032101
7200
3600
1209600
3600
)
@ IN NS name.example.com.
name IN A 172.16.0.200
web IN A 172.16.0.1
db IN A 172.16.0.2
動作確認
ServiceリソースをデプロイしてないのでPodのIPアドレスを直接指定して問い合わせる。
$ kubectl get po -n coredns -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
coredns-5775847dc8-4lp7q 1/1 Running 0 41m 10.192.173.113 test-node03 <none> <none>
coredns-5775847dc8-9vf7x 1/1 Running 0 41m 10.192.184.113 test-node02 <none> <none>
coredns-5775847dc8-vtpl5 1/1 Running 0 41m 10.192.130.106 test-node01 <none> <none>
以下、確認結果を示す。
$ dig A server1.example.com @10.192.173.113 +short
10.0.0.1
$ dig A server2.example.com @10.192.173.113 +short
10.0.0.2
$ dig A name.example.net @10.192.173.113 +short
172.16.0.200
$ dig A db.example.net @10.192.173.113 +short
172.16.0.2
### example.orgについてはAレコードで返ることを分かりやすく示すため+shortを外している
$ dig A hoge.example.org @10.192.173.113
; <<>> DiG 9.18.30-0ubuntu0.22.04.2-Ubuntu <<>> A hoge.example.org @10.192.173.113
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6808
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: ae23e97670ce4991 (echoed)
;; QUESTION SECTION:
;hoge.example.org. IN A
;; ANSWER SECTION:
hoge.example.org. 3600 IN A 192.168.1.1
;; Query time: 0 msec
;; SERVER: 10.192.173.113#53(10.192.173.113) (UDP)
;; WHEN: Fri Mar 21 15:30:28 JST 2025
;; MSG SIZE rcvd: 89
$ dig A fuga.example.org @10.192.173.113
; <<>> DiG 9.18.30-0ubuntu0.22.04.2-Ubuntu <<>> A fuga.example.org @10.192.173.113
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4067
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: b67f04c7c08f658d (echoed)
;; QUESTION SECTION:
;fuga.example.org. IN A
;; ANSWER SECTION:
fuga.example.org. 3600 IN A 192.168.1.2
;; Query time: 4 msec
;; SERVER: 10.192.173.113#53(10.192.173.113) (UDP)
;; WHEN: Fri Mar 21 15:30:43 JST 2025
;; MSG SIZE rcvd: 89
管理外のゾーン情報をフォワーディングして問題なく名前解決できることも確認する。
$ dig A qiita.com @10.192.173.113
; <<>> DiG 9.18.30-0ubuntu0.22.04.2-Ubuntu <<>> A qiita.com @10.192.173.113
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12650
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;qiita.com. IN A
;; ANSWER SECTION:
qiita.com. 60 IN A 13.249.146.69
qiita.com. 60 IN A 13.249.146.22
qiita.com. 60 IN A 13.249.146.65
qiita.com. 60 IN A 13.249.146.98
;; Query time: 24 msec
;; SERVER: 10.192.173.113#53(10.192.173.113) (UDP)
;; WHEN: Fri Mar 21 15:33:31 JST 2025
;; MSG SIZE rcvd: 138
おまけ
.:53 {
forward . 8.8.8.8 8.8.4.4
}
ここ消してDeploymentとConfigMapとも再デプロイすると、管理外のゾーン情報については名前解決できなくなる。
(reloadプラグイン使えば再デプロイ不要なはず)
$ dig A qiita.com @10.192.130.107 # デプロイし直したのでIPアドレス変わってる
; <<>> DiG 9.18.30-0ubuntu0.22.04.2-Ubuntu <<>> A qiita.com @10.192.130.107
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 40859
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: e8c5afbb1f5024ac (echoed)
;; QUESTION SECTION:
;qiita.com. IN A
;; Query time: 0 msec
;; SERVER: 10.192.130.107#53(10.192.130.107) (UDP)
;; WHEN: Fri Mar 21 15:36:27 JST 2025
;; MSG SIZE rcvd: 50