[ตอนที่ 4] Deploy NodelocalDNS มาช่วย CoreDNS /Kube-dns
NodeLocal DNSCache ปรับปรุงประสิทธิภาพของ DNS Cluster โดยการเรียกใช้งาน Cache dns on Cluster node เป็น DaemonSet ทุกวันนี้ Pods ใช้งาน ClusterFirst DNS mode จะเข้าถึงบริการ kube-dns IP สำหรับการค้นหา DNS queries สิ่งนี้ถูกแปลเป็นปลายทาง kube-dns / CoreDNS โดยผ่าน iptables ที่เพิ่มเข้าไปโดย kube-proxy ดังนั้นด้วยสถาปัตยกรรมใหม่นี้ Pods จะเข้าถึง dns caching agent ที่ทำงานบน Node เดียวกันดังนั้นจึงหลีกเลี่ยง iptables DNAT rules and connection tracking. หน้าที่สำหรับ caching agent ค้นหาแคชที่หายไปของชื่อโฮสต์ของคลัสเตอร์ (cluster.local suffix by default) อ่านต่อที่
## ทำไมทางทีมเราถึงเลือก nodelocaldns
- Pod ที่มี DNS QPS สูงสุดต้องติดต่อกับโหนดอื่นหากไม่มี kube-dns / CoreDNS ดังนั้นการจำเป็นต้องมี Local cache มาช่วยเรื่อง latency time
- ข้าม iptables DNAT และการติดตามการเชื่อมต่อจะช่วยลดการแข่งขัน conntrack และหลีกเลี่ยงรายการ UDP DNS ที่เติมตาราง conntrack
- การเชื่อมต่อจาก local caching agent ไปยัง kube-dns service สามารถอัพเกรดเป็น TCP การทำงานของ TCP conntrack จะถูกลบเมื่อการเชื่อมต่อใกล้เคียงกับ UDP ที่หมดเวลา (ค่าเริ่มต้น nf_conntrack_udp_timeout คือ 30 วินาที)
- อัพเกรด DNS queries from UDP to TCP เนื่องจากแพ็คเก็ต UDP ที่ลดลงและการหมดเวลา DNS มักจะสูงถึง 30 วินาที (3 retries + 10s timeout)
- มี Metrics สามารถมองเห็น dns requests ในระดับ Node
- Negative caching สามารถเปิดใช้งานได้อีกครั้งซึ่งช่วยลดจำนวนการค้นหาไปยังบริการ kube-dns service.

## Download Source file

##Get IP kube-dns
kubectl get svc kube-dns -n kube-system -o jsonpath={.spec.clusterIP}

##Get dnsDomain
kubectl get cm -n kube-system kubeadm-config -o yaml |grep dnsDomain

## Note variables in the manifest with the right values:
kubedns=10.233.0.10
domain=cluster.local
localdns=169.254.20.10 ## (169.254.20.10 by default).
## If kube-proxy is running in IPVS mode:
**Default Template
sed -i "s/__PILLAR__LOCAL__DNS__/$localdns/g; s/__PILLAR__DNS__DOMAIN__/$domain/g; s/__PILLAR__DNS__SERVER__//g; s/__PILLAR__CLUSTER__DNS__/$kubedns/g" nodelocaldns.yaml
## Run cmd Custom Template
sed -i "s/__PILLAR__LOCAL__DNS__/169.254.20.10/g; s/__PILLAR__DNS__DOMAIN__/cluster.local/g; s/__PILLAR__DNS__SERVER__//g; s/__PILLAR__CLUSTER__DNS__/10.233.0.10/g" nodelocaldns.yaml
## Re-check nodelocaldns.yaml has error syntex
vi nodelocaldns.yaml
**solve by remove ,

## Deployment
kubectl create -f nodelocaldns.yaml
kubectl get pod -n kube-system

## Edit kubelet config (All Master / Work node)
อธิบายเพิ่มเติม เนื่องจาก Kubelet config ของทุกๆ Server (Master /Node) จะมี Parameter ชื่อ clusterDNS ชี้ไปยัง Service สำหรับการค้นหา DNS querie (kube-dns by default) เราจะแก้ไขให้ชี้ที่ 169.254.25.10 (IP Dummy Nodelocaldns)

10.233.0.10 == IP Service kube-dns
## edit kubelet config
vi /var/lib/kubelet/config.yaml
clusterDNS:- 10.233.0.10 >>> 169.254.20.10
## Restart kubelet service
systemctl daemon-reload
systemctl restart kubelet
## How to checking /etc/resolv.conf
## **Focus >> nameserver 169.254.25.10 (IP Dummy Nodelocaldns)
kubectl exec -ti nginx-76df748b9-r48lg — cat /etc/resolv.conf

PS. ถ้า Namesever ยังไม่เปลี่ยนจาก 10.233.0.10 >>> 169.254.20.10 แนะนำให้ Restart pod ก่อนนะครับ
ขอบคุณแหล่งเนื้อหาที่อ้างอิงครับ
https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/
https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/dns/nodelocaldns
https://github.com/kubernetes/kubernetes/issues/56903