الرئيسيةمن أناالدوراتالمدونةسوق الأوامرالمناهج والباقاتالشركاء

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

المنصة مبنية على الوضوح، التطبيق، والنتيجة النافعة: شرح مرتب يساعدك تفهم الأدوات، تكتب كودًا أفضل، وتستخدم الذكاء الاصطناعي بوعي داخل العمل الحقيقي.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • المناهج والباقات
  • سوق الأوامر
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالمناهجالمدونةالدخول
DevOps بالعربي

ndots:5: ليه نداء DNS واحد في Kubernetes بيتحوّل لـ 5 استعلامات

محترف28 يوليو 20265 دقائق قراءة
ndots:5: ليه نداء DNS واحد في Kubernetes بيتحوّل لـ 5 استعلامات

مستوى المقال: محترف — يفترض إنك بتشغّل خدمات على Kubernetes وعندك إلمام بـ Pods و resolv.conf وأساسيات DNS.

ndots:5: ليه نداء DNS واحد في Kubernetes بيتحوّل لـ 5 استعلامات

تقدر تشيل عشرات المللي ثانية من زمن كل نداء خارجي في كلاستر Kubernetes بسطر واحد في تعريف الـ Pod. المشكلة مش في الشبكة ولا في CoreDNS نفسه، المشكلة في إعداد افتراضي اسمه ndots:5 بيخلّي كل نداء لاسم خارجي زي api.stripe.com يتحوّل لحد 5 استعلامات DNS بدل استعلام واحد.

المشكلة باختصار

خدمتك بتنادي API خارجي، والـ p99 بيقفز بشكل غير مفهوم رغم إن الترافيك عادي والـ CPU مرتاح. تفتح traces تلاقي وقت ضايع قبل أول بايت في الاتصال. ده وقت resolution، مش وقت السيرفر البعيد. السبب إن الـ Pod بيسأل DNS كذا مرة على كل اسم قبل ما يوصل للإجابة الصح.

يعني إيه ndots أصلًا؟ (المثال البسيط الأول)

تخيّل إنك في مكتب فيه سنترال داخلي. لو قلت للسنترال رقم قصير زي "204"، هو مش هيفترض إنه رقم خارجي، هيحاول يوصّلك جوّه الشركة الأول. لو قلتله رقم طويل واضح إنه خارجي، هيطلبه على طول برّه. ndots هو بالظبط "كام نقطة لازم يكون في الاسم عشان النظام يعتبره اسمًا خارجيًا كاملًا ويطلبه دايركت".

في Kubernetes، القيمة الافتراضية ndots:5. يعني أي اسم فيه أقل من 5 نقاط، النظام هيفترض إنه اسم داخلي ناقص، وهيحاول يكمّله بالـ search domains بتاعة الـ Pod الأول قبل ما يجرّبه كاسم مطلق. اسم زي api.stripe.com فيه نقطتين بس، فبيقع تحت الشرط ده.

الشرح العلمي الدقيق

كل Pod بياخد ملف /etc/resolv.conf شبه ده:

search default.svc.cluster.local svc.cluster.local cluster.local ec2.internal
nameserver 10.96.0.10
options ndots:5

لمّا الـ resolver يشوف اسمًا فيه عدد نقاط أقل من ndots، بيطبّق قاعدة الـ search list: بيلزق كل search domain على الاسم ويسأل عليه بالترتيب، ولو كلهم فشلوا يسأل على الاسم المطلق في الآخر. يعني api.stripe.com بيتحوّل عمليًا للتسلسل ده:

  1. api.stripe.com.default.svc.cluster.local ← NXDOMAIN
  2. api.stripe.com.svc.cluster.local ← NXDOMAIN
  3. api.stripe.com.cluster.local ← NXDOMAIN
  4. api.stripe.com.ec2.internal ← NXDOMAIN
  5. api.stripe.com. ← الإجابة الصح أخيرًا

كل ده لاستعلام واحد. وبما إن الـ stub resolver بيسأل عن سجل A و AAAA مع بعض، اضرب العدد في 2: ممكن توصل لحوالي 10 حزم DNS لكل نداء خارجي واحد.

ليه ده بيوجع في الإنتاج؟

الافتراض إن عندك خدمة بتعمل نداءات كتير لـ APIs خارجية (بوابة دفع، مخزن كائنات، Webhooks). لو الخدمة بتفتح اتصال جديد لكل نداء من غير reuse، كل اتصال بيدفع ضريبة الـ 4 استعلامات الفاشلة قبل الاستعلام الصح.

