حل DNS طويل في Kubernetes

تركز هذه المقالة على مشكلات DNS في Kubernetes التي واجهها فريقنا. كما اتضح ، أحيانًا ما تكمن المشكلة في أعمق مما تبدو عليه في البداية.


المقدمة


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


نظرًا لعدم استخدام أي شخص لـ Kubernetes من قبل ، فقد تم إعادة إنشاء المجموعة عدة مرات ، ولهذا السبب لم يكن لدينا الوقت لتقييم جودة التطبيقات المنقولة. وهكذا ، بعد النقل الرابع ، عندما تكون جميع المخاريط الرئيسية ممتلئة بالفعل ، يتم تجميع جميع الحاويات وكتابة جميع عمليات النشر ، يمكنك تحليل العمل المنجز ، وأخيرًا ، الانتقال إلى مهام أخرى.


11 ساعة ، بداية يوم العمل. يفتقر نظام المراقبة إلى جزء من الرسائل الواردة من أحد التطبيقات.


التشخيص


تم نقل التطبيق مؤخرًا إلى كتلة ويتكون من عامل بسيط صعد إلى قاعدة البيانات مرة واحدة كل بضع دقائق ، وفحصها بحثًا عن التغييرات ، وإذا وجدت ، أرسل رسالة إلى الحافلة. قبل بدء الاختبار وبعد انتهائه ، يكتب التطبيق رسالة إلى السجل. لا توازي ، لا تعدد المهام ، الموقد الوحيد الذي يحتوي على الحاوية الوحيدة فيه.


عند الفحص الدقيق ، أصبح من الواضح أن السجلات موجودة في وحدة التحكم ، ولكن في مرونة لم تعد هناك.


القليل من المعلومات حول نظام المراقبة: مجموعة Elasticsearch مع ثلاث عقد ، منتشرة في نفس Kubernetes ، تعرض باستخدام Kibana. دخلت السجلات إلى المرونة باستخدام حزمة Serilog.Sinks.Elasticsearch ، التي أرسلت الطلبات من خلال الوكلاء العكسيين المستندة إلى Nginx (في البداية تمت كتابة جميع الطلبات مع توقع عدم استخدام التفويض في Elasticsearch ، لذلك كان علي التخلص منها). أظهر فحص سجلات Nginx أنه في بعض الأحيان لا توجد طلبات من التطبيق على الإطلاق.


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


Serilog.Debugging.SelfLog.Enable(msg =>
{
  Serilog.Log.Logger.Error($"Serilog self log: {msg}");
});

أقوم ببناء جديد ، وأطلق الإصدار ، وتحقق من سجلات التطبيق. في كيبانا.


> Caught exception while preforming bulk operation to Elasticsearch: Elasticsearch.Net.ElasticsearchClientException: Maximum timeout reached while retrying request. Call: Status code unknown from: POST /_bulk

Elasticsearch , Elasticsearch . , HttpClient . , , .


, , . . , API Kubernetes, 5-10 100-150 . HTTP . .


– , , HTTP .


, , bash-, google.com :


while true;
do curl -w "%{time_total}\n" -o /dev/null -s "https://google.com/";
sleep 1;
done

– 5 .


صورة


, :


apiVersion: v1
kind: ConfigMap
metadata:
  name: ubuntu-test-scripts
data:
  loop.sh: |-
    apt-get update;
    apt-get install -y curl;
    while true;
    do echo $(date)'\n';
    curl -w "@/etc/script/curl.txt" -o /dev/null -s "https://google.com/";
    sleep 1;
    done
  curl.txt: |-
    lookup:        %{time_namelookup}\n
    connect:       %{time_connect}\n
    appconnect:    %{time_appconnect}\n
    pretransfer:   %{time_pretransfer}\n
    redirect:      %{time_redirect}\n
    starttransfer: %{time_starttransfer}\n
    total:         %{time_total}\n
---
apiVersion: v1
kind: Pod
metadata:
  name: ubuntu-test
  labels:
      app: ubuntu-test
spec:
  containers:
  - name: test
    image: ubuntu
    args: [/bin/sh, /etc/script/loop.sh]
    volumeMounts:
    - name: config
      mountPath: /etc/script
      readOnly: true
  volumes:
  - name: config
    configMap:
      defaultMode: 0755
      name: ubuntu-test-scripts

– google.com curl. , /dev/null, curl.


, , . – DNS ( – ). Kubernetes 1.14, , , .


, :


صورة


, – DNS-lookup, 99% – 5 . , .



.


, — 5 seconds dns resolve kubernetes.


, :



issue weave.


, :


  1. ( , – 2017 , , , ) .
  2. DNS lookup. , 10-15 .
  3. , DNS- VIP, DNAT.
  4. .

– race conditions conntraking Linux SNAT DNAT. Tobias Klausmann 2009 , Linux 5.0 , .


, Kubernetes DNS, race condition .


glibc ( Ubuntu, Debian . .), :


  1. glibc UDP (A AAAA). UDP connectionless , connect(2) , conntrack .
  2. DNS- Kubernetes VIP DNAT iptables.
  3. DNAT , netfilter :
    a. nf_conntrack_in: conntrack hash object .
    b. nf_nat_ipv4_fn: conntrack.
    c. nf_conntrack_confirm: , .
  4. UDP . , DNS-. , . - insert_failed, .


, workaround:


  1. DNS- nameserver. LocalDNS cache
  2. Weave tc(8) - AAAA DNS
  3. single-request-reopen resolv.conf

, .


Kubernetes 1.9, pod dnsConfig, resolv.conf.


pod, glibc A AAAA , race condition.


spec:
  dnsConfig:
    options:
    - name: single-request-reopen

, — glibc (, alpine, musl), resolv.conf .


ملحوظة: في حالتنا ، لأتمتة هذه العملية ، تمت كتابة أبسط تغيير على الويب ، والذي يضع تلقائيًا قسم التكوين هذا لجميع الحاضنات الجديدة في المجموعة. للأسف ، لا يمكنني تقديم الرمز.


All Articles