CoreDNS Cache: خفّض DNS latency في Kubernetes من 42ms لـ 9ms
لو كل request عندك بيعمل DNS lookup بطيء، ضبط CoreDNS cache ممكن ينقل p95 من 42ms إلى 9ms قبل ما تزود أي replicas.
مستوى القارئ: متوسط
المشكلة باختصار
في Kubernetes، الـ Pod غالبًا بينادي خدمات بأسماء زي checkout.default.svc.cluster.local. Kubernetes بيجهز DNS records للـ Services والـ Pods، وبيخلي كل Pod يستخدم resolver داخلي بدل IP ثابت. ده ممتاز للتشغيل اليومي، لكنه يضغط CoreDNS لو عندك traffic عالي أو تطبيق بيعمل lookups كتير.
الطريقة الشائعة الغلط هنا إنك تزود عدد CoreDNS replicas فورًا. الطريقة دي بتفشل لو أصل المشكلة إن نفس الأسماء بتتسأل آلاف المرات في الدقيقة بدون cache مضبوط. هتكسب capacity مؤقتة، لكن هتخسر CPU وlatency ثابتة في كل query.
مثال بسيط قبل التعريف العلمي
ركز في المثال ده. عندك 40 microservice، وكل service بينادي auth.default.svc وpayments.default.svc في بداية كل request. لو عندك 1,000 request في الثانية، و10% منها بتعمل DNS lookup جديد، فأنت عندك حوالي 100 query في الثانية على CoreDNS من مسارين بس.
لو الاسم ثابت لمدة 30 ثانية، مفيش معنى تسأل backend كل مرة. الأفضل إن CoreDNS يرد من cache. بالظبط زي إنك تحفظ رقم داخلي بتستخدمه كل دقيقة بدل ما تفتح دليل الشركة في كل مكالمة.
علميًا، CoreDNS cache plugin بيحفظ DNS responses داخل الذاكرة حسب TTL. التوثيق الرسمي يذكر إن الـ cache يقسم العناصر إلى 256 shard، وبالإعداد الافتراضي يستوعب تقريبًا 9984 عنصر. كمان يتيح ضبط success وdenial وprefetch وserve_stale حسب احتياجك.
الإعداد العملي في Corefile
الافتراض إن عندك cluster Kubernetes بحجم متوسط: من 20 إلى 80 service، وCoreDNS شغال كـ Deployment في namespace اسمه kube-system. ابدأ بقياس الوضع الحالي، ثم غيّر Corefile، ثم قِس تاني.
# اعرض إعداد CoreDNS الحالي
kubectl -n kube-system get configmap coredns -o yaml
# افتح التعديل
kubectl -n kube-system edit configmap coredns
داخل Corefile استخدم إعداد محافظ بدل cache مفتوح بلا تفكير:
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30 {
success 20000 30 5
denial 5000 10 5
prefetch 20 1m 20%
serve_stale 30s verify
}
loop
reload
loadbalance
}