رفتن به محتوا
IROSG.
مقاله‌ها

CoreDNS و زنجیره Plugin؛ یک Query چگونه از Corefile عبور می‌کند؟

CoreDNS با زنجیره Pluginها کار می‌کند؛ ترتیب و دامنه هر Plugin می‌تواند نتیجه DNS، Cache، Rewrite و Service Discovery را تغییر دهد.

CoreDNS و زنجیره Plugin؛ یک Query چگونه از Corefile عبور می‌کند؟

تصویر کلی

CoreDNS یک DNS Server ماژولار است و قابلیت‌ها از Pluginهایی مثل kubernetes، file، cache، rewrite و prometheus ساخته می‌شوند.

برای فهم این موضوع بهتر است اجزا را به‌عنوان یک مسیر ببینیم، نه مجموعه‌ای از گزینه‌های مستقل. در Production معمولاً مشکل زمانی شکل می‌گیرد که تنظیم روی دیسک، وضعیت Runtime و فرض تیم درباره رفتار سیستم با هم یکی نیستند. به همین دلیل مشاهده وضعیت مؤثر، Log و Metric باید کنار Configuration بررسی شود.

اجزای اصلی و مرز مسئولیت

Corefile مشخص می‌کند کدام Zone و Port با چه Pluginهایی پردازش شود؛ ترتیب اجرای زنجیره از ترتیب ثبت‌شده در باینری می‌آید، نه ترتیب خطوط Corefile.

در طراحی عملی، برای هر جزء یک سؤال روشن بنویسید: چه ورودی می‌گیرد، چه خروجی تولید می‌کند، چه Stateای نگه می‌دارد و در خرابی چه کسی مسئول Recovery است. این مدل ساده کمک می‌کند خطاهای شبکه، هویت، ذخیره‌سازی یا Replication به‌اشتباه به جزء دیگری نسبت داده نشوند.

خطاهای رایج

در Kubernetes، خطای DNS ممکن است از Service Discovery، Forwarder، NetworkPolicy یا Resolver کلاینت باشد؛ فقط Pod CoreDNS را متهم نکنید.

خطای دیگر، فعال‌کردن قابلیت پیشرفته بدون تعریف معیار موفقیت است. قبل از تغییر، Baseline بگیرید؛ بعد از تغییر همان Signalها را مقایسه کنید. اگر سیستم توزیع‌شده است، Failure Modeهای قطع شبکه، Restart، Lag، Timeout و از دست‌رفتن Dependency را نیز آزمایش کنید.

چک‌لیست عملی

  • نسخه و Configuration مؤثر را ثبت کنید، نه فقط فایل مورد انتظار را.
  • مسیر داده و کنترل را جدا رسم کنید.
  • Health، Latency، Error Rate و ظرفیت را قبل و بعد از تغییر مقایسه کنید.
  • برای تغییرات Stateful، Backup/Restore یا Rollback واقعی را آزمایش کنید.
  • دسترسی مدیریتی را حداقل کنید و Log تصمیم‌ها را نگه دارید.
  • مستندات همان نسخه محصول را مرجع نهایی قرار دهید.

تمرین IROSG

یک محیط کوچک آزمایشی بسازید و فقط یک Failure را تزریق کنید؛ مثلاً قطع Upstream، حذف یک Replica، خطای DNS یا تغییر Route. قبل از آزمایش بنویسید انتظار دارید کدام Metric و Log تغییر کند. بعد نتیجه واقعی را با انتظار مقایسه کنید. این تمرین معمولاً سریع‌تر از حفظ‌کردن Optionها، مدل ذهنی سیستم را اصلاح می‌کند.

مرجع

این راهنما بر پایه مستندات رسمی CoreDNS نوشته شده و مثال‌های عملی تحریریه برای آموزش دفاعی و عملیاتی هستند.

یک اصلاح مهم درباره ترتیب افزونه‌ها

Corefile تعیین می‌کند چه افزونه‌هایی برای یک server block پیکربندی شوند، اما ترتیب نوشتن خطوط آن الزاماً ترتیب اجرای زنجیره نیست. ترتیب ثبت‌شده هنگام ساخت باینری در plugin.cfg تعیین‌کننده است. بنابراین جابه‌جا کردن ظاهری دو خط لزوماً مسیر پردازش را عوض نمی‌کند. برای فهم رفتار، فهرست افزونه‌های باینری و مستندات هر افزونه را بررسی کنید. این نکته به‌ویژه وقتی cache، rewrite و افزونه پاسخ‌دهنده را کنار هم قرار می‌دهید اهمیت دارد.

پیش از زنجیره، server مناسب برای نام و پورت پرس‌وجو انتخاب می‌شود. اگر دو ناحیه با دامنه‌های هم‌پوشان دارید، ناحیه مشخص‌تر می‌تواند مسیر متفاوتی بسازد. یک نام زیر دامنه اصلی و یک نام زیر دامنه اختصاصی را جدا آزمایش کنید. این کار روشن می‌کند آیا خطا ناشی از انتخاب server block است یا رفتار افزونه داخل آن. بدون این تفکیک، ممکن است تنظیم درست را در بخشی تغییر دهید که پرس‌وجوی مسئله‌دار هرگز وارد آن نمی‌شود.

پاسخ‌دادن، عبور دادن و fallthrough

همه افزونه‌ها پاسخ نهایی تولید نمی‌کنند. برخی مشاهده یا تبدیل انجام می‌دهند و درخواست را به مرحله بعد می‌سپارند. افزونه‌ای که پاسخ قطعی می‌دهد ممکن است پردازش بعدی را پایان دهد. fallthrough یک قرارداد مشخص برای ادامه در شرایط تعریف‌شده است و نباید آن را به معنی «اگر هر خطایی رخ داد همه چیز را امتحان کن» فرض کرد. مستندات افزونه تعیین می‌کند چه نتیجه‌ای باعث ادامه می‌شود.

در آزمایش، سه پرس‌وجو انتخاب کنید: نامی که در منبع نخست وجود دارد، نامی که فقط در منبع بعدی پاسخ دارد و نامی که در هیچ‌کدام وجود ندارد. برای هر سه، کد پاسخ و محتوای بخش پاسخ را ثبت کنید. این مجموعه کوچک نشان می‌دهد کدام منبع واقعاً پاسخ داده و نام غایب چه سرنوشتی داشته است. یک پاسخ NXDOMAIN با timeout یا SERVFAIL تفاوت دارد و هرکدام مسیر بررسی متفاوتی می‌خواهند.

DNS درون Kubernetes را لایه‌بندی کنید

برای یک Service، نخست وجود خود شیء و endpointهای مورد انتظار را بررسی کنید. سپس از داخل Pod کلاینت، نام کامل و نام کوتاه را جدا پرس‌وجو کنید. resolver کلاینت می‌تواند با search domain و تنظیمات خود چند پرس‌وجو بسازد؛ این رفتار گاهی حجم درخواست یا تأخیر را افزایش می‌دهد. موفقیت نام کامل و شکست نام کوتاه سرنخ مهمی درباره تنظیمات کلاینت است، نه الزاماً خرابی افزونه kubernetes.

دسترسی CoreDNS به API خوشه نیز بخشی از زنجیره است. اگر داده سرویس‌ها به‌روز نمی‌شود، وضعیت اتصال و مجوز خواندن اطلاعات لازم را بررسی کنید. restart مکرر Podهای DNS ممکن است نشانه را موقتاً تغییر دهد اما خطای دسترسی را حل نمی‌کند. زمان ایجاد Service و زمان مشاهده پاسخ را کنار هم ثبت کنید تا تأخیر همگام‌سازی از cache قدیمی تفکیک شود. در محیط آزمایش، ساخت و حذف یک Service کوچک روش خوبی برای دیدن این مسیر است.

forward و حلقه ناخواسته

وقتی پرس‌وجو برای پاسخ به resolver دیگری فرستاده می‌شود، مقصد واقعی forwarder را بشناسید. فایل resolver میزبان ممکن است به یک نشانی محلی اشاره کند که در محیط کانتینر معنای متفاوتی دارد. اگر مسیر به خود CoreDNS برگردد، حلقه می‌تواند درخواست‌ها را بی‌نتیجه بچرخاند. نقشه ساده‌ای از نشانی listener و مقصد forward رسم کنید و هر گام را با پرس‌وجوی مستقیم آزمایش کنید.

پرس‌وجوی مستقیم به upstream باید از همان محیط شبکه‌ای انجام شود که CoreDNS در آن قرار دارد. موفقیت از لپ‌تاپ مدیر، دسترسی Pod را ثابت نمی‌کند. فایروال، policy خروجی و مسیر TCP و UDP را بررسی کنید. پاسخ‌های بزرگ یا شرایط خاص ممکن است به TCP نیاز پیدا کنند؛ باز بودن UDP تنها، تضمین همه رفتارهای DNS نیست. نمونه کوچک و نمونه‌ای با پاسخ بزرگ‌تر را در آزمون اتصال وارد کنید.

cache مثبت و منفی

cache می‌تواند تأخیر و بار upstream را کم کند، اما زمان دیده‌شدن تغییرات را نیز تحت تأثیر قرار می‌دهد. پاسخ درباره نبود نام هم ممکن است برای مدتی نگه‌داری شود. اگر بلافاصله پس از ساخت رکورد هنوز پاسخ منفی می‌بینید، همه لایه‌های cache را بررسی کنید: کلاینت، resolver میانی و CoreDNS. پاک کردن تنها یکی از آن‌ها ممکن است نتیجه را عوض نکند. زمان پاسخ و TTL باقی‌مانده سرنخ مفیدی برای این تحلیل است.

در آزمایش تغییر رکورد، یک نام اختصاصی انتخاب کنید تا با درخواست کاربران مخلوط نشود. ابتدا پاسخ و TTL را ثبت کنید، سپس تغییر را در منبع اعمال کنید و از چند مسیر مشخص دوباره پرس‌وجو کنید. هدف شناخت تأخیر انتشار در معماری شماست. وعده دیده‌شدن فوری تغییر با وجود cacheهای کنترل‌نشده دقیق نیست. اگر کاربردی نیاز به واکنش بسیار سریع دارد، باید TTL و رفتار کلاینت آن از ابتدا با این نیاز طراحی شود.

متریک و log برای پرسش مشخص

متریک نرخ پاسخ و تأخیر به تشخیص روند کمک می‌کند، ولی علت یک نام خاص را همیشه نشان نمی‌دهد. log پرس‌وجو می‌تواند نمونه دقیق بدهد، اما در حجم زیاد هزینه و حساسیت دارد. در عیب‌یابی، بازه و دامنه ثبت را تا حد لازم محدود کنید و پس از پایان به حالت معمول برگردانید. نام‌های DNS ممکن است اطلاعاتی درباره سامانه‌های داخلی و رفتار کاربران آشکار کنند؛ دسترسی به این log باید متناسب باشد.

کدهای پاسخ را جدا تحلیل کنید. افزایش NXDOMAIN ممکن است از نام‌سازی اشتباه برنامه یا جست‌وجوی چند پسوند بیاید، در حالی که افزایش SERVFAIL بیشتر به ناتوانی پردازش یا وابستگی مربوط است. timeout ممکن است حتی پیش از رسیدن درخواست به CoreDNS رخ دهد. برای یک نمونه، وجود درخواست در ورودی و نتیجه خروجی را با زمان کلاینت تطبیق دهید. این کار از نسبت دادن همه خطاهای نام به یک نمودار کلی جلوگیری می‌کند.

readiness و سلامت واقعی

endpoint سلامت یک فرایند با آمادگی آن برای پاسخ به همه ناحیه‌ها یکسان نیست. قابلیت readiness و رفتار افزونه‌های مورد استفاده را بررسی کنید. یک سرور ممکن است زنده باشد اما هنوز داده لازم را از API یا فایل نگرفته باشد. آزمون پذیرش باید پرس‌وجوی واقعی برای ناحیه‌های نماینده داشته باشد. پاسخ موفق برای یک دامنه عمومی، سلامت سرویس‌یابی داخلی را تضمین نمی‌کند.

در به‌روزرسانی پیکربندی، نخست اعتبار فایل و وجود افزونه‌ها را با همان باینری بررسی کنید. سپس چند پرس‌وجوی شاهد را پیش و پس از تغییر اجرا کنید و نسخه مؤثر را ثبت کنید. اگر روش reload استفاده می‌شود، مطمئن شوید تغییر واقعاً اعمال شده است. وجود فایل تازه روی دیسک به تنهایی کافی نیست. برای برگشت، نسخه قبلی و نتیجه آزمون‌های آن باید در دسترس باشد تا اصلاح عجولانه به حذف تنظیمات دیگر منجر نشود.

ظرفیت و توزیع درخواست

افزایش replicaهای DNS تنها وقتی مفید است که ترافیک واقعاً میان آن‌ها توزیع شود و گره‌های باقی‌مانده ظرفیت داشته باشند. توزیع درخواست را از متریک نمونه‌ها بررسی کنید. اگر یک کلاینت یا cache میانی بیشتر بار را به یک مقصد می‌فرستد، میانگین خوشه می‌تواند اشباع همان نمونه را پنهان کند. بار آزمایش را با تعداد کلاینت و الگوی نام‌های واقعی بسازید؛ پرس‌وجوی مکرر یک نام cacheشده رفتار متفاوتی از نام‌های متعدد دارد.

در گزارش عملیات، نام ناحیه، منبع پاسخ، upstream و قرارداد cache را کنار هم ثبت کنید. همکار بعدی باید بتواند بفهمد یک پرس‌وجو چرا از مسیر خاصی رفته است. مستندات افزونه‌ها در کنار Corefile و فهرست باینری، مجموعه کامل‌تری از واقعیت می‌سازند. راهنمای رسمی CoreDNS برای بررسی ترتیب زنجیره و انتخاب server مرجع تکمیلی این بخش است.

نمونه خطای قابل بازتولید

اگر برنامه تنها در بعضی گره‌ها نام را پیدا نمی‌کند، یک Pod آزمایشی مشابه را روی گره سالم و گره مسئله‌دار اجرا کنید. تنظیم resolver، مقصد DNS و نتیجه پرس‌وجوی مستقیم را مقایسه کنید. از نام کاملاً مشخص و یک نوع رکورد ثابت استفاده کنید تا تفاوت search domain یا درخواست هم‌زمان IPv6 نتیجه را مبهم نکند. سپس همان آزمایش را با مسیر عادی برنامه تکرار کنید. این مقایسه کوچک می‌تواند اختلاف تنظیمات گره، مسیر Service و رفتار کتابخانه resolver را از مشکل خود ناحیه جدا کند. نتیجه منفی نیز باید همراه timeout و مقصد دقیق ثبت شود تا آزمایش واقعاً قابل تکرار بماند.

TRACEABLE KNOWLEDGE

منابع و مطالعهٔ بیشتر

01
CoreDNS — مستندات رسمیhttps://coredns.io/

آخرین بررسی تحریریه:

IROSG / EDITORIAL

خبرها و معرفی مشاهیر با نگارش مستقل و ذکر منبع تهیه شده‌اند. اعتبار و مجوز تصاویر در بخش منابع همین صفحه نگه‌داری می‌شود تا متن زیر عکس‌ها شلوغ نشود. داده‌های مرجع CVE با اعتباردهی به منابع اصلی ارائه می‌شوند.

سیاست تألیف و حقوق تصاویر ↗

ادامهٔ کشف.

مقاله‌ها ↗