🎃

EKSにNodeLocal DNSCacheを導入する

2023/11/25に公開

はじめに

Kubernetesは、負荷に応じてスケールアウトできたり、障害が発生した場合に自動的に復旧できるように設計されています。
が、その反面、Kubernetesクラスター内のPod間の通信は、DNSを経由して行われます。
そのため、DNSサーバーに負荷がかかると、クラスター全体に影響が出てしまいます。
この問題を解決するために、NodeLocal DNSCacheを導入します。
NodeLocal DNSCacheは、Kubernetes クラスター内の各ノードにデプロイされる DNS キャッシュサーバーです。
本記事では、EKSにNodeLocal DNSCacheを導入する方法を紹介します。

前提条件

  • EKSクラスターが作成済みであること
  • EKS on Fargateではなく、EC2ノードで構成されていること

NodeLocal DNSCacheの導入

まず、Github にある nodelocaldns.yaml をダウンロードします。

curl -O https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml

続いて、nodelocaldns.yaml__PILLAR__DNS__SERVER__, __PILLAR__LOCAL__DNS__, __PILLAR__DNS__DOMAIN__ の値を編集します。

  • __PILLAR__DNS__SERVER__ : kubectl get svc kube-dns -n kube-system -o jsonpath={.spec.clusterIP} で取得できます。
  • __PILLAR__LOCAL__DNS__ : 169.254.20.10がデフォルト値です。
  • __PILLAR__DNS__DOMAIN__ : cluster.localがデフォルト値です。

下記sedコマンドを実行すると、編集が完了します。

export DNS_SERVER=$(kubectl get svc kube-dns -n kube-system -o jsonpath={.spec.clusterIP})
export LOCAL_DNS=169.254.20.10
export DNS_DOMAIN=cluster.local
sed -i -e "s/__PILLAR__DNS__SERVER__/$DNS_SERVER/g" -e "s/__PILLAR__LOCAL__DNS__/$LOCAL_DNS/g" -e "s/__PILLAR__DNS__DOMAIN__/$DNS_DOMAIN/g" nodelocaldns.yaml

最後に、nodelocaldns.yaml を適用します。

kubectl apply -f nodelocaldns.yaml

動作確認

NodeLocal DNSCacheが正しく動作しているか確認するために、EKSのEC2ノードにSSHもしくはSesssion Managerでアクセスします。

ip addrで、nodelocaldns というインターフェースが追加されていることを確認します。

[root@admin]# ip addr
....省略....
3: nodelocaldns: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default
    link/ether 5a:12:93:b7:cc:1a brd ff:ff:ff:ff:ff:ff
    inet 169.254.20.10/32 scope global nodelocaldns
       valid_lft forever preferred_lft forever
    inet 10.100.0.10/32 scope global nodelocaldns
       valid_lft forever preferred_lft forever
....省略....

nodelocaldns というインターフェースが追加されていることが確認できます。

続いて、routel localnetで、先ほど設定した DNS_SERVERLOCAL_DNS が一致していることを確認します。

[root@admin]# routel local
         target            gateway          source    proto    scope    dev tbl
    10.100.0.10              local     10.100.0.10   kernel     hostnodelocaldns # 10.100.0.10は、自分のEKSクラスターのDNS_SERVERです。
     127.0.0.0/ 8            local       127.0.0.1   kernel     host     lo
      127.0.0.1              local       127.0.0.1   kernel     host     lo
127.255.255.255          broadcast       127.0.0.1   kernel     link     lo
  169.254.20.10              local   169.254.20.10   kernel     hostnodelocaldns # LOCAL_DNSと一致していることを確認
    172.31.1.92              local     172.31.1.92   kernel     host   eth1
   172.31.1.223              local    172.31.1.223   kernel     host   eth0
   172.31.1.255          broadcast    172.31.1.223   kernel     link   eth0
   172.31.1.255          broadcast     172.31.1.92   kernel     link   eth1

routel localnet というルーティングルールが追加されていることが確認できます。

最後に、dig もしくは nslookup コマンドで、名前解決ができることを確認します。

[root@admin]# dig google.com

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.13.5 <<>> google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59583
;; 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.             251     IN      A       172.217.31.174

;; Query time: 1 msec
;; SERVER: 172.31.0.2#53(172.31.0.2)
;; WHEN: Sat Nov 25 12:47:24 UTC 2023
;; MSG SIZE  rcvd: 55

名前解決ができることが確認できます。

まとめ

本記事では、EKSにNodeLocal DNSCacheを導入する方法を紹介しました。
NodeLocal DNSCacheを導入することで、DNSサーバーに負荷がかかることを防ぐことができるので、
特に第三者サービスとの通信が多い場合には、ぜひ導入してみてください。

Discussion