على كلاستر تحت ضغط، النتيجة زمن ذيل (tail latency) بيقفز. سيناريو واقعي: خدمة بتعمل حوالي 2000 نداء خارجي في الثانية، النقلة من 5 استعلامات لاستعلام واحد بتنزّل حِمل الاستعلامات على CoreDNS بحوالي 80%. والأخطر: مع سباق معروف في conntrack عند ترجمة عناوين UDP، ممكن حزمة DNS تتفقد وتستنى الـ timeout الافتراضي (5 ثواني) قبل إعادة المحاولة، فتشوف نداء عادي فجأة بياخد 5 ثواني كاملة.

الحل: خطوات قابلة للنسخ

أفضل طريقة هي إنك تقلّل عدد الاستعلامات لكل اسم خارجي. عندك ثلاث روافع، مرتبة بالأولوية:

  1. اضبط ndots للـ workload اللي بيكلّم برّه. حط ndots:2 في dnsConfig على مستوى الـ Pod. ده بيلغي جولات الـ search domains لمعظم أسماء الـ APIs الخارجية مع الحفاظ على اكتشاف الخدمات الداخلية بالأسماء القصيرة المعتادة.
  2. استخدم FQDN بنقطة نهائية. لو الاسم في كودك أو إعداداتك مكتوب api.stripe.com. بنقطة في الآخر، الـ resolver بيعتبره اسمًا مطلقًا ويسأل عليه مرة واحدة مباشرة، من غير ما تلمس أي إعداد كلاستر.
  3. شغّل NodeLocal DNSCache. كاش DNS على كل node بيقصّر مسار الاستعلام ويقلّل ضربات conntrack، ومفيد على الكلاسترات الكبيرة تحت ضغط عالي.

ده الباتش المباشر على الـ Deployment:

YAML
spec:
  template:
    spec:
      dnsConfig:
        options:
          - name: ndots
            value: "2"

للتحقق إنه اشتغل، قيس زمن الـ resolution جوّه الـ Pod قبل وبعد:

Bash
# شوف الإعداد الحالي
kubectl exec deploy/my-app -- cat /etc/resolv.conf

# قِس زمن اكتشاف الاسم فقط (بدون وقت النقل)
kubectl exec deploy/my-app -- \
  curl -o /dev/null -s -w 'dns=%{time_namelookup}s total=%{time_total}s\n' \
  https://api.stripe.com/healthcheck

لو time_namelookup نزل من حدود 0.2 ثانية لحدود 0.02 ثانية، يبقى القاعدة خلاص مش بتضربك.

الـ trade-offs

لا يوجد حل مجاني. لو نزّلت ndots لـ 1 أو 2 على مستوى الكلاستر كله، الأسماء الداخلية اللي بتعتمد على أكتر من search domain (زي نداء خدمة في namespace تاني بالاسم القصير) ممكن تفشل. المكسب: استعلامات أقل وزمن أقل. الخسارة: لازم تكتب أسماء الخدمات الداخلية بشكل أكمل (مثلًا svc.namespace بدل svc). عشان كده الأأمن هو ضبط ndots على مستوى الـ Pod للـ workloads اللي بتكلّم الخارج بس، مش على مستوى الكلاستر.

أما NodeLocal DNSCache فبيكسّبك استقرارًا كبيرًا، مقابل مكوّن إضافي (DaemonSet) لازم تراقبه وتحدّثه.

متى لا تستخدم هذه الطريقة

لو خدمتك بتعمل reuse كويس للاتصالات (connection pooling / keep-alive) وبتنادي عدد صغير من الأسماء الخارجية، الـ resolution بيحصل مرات قليلة جدًا والكاش بيغطّيها، فالمكسب هيبقى مهمَل ومش مستاهل تعقيد. كمان لو كلاسترك صغير وترافيك الـ DNS تحته بعيد عن أي سقف، سيبها زي ما هي. ركّز جهدك على reuse الاتصالات الأول، لأنه بيحل جذر المشكلة قبل أي ضبط لـ ndots.

الخطوة التالية

افتح traces خدمة واحدة بتكلّم API خارجي، ودوّر على time_namelookup أو أي وقت resolution متكرر. لو لقيته أكبر من زمن النقل نفسه، ضيف باتش dnsConfig بـ ndots:2 على الـ Deployment بتاعها بس، وقارن الأرقام قبل وبعد بأمر الـ curl فوق. لو الفرق واضح، عمّمه على باقي الخدمات اللي بتكلّم الخارج.

المصادر

  • Kubernetes Docs — DNS for Services and Pods (dnsConfig و ndots)
  • Marco Pracucci — Kubernetes pods /etc/resolv.conf ndots:5 option and why it may negatively affect performance
  • Kubernetes Docs — Using NodeLocal DNSCache
  • kubernetes/kubernetes #56903 — DNS intermittent delays (conntrack UDP race)

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة