個人的に気になる記事を発見したので、読んだり、試してみたのでそのメモなど。
気になった記事
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でどれくらいクエリが発行されるか見てみる
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)
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)
※この場合は解決できない
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)
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による障害が起きるかもしれない。
検証はしていないが、こちらの記事に障害が発生したことや、クエリ量を少なくする対応を行ったことによってトラフィック量が減少したことを示されている。
クエリ量を減少させるための対応方法について考えてみる
これらがあると思う。
- 内部通信先のエンドポイント設定をFQDNにする
- dnsConfigを用いる
1. 内部通信先のエンドポイント設定をFQDNにする
これはあまりオススメはされていない。(たしかに「FQDNまで設定されているね。」と確認したくない。。。)
下記のコメントにはndotsがデフォルト5で設定されているの理由やsearchのリストについての背景などが記載されていたりしている。
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の負荷を軽減してくれそうな仕組みなので、今度動かしてみてみたいと思う。