🚀

【Kubernetes】CoreDNSを使って自宅に内部向けのDNSサーバーを作ろう

2023/09/27に公開

はじめに

今回はkubernetesクラスタ上にCoreDNSのPodを立てて自宅内にDNSサーバーを構築しました。

構成図

192.168.150.0/24の空間にProxmoxのLXCで立てた4つのコンテナ上にKubernetesクラスタを構築しているのでそれにCoreDNSのPodを立てた。

CoreDNSについて

CoreDNSはCNCF社がGo言語を用いて作った物らしいです。そして、CoreDNSはKubernetes内部で使用されていたりするようにKubernetesとの親和性が高いと言われています。これは、データベースにetcdを使っていたりする点が挙げられるためです。一方で、dnsmasqやhostsファイルをベースに書けるところもメリットとして挙げられます。
https://coredns.io/

Podを建てる

今回はDNSサーバーを冗長化させるためにレプリカ数を3つにして構築を行う。そのため、Kubernetesクラスタ外部にDNSサーバーを公開するにあたって、負荷分散ができるようにするためにtype: LoadBalancerで公開することにする。

  1. MetalLBの導入
    MetalLBを導入するためにHelmを用いて行うことにする。そのためHelmの最新バージョンをインストールする。
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl diff -f - -n kube-system
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl apply -f - -n kube-system
helm repo add metallb https://metallb.github.io/metallb
kubectl create namespace metallb-system
helm install metallb metallb/metallb -n metallb-system
  1. マニフェストファイル(YAML)の作成
  • マニフェストファイル(ConfigMap)
coredns-custom-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns-custom-config
  namespace: default
data:
  Corefile: |
    .:53 {
      errors
      health
      hosts {
        192.168.150.1 proxmox.local
        192.168.150.2 nextcloud.local
        192.168.150.3 ntp.local
        192.168.150.10 ubuntu-vps.local
        192.168.150.11 school.local
        192.168.150.201 k8sc1.local
        192.168.150.211 k8sw1.local
        192.168.150.212 k8sw3.local
        192.168.150.213 k8sw3.local
        fallthrough
      }
      ready
      forward . 192.168.50.1
      loop
      reload
      loadbalance
    }
  • マニフェストファイル(Service)
coredns-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: coredns-service
spec:
  type: LoadBalancer
  selector:
    k8s-app: coredns
  loadBalancerIP: 192.168.150.252
  ports:
    - name: dns
      port: 53
      protocol: UDP
    - name: dns-tcp
      port: 53
      protocol: TCP
  • マニフェストファイル(deployment)
coredns-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: coredns-custom
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      k8s-app: coredns
  template:
    metadata:
      labels:
        k8s-app: coredns
    spec:
      containers:
        - name: coredns
          image: coredns/coredns:1.10.1
          args:
            - -conf
            - /etc/coredns/Corefile
          volumeMounts:
            - name: config-volume
              mountPath: /etc/coredns
              readOnly: true
      volumes:
        - name: config-volume
          configMap:
            name: coredns-custom-config
  1. 作成したマニフェストファイルをデプロイ
kubectl apply -f coredns-custom-config.yaml
kubectl apply -f coredns-service.yaml
kubectl apply -f coredns-deployment.yaml
  1. kubectl getしてみる
tochiman@k8sc1:~$ kubectl get service
NAME              TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)                     AGE
coredns-service   LoadBalancer   10.107.84.177   192.168.150.252   53:31883/UDP,53:31883/TCP   81m
kubernetes        ClusterIP      10.96.0.1       <none>            443/TCP                     3h9m
tochiman@k8sc1:~$ kubectl get deployments.apps
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
coredns-custom   3/3     3            3           81m
tochiman@k8sc1:~$ kubectl get configmaps
NAME                    DATA   AGE
coredns-custom-config   1      81m
kube-root-ca.crt        1      3h9m
tochiman@k8sc1:~$ kubectl get pods
NAME                              READY   STATUS    RESTARTS   AGE
coredns-custom-6bdc4558d6-9f8m5   1/1     Running   0          82m
coredns-custom-6bdc4558d6-mk6nz   1/1     Running   0          82m
coredns-custom-6bdc4558d6-sjp4z   1/1     Running   0          68m

検証

今回は、ConfigMapに記述した内部向けのFQDNに対してdigコマンドを用いて名前解決できるかを検証してみる。

dig ubuntu-vps.local @<Serviceで指定したloadBalancerIP>
; <<>> DiG 9.18.12-0ubuntu0.22.04.3-Ubuntu <<>> ubuntu-vps.local @192.168.150.252
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 47621
;; 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: 1ea7d550f5129d4c (echoed)
;; QUESTION SECTION:
;ubuntu-vps.local.		IN	A

;; ANSWER SECTION:
ubuntu-vps.local.	3600	IN	A	192.168.150.10

;; Query time: 0 msec
;; SERVER: 192.168.150.252#53(192.168.150.252) (UDP)
;; WHEN: Wed Sep 27 22:13:14 JST 2023
;; MSG SIZE  rcvd: 89

良さそう

終わりに

以上でCoreDNSの構築は以上になります。個人的に自宅のデスクトップのWebサイトへのアクセスが明らかに早くなったのが嬉しいです。

Discussion