CoreDNS を使って自宅のネットワークに DNS サーバをたてました。
Kubernetesを構築して1プライベートのサービスを動かそうと思ってたんですが、そのときにサービスにもドメインつけたいし、サーバごにょごにょするときのもドメインほしいしってことでDNSサーバをたてました。
そもそもたてる必要あるの?
SSHするときもWebでアクセスするときもIPよりはドメインの方がいいので、なんらかのDNSサーバは必要でした。 DNSサーバの選択肢として、他にはパブリッククラウドのDNSサービス、ルータのDNS機能がありました。
簡単に比較するとこんな感じです。
項目 | クラウド | 自前CoreDNS | ルータ | コメント |
---|---|---|---|---|
料金 | 😷 | 😆 | 😆 | 有料か無料か |
反応速度 | 😷 | 😆 | 😆 | やっぱりローカルは圧倒的に速い |
運用 | 😆 | 😷 | 😷 | オンプレはだるい |
設定 | 😆 | 😆 | 😷 | /etc/hosts書き換えればOK |
自動化 | 😆 | 😃 | 😷 | etcdプラグインとか使えば簡単にできる |
機能 | 😄 | 😆 | 😷 | まあいろいろできる |
速くて無料で必要な機能が実現できる、ということで自前でDNSサーバたてることを選択しました。 運用に関しても、データぶっ飛んでもすぐ復旧できるレベルでしか使わないだろうし、なんか問題でてきたらクラウドに移せばいいぐらいの感覚です。
なんでCoreDNS?
CoreDNSっていうのはCNCFにホストされている、Goで書かれたDNSサーバです。
CoreDNSを選んだのはこのへんが理由です。
- CNCFのプロジェクトということで以前から使ってみたいと思ってた
- dnsmasq的な
/etc/hosts
での設定ができる - DB (etcd) をバックエンドにできるのでバックアップとか自動化とかが楽
- プラグインが簡単に書けるので楽しそう
- 設定がシンプル
- 機能が全部プラグインで実現されてるって思想が良い
- Goで書かれている
今までBind、dnsmasq、PowerDNSを構築、運用したことあるんですが、今の所一番気に入ってます。 使用感もいいし、わくわく感もあります。
構築手順
Kubernetesのマスターとなるサーバにインストールしました。以下rootでの実行コマンドです。
# ダウンロード、インストール
curl -LO https://github.com/coredns/coredns/releases/download/v1.6.9/coredns_1.6.9_linux_amd64.tgz
tar xf coredns_1.6.9_linux_amd64.tgz
mv coredns /usr/local/bin/
chown root. /usr/local/bin/coredns
# CoreDNS用ユーザの追加
useradd -l -r -s /usr/sbin/nologin -m -d /var/lib/coredns -c 'CoreDNS user' coredns
# systemdのユニットファイル
cat <<EOF > /etc/systemd/system/coredns.service > /etc/systemd/system/coredns.service
[Unit]
Description=CoreDNS
Documentation=https://coredns.io
After=network.target
[Service]
LimitNOFILE=1048576
LimitNPROC=512
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
User=coredns
WorkingDirectory=/var/lib/coredns
ExecStart=/usr/local/bin/coredns -conf=/etc/coredns/Corefile
ExecReload=/bin/kill -SIGUSR1 $MAINPID
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
# CoreDNSの設定
mkdir /etc/coredns
cat <<EOF > /etc/coredns/Corefile
(common) {
cache
errors
loop
}
. {
forward . 8.8.8.8 1.1.1.1
health :1053
import common
prometheus :9153
reload
}
nownabe.in {
hosts /etc/coredns/nownabe.in
import common
}
EOF
# nownabe.inのレコード設定
cat <<EOF > /etc/coredns/nownabe.in
10.0.0.2 rtx.cf.nownabe.in
10.0.1.1 sv-1.cf.nownabe.in dns.cf.nownabe.in kube-master.cf.nownabe.in
10.0.1.101 kube-worker-1.cf.nownabe.in
10.0.1.102 kube-worker-2.cf.nownabe.in
10.0.1.103 kube-worker-3.cf.nownabe.in
10.0.1.104 kube-worker-4.cf.nownabe.in
EOF
# CoreDNS有効化、起動
systemctl enable coredns
systemctl start coredns
バイナリひとつで動くのがいいですよね。Goプロダクトって感じです。
systemdのユニットファイルは、coredns/deploymentというリポジトリにあるcoredns.serviceを参考にしました。 ちょっと古かったり余計な権限がついてたりしたので、少し修正しています。
今の所レコードは/etc/hosts形式で設定しています。
DHCPの設定
ルータ RTX830 をDHCPサーバに使っているので、構築したDNSサーバを設定しました。
no dns server pp 1
no dns server dhcp lan2
no dns server select 500000 dhcp lan2 any .
no dns server select 500001 pp 1 any . restrict pp 1
dns server 10.0.1.1 8.8.8.8 1.1.1.1
dns notice order dhcp server
dns domain cf.nownabe.in
クライアントの設定
DHCPを使っていないサーバにはそれぞれ手動で設定しました。
いろいろあるのでそれぞれの設定は省略しますが、 /etc/resolv.conf
はこんな感じです。
nameserver 10.0.1.1
nameserver 8.8.8.8
nameserver 1.1.1.1
domain cf.nownabe.in
search cf.nownabe.in nownabe.in
試してみる
$ dig kube-worker-1.cf.nownabe.in
; <<>> DiG 9.11.5-P4-5.1ubuntu2.2-Ubuntu <<>> kube-worker-1.cf.nownabe.in
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39530
;; 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: 4096
; COOKIE: 10fad6c1cf5760b3 (echoed)
;; QUESTION SECTION:
;kube-worker-1.cf.nownabe.in. IN A
;; ANSWER SECTION:
kube-worker-1.cf.nownabe.in. 2288 IN A 10.0.1.101
;; Query time: 0 msec
;; SERVER: 10.0.1.1#53(10.0.1.1)
;; WHEN: 土 7月 11 21:35:29 JST 2020
;; MSG SIZE rcvd: 111
いいですねー。0msで答えが返ってきてます。
外部ドメインでもキャッシュされてると0msで返ってきます。
$ dig google.com
; <<>> DiG 9.11.5-P4-5.1ubuntu2.2-Ubuntu <<>> google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61410
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 1fc6abfd8e8a2b9d (echoed)
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 298 IN A 172.217.24.142
;; Query time: 0 msec
;; SERVER: 10.0.1.1#53(10.0.1.1)
;; WHEN: 土 7月 11 21:38:23 JST 2020
;; MSG SIZE rcvd: 77
パブリックDNSサーバに問い合わせると4msとかかかります。
$ dig google.com @8.8.8.8
; <<>> DiG 9.11.5-P4-5.1ubuntu2.2-Ubuntu <<>> google.com @8.8.8.8
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55448
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 203 IN A 172.217.27.78
;; Query time: 4 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: 土 7月 11 21:38:38 JST 2020
;; MSG SIZE rcvd: 55
ただ、キャッシュにのってない場合はめちゃくちゃ遅くなります。 うーんなんでだろう。2
$ dig google.com
; <<>> DiG 9.11.5-P4-5.1ubuntu2.2-Ubuntu <<>> google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32912
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 299 IN A 172.217.24.142
;; Query time: 84 msec
;; SERVER: 10.0.1.1#53(10.0.1.1)
;; WHEN: 土 7月 11 21:38:22 JST 2020
;; MSG SIZE rcvd: 65
おわりに
以上です。無事に ssh kube-worker-1
ができるようになって満足です。
キャッシュにのってない外部ドメインのクエリがめっちゃ遅いのは不便なのでなんとかしたいですね。2
今後は、簡単なWeb UIとかを作りたいなーと思ってます。
-
記事書いた直後に調べたら、単純にサーバから外に出る回線(PPPoE)が遅いだけだった ↩︎