記録。

めも。

kube-dnsとDNS resolveのことで気になったこと

個人的に気になる記事を発見したので、読んだり、試してみたのでそのメモなど。

気になった記事

NodeLocal DNSCacheを導入するまでの過程. この記事は ミクシィグループ Advent Calendar… | by Naohiro Kurihara | mixi developers | Dec, 2020 | Medium

Karan Sharma | DNS Lookups in Kubernetes

kube-dnsがどのようにクエリをさばいているか確認してみる

環境

GKE 1.16.15-gke.6000

どんなクエリが生成されるか見てみる

通信先のserviceやdeployment

apiVersion: v1
kind: Service
metadata:
  name: hoge-go
  namespace: hoge
spec:
  selector:
    app: hoge-go
  ports:
    - port: 80
      targetPort: 80

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hoge-go
  namespace: hoge
spec:
  replicas: 2
  selector:
    matchLabels:
      app: hoge-go
  template:
    metadata:
      labels:
        app: hoge-go
    spec:
      containers:
        - name: hoge-go
          image: hoge-go
          resources:
            limits:
              memory: "50Mi"
              cpu: "50m"
          ports:
            - containerPort: 80

通信するクライアント用のpod生成

kubectl run multitool --image=praqma/network-multitool --replicas=1

tcpdumpでどれくらいクエリが発行されるか見てみる

  1. nslookup hoge-go.hoge
bash-5.0# tcpdump -n dst port 53


10:40:14.158155 IP 10.0.1.10.48385 > 10.4.0.10.53: 54428+ A? hoge-go.hoge.default.svc.cluster.local. (56)
10:40:14.159412 IP 10.0.1.10.41017 > 10.4.0.10.53: 35215+ A? hoge-go.hoge.svc.cluster.local. (48)
10:40:14.161212 IP 10.0.1.10.47116 > 10.4.0.10.53: 40310+ AAAA? hoge-go.hoge.svc.cluster.local. (48)
  1. nslookup hoge-go.hoge.
10:42:21.884964 IP 10.0.1.10.58678 > 10.4.0.10.53: 8623+ A? hoge-go.hoge. (30)

※この場合は解決できない

  1. nslookup hoge-go.hoge.svc.cluster.local

10:42:59.527023 IP 10.0.1.10.44223 > 10.4.0.10.53: 58441+ A? hoge-go.hoge.svc.cluster.local.default.svc.cluster.local. (74)
10:42:59.529878 IP 10.0.1.10.59164 > 10.4.0.10.53: 37994+ A? hoge-go.hoge.svc.cluster.local.svc.cluster.local. (66)
10:42:59.532175 IP 10.0.1.10.60062 > 10.4.0.10.53: 37258+ A? hoge-go.hoge.svc.cluster.local.cluster.local. (62)
10:42:59.533090 IP 10.0.1.10.40975 > 10.4.0.10.53: 57453+ A? hoge-go.hoge.svc.cluster.local.asia-northeast1-a.c.test.internal. (98)
10:42:59.536537 IP 10.0.1.10.45882 > 10.4.0.10.53: 20638+ A? hoge-go.hoge.svc.cluster.local.c.test.internal. (80)
10:42:59.539721 IP 10.0.1.10.57718 > 10.4.0.10.53: 39085+ A? hoge-go.hoge.svc.cluster.local.google.internal. (64)
10:42:59.542635 IP 10.0.1.10.48161 > 10.4.0.10.53: 49588+ A? hoge-go.hoge.svc.cluster.local. (48)
10:42:59.544235 IP 10.0.1.10.42390 > 10.4.0.10.53: 37242+ AAAA? hoge-go.hoge.svc.cluster.local. (48)
  1. nslookup hoge-go.hoge.svc.cluster.local.
10:45:12.725623 IP 10.0.1.10.51546 > 10.4.0.10.53: 49162+ A? hoge-go.hoge.svc.cluster.local. (48)
10:45:12.727908 IP 10.0.1.10.41173 > 10.4.0.10.53: 49705+ AAAA? hoge-go.hoge.svc.cluster.local. (48)

AAAAレコードをいったん抜きにしてみてみると最後の . まで加えたFQDNでの名前解決は発行数が少ない。

FQDNを使用していない場合は発行数が多い(1と3の発行数が異なる理由は後述)

クライアント用のpodのresolv.confを確認してみる

bash-5.0# cat /etc/resolv.conf

nameserver 10.4.0.10
search default.svc.cluster.local svc.cluster.local cluster.local asia-northeast1-a.c.test.internal c.test.internal google.internal
options ndots:5

nameserverはkube-dnsのservice

% kubectl get svc -n kube-system | grep kube-dns

kube-dns               ClusterIP   10.4.0.10    <none>        53/UDP,53/TCP   16d

ndotsは5に設定されている。

そのため前述の1~3までの問い合わせはドット数が5より少ないため searchで設定されている検索リストを順番に試すことになる。

1と3がクエリの発行数が違うのは1の場合、searchの左から2番目( svc.cluster.local )を試して成功したから少ないということだった。

3番目のクエリはsearch全て試して解決できなく、最後のFQDNで解決できるまでにたくさんのクエリが発行されてしまった。

もしかしたらDNSで障害が発生する可能性があるかもしれない

例えば、マイクロサービスでたくさんの内部通信が発生していて

気づかぬうちに大量のDNS解決のクエリが発行されていたらDNSによる障害が起きるかもしれない。

検証はしていないが、こちらの記事に障害が発生したことや、クエリ量を少なくする対応を行ったことによってトラフィック量が減少したことを示されている。

Kubernetes pods /etc/resolv.conf ndots:5 option and why it may negatively affect your application performances

クエリ量を減少させるための対応方法について考えてみる

これらがあると思う。

  1. 内部通信先のエンドポイント設定をFQDNにする
  2. dnsConfigを用いる

1. 内部通信先のエンドポイント設定をFQDNにする

これはあまりオススメはされていない。(たしかに「FQDNまで設定されているね。」と確認したくない。。。)

下記のコメントにはndotsがデフォルト5で設定されているの理由やsearchのリストについての背景などが記載されていたりしている。

Kube-dns add-on should accept option ndots for SkyDNS or document ConfigMap alternative subPath · Issue #33554 · kubernetes/kubernetes · GitHub

2. dnsConfigを用いる

dnsConfigを用いることでPodのresolv.confをカスタマイズすることができる。

この機能はkubernetesのversion 1.14からはstableになっている。

https://kubernetes.io/ja/docs/concepts/services-networking/dns-pod-service/#pod-dns-config

ドキュメントの例を見てもsearchやndotsなど様々な設定ができることがわかる。

最後に

2つの方法で対応できると記載したが、GKEにはNodeLocalDNSCacheというものが提供されていた。

これもkube-dnsの負荷を軽減してくれそうな仕組みなので、今度動かしてみてみたいと思う。

cloud.google.com