مجله ایرانیکاسرورآموزش سرور، هاست، وردپرس و شبکه
آموزشی

رفع مشکل DNS داخل Docker Container؛ از تشخیص تا تنظیم DNS

اگر کانتینر Docker به اینترنت دسترسی دارد اما دستورهایی مثل curl، apt، apk یا برنامه داخل کانتینر نمی‌توانند نام دامنه را Resolve کنند، احتمالاً با مشکل DNS داخل Docker Container روبه‌رو هستید. قبل از…

رفع مشکل DNS داخل Docker Container؛ از تشخیص تا تنظیم DNS
خلاصه سریع این آموزش

اگر کانتینر Docker به اینترنت دسترسی دارد اما دستورهایی مثل curl، apt، apk یا برنامه داخل کانتینر نمی‌توانند نام دامنه را Resolve کنند، احتمالاً با مشکل DNS داخل Docker Container…

۱۰ دقیقه مطالعه ۰ دیدگاه ۱۲ مهر ۱۴۰۵ آخرین به‌روزرسانی

اگر کانتینر Docker به اینترنت دسترسی دارد اما دستورهایی مثل curl، apt، apk یا برنامه داخل کانتینر نمی‌توانند نام دامنه را Resolve کنند، احتمالاً با مشکل DNS داخل Docker Container روبه‌رو هستید. قبل از تغییر تنظیمات Docker باید مشخص کنید مشکل واقعاً DNS است یا کانتینر به‌طور کلی به شبکه دسترسی ندارد.

پاسخ سریع: اگر دسترسی به IP برقرار است اما نام دامنه Resolve نمی‌شود، ابتدا /etc/resolv.conf داخل کانتینر را بررسی کنید. در شبکه‌های سفارشی Docker مشاهده 127.0.0.11 طبیعی است؛ این آدرس DNS داخلی Docker است. اگر resolver بالادستی مشکل دارد، می‌توانید DNS را برای همان کانتینر، Docker Compose یا کل Docker Engine مشخص کنید.

DNS در Docker چگونه کار می‌کند؟

Docker برای تبدیل نام‌هایی مانند example.com به IP از تنظیمات DNS میزبان و resolver داخلی خودش استفاده می‌کند. رفتار دقیق به نوع شبکه کانتینر بستگی دارد.

رفتار DNS در شبکه‌های Docker
نوع شبکه رفتار معمول DNS
Default Bridge کانتینر تنظیمات DNS میزبان را دریافت می‌کند.
User-defined Network Docker معمولاً resolver داخلی خود با آدرس 127.0.0.11 را در اختیار کانتینر قرار می‌دهد.
DNS سفارشی می‌توان DNS را با –dns یا گزینه dns در Compose مشخص کرد.

بنابراین اگر داخل یک کانتینر دستور زیر را اجرا کردید و 127.0.0.11 دیدید، فوراً آن را به‌عنوان خطا در نظر نگیرید.

docker exec CONTAINER_NAME cat /etc/resolv.conf

به‌جای CONTAINER_NAME نام واقعی کانتینر را قرار دهید.

مرحله ۱: مطمئن شوید مشکل واقعاً DNS است

مهم‌ترین مرحله همین است. اگر کل ارتباط شبکه Docker خراب باشد، تغییر DNS مشکل را حل نمی‌کند.

ابتدا کانتینرهای فعال را ببینید:

docker ps

حالا وارد کانتینر موردنظر شوید. برای بسیاری از ایمیج‌های لینوکسی می‌توانید از دستور زیر استفاده کنید:

docker exec -it CONTAINER_NAME sh

اگر Bash داخل ایمیج نصب است:

docker exec -it CONTAINER_NAME bash

تست دسترسی به IP

اگر ابزار ping در ایمیج موجود است، یک IP عمومی را آزمایش کنید:

ping -c 4 1.1.1.1

سپس یک دامنه را آزمایش کنید:

ping -c 4 example.com

نتیجه را این‌طور تفسیر کنید:

🔹 اگر IP کار می‌کند ولی دامنه نه، مشکل به احتمال زیاد مربوط به DNS است.

🔹 اگر IP هم قابل دسترس نیست، ابتدا شبکه Docker، NAT، Forwarding و Firewall را بررسی کنید.

🔹 اگر فقط یک دامنه خاص Resolve نمی‌شود، مشکل الزاماً از Docker نیست.

نبودن دستور ping نیز به معنی خرابی شبکه نیست؛ بعضی ایمیج‌های مینیمال این ابزار را نصب ندارند.

مرحله ۲: فایل resolv.conf داخل کانتینر را بررسی کنید

docker exec CONTAINER_NAME cat /etc/resolv.conf

در یک شبکه سفارشی Docker ممکن است خروجی شامل این مقدار باشد:

nameserver 127.0.0.11

این آدرس مربوط به DNS داخلی Docker است و وجود آن در این شرایط طبیعی است. Docker درخواست‌های DNS خارجی را به resolverهای بالادستی ارسال می‌کند و همچنین از DNS داخلی برای قابلیت‌هایی مانند Resolve شدن نام سرویس‌ها در شبکه‌های Docker استفاده می‌کند.

مرحله ۳: DNS خود سرور میزبان را آزمایش کنید

قبل از دست‌کاری Docker مطمئن شوید خود VPS می‌تواند دامنه‌ها را Resolve کند.

getent hosts example.com
cat /etc/resolv.conf

در Ubuntuهایی که از systemd-resolved استفاده می‌کنند، این دستور نیز اطلاعات مفیدی می‌دهد:

resolvectl status

اگر خود میزبان نیز نمی‌تواند دامنه‌ها را Resolve کند، بهتر است ابتدا DNS سیستم‌عامل را اصلاح کنید؛ تنظیم DNS داخل کانتینر در این حالت ممکن است فقط علامت مشکل را دور بزند.

مرحله ۴: تست یک کانتینر جدید با DNS مشخص

برای اینکه بدون تغییر تنظیمات اصلی سرور بفهمیم مشکل از DNS پیش‌فرض است یا نه، یک کانتینر موقت با DNS مشخص اجرا کنید:

docker run --rm --dns 1.1.1.1 busybox nslookup example.com

می‌توانید DNS دیگری را نیز جداگانه امتحان کنید:

docker run --rm --dns 8.8.8.8 busybox nslookup example.com

اگر این تست موفق است اما همان کانتینر بدون گزینه –dns نمی‌تواند دامنه را Resolve کند، شواهد قوی‌تری دارید که مشکل در مسیر DNS پیش‌فرض Docker یا resolver بالادستی آن قرار دارد.

⚠️ نکته: انتخاب DNS عمومی باید با شرایط شبکه شما سازگار باشد. اگر برنامه باید دامنه‌های داخلی سازمان را Resolve کند، جایگزین کردن DNS داخلی با یک resolver عمومی می‌تواند دسترسی به نام‌های داخلی را از بین ببرد.

راه‌حل اول: تعیین DNS فقط برای یک Container

اگر نمی‌خواهید تنظیمات کل Docker را تغییر دهید، DNS را فقط هنگام ساخت کانتینر تعیین کنید:

docker run --dns 1.1.1.1 --dns 8.8.8.8 IMAGE_NAME

این روش زمانی مناسب است که مشکل فقط یک سرویس را درگیر کرده یا می‌خواهید پیش از اعمال تغییر سراسری نتیجه را آزمایش کنید.

راه‌حل دوم: تنظیم DNS در Docker Compose

اگر برنامه را با Docker Compose اجرا می‌کنید، گزینه dns را به سرویس موردنظر اضافه کنید:

services:
  app:
    image: IMAGE_NAME
    dns:
      - 1.1.1.1
      - 8.8.8.8

بعد از ذخیره فایل Compose، کانتینر سرویس باید با تنظیم جدید دوباره ساخته شود:

docker compose up -d --force-recreate

اگر چند سرویس دارید، لازم نیست DNS را بدون دلیل برای همه آن‌ها تغییر دهید؛ ابتدا سرویس مشکل‌دار را مشخص کنید.

راه‌حل سوم: تنظیم DNS برای کل Docker Engine

اگر تعداد زیادی کانتینر با همین مشکل مواجه‌اند و مشخص شده resolver پیش‌فرض مناسب نیست، می‌توانید DNS را در تنظیمات Docker daemon مشخص کنید.

⚠️ قبل از تغییر: ری‌استارت Docker می‌تواند روی سرویس‌های در حال اجرا اثر بگذارد. روی سرور Production ابتدا کانتینرهای فعال و سیاست Restart آن‌ها را بررسی کنید و تغییر را در زمان مناسب انجام دهید.

ابتدا فایل فعلی را در صورت وجود مشاهده کنید:

sudo cat /etc/docker/daemon.json

اگر فایل از قبل وجود دارد، از آن نسخه پشتیبان بگیرید:

sudo cp /etc/docker/daemon.json /etc/docker/daemon.json.bak

سپس فایل را ویرایش کنید:

sudo nano /etc/docker/daemon.json

برای نمونه، در یک فایل خالی می‌توانید چنین تنظیمی داشته باشید:

{
  "dns": ["1.1.1.1", "8.8.8.8"]
}

اگر فایل از قبل تنظیمات دیگری دارد، محتوای آن را پاک نکنید. کلید dns باید به JSON موجود اضافه شود و ساختار JSON معتبر باقی بماند.

قبل از Restart می‌توانید اعتبار فایل پیکربندی Docker را بررسی کنید:

sudo dockerd --validate --config-file=/etc/docker/daemon.json

اگر اعتبارسنجی موفق بود، Docker را ری‌استارت کنید:

sudo systemctl restart docker

سپس وضعیت سرویس را بررسی کنید:

systemctl status docker --no-pager

اگر Docker پس از تغییر بالا نیامد، لاگ‌ها را ببینید:

journalctl -u docker -n 100 --no-pager

برای بازگشت به تنظیم قبلی، در صورتی که فایل پشتیبان ساخته‌اید:

sudo cp /etc/docker/daemon.json.bak /etc/docker/daemon.json
sudo systemctl restart docker

Docker روی VPS اجرا می‌کنید؟

برای اجرای سرویس‌های Docker به یک سرور لینوکسی با شبکه پایدار و منابع متناسب با تعداد کانتینرها نیاز دارید. در صورت نیاز می‌توانید پلن‌های VPS ایران ایرانیکاسرور را بررسی کنید.

مشکل systemd-resolved و آدرس‌های Loopback

یکی از مواردی که در عیب‌یابی DNS باید به آن توجه کنید resolver محلی میزبان است. یک آدرس Loopback روی میزبان لزوماً از داخل namespace شبکه کانتینر همان معنی را ندارد. برای مثال 127.0.0.1 داخل کانتینر به خود کانتینر اشاره می‌کند، نه میزبان.

به همین دلیل تنظیم کردن این مقدار به‌عنوان DNS کانتینر معمولاً راه‌حل صحیحی نیست:

--dns 127.0.0.1

برای بررسی وضعیت resolver میزبان Ubuntu از این دستور استفاده کنید:

resolvectl status

اگر مشکل DNS روی خود Ubuntu هم وجود دارد، ابتدا resolver میزبان را عیب‌یابی کنید و بعد سراغ تغییر Docker بروید.

چرا ویرایش دستی resolv.conf داخل کانتینر راه‌حل خوبی نیست؟

ممکن است وسوسه شوید وارد کانتینر شوید و فایل /etc/resolv.conf را دستی تغییر دهید. این کار برای عیب‌یابی موقت ممکن است اطلاعاتی به شما بدهد، اما برای پیکربندی پایدار بهتر است DNS را از طریق Docker یا Compose مدیریت کنید.

کانتینرها ماهیت بازتولیدپذیر دارند و ممکن است با Recreate شدن، تنظیمات دستی داخل آن‌ها از بین برود. تنظیم موردنیاز سرویس باید در تعریف کانتینر یا تنظیمات daemon ثبت شود.

اگر مشکل DNS نبود چه چیزی را بررسی کنیم؟

اگر کانتینر حتی به IP عمومی هم دسترسی ندارد، ادامه تغییر DNS منطقی نیست. در این حالت موارد زیر باید بررسی شوند:

🔹 وضعیت شبکه‌های Docker و اتصال کانتینر به Network صحیح.

🔹 IP Forwarding روی میزبان.

🔹 قوانین nftables یا iptables.

🔹 قوانین UFW و زنجیره‌های ایجادشده توسط Docker.

🔹 NAT و Masquerading برای شبکه Bridge.

🔹 Route و Gateway کانتینر.

برای مشاهده شبکه‌های موجود:

docker network ls

و برای مشاهده تنظیمات شبکه یک کانتینر:

docker inspect CONTAINER_NAME

آزمون نهایی بعد از رفع مشکل

پس از اعمال تغییر، فقط به بالا آمدن کانتینر اکتفا نکنید. DNS را مستقیماً آزمایش کنید:

docker run --rm busybox nslookup example.com

اگر کانتینر اصلی ابزار مناسب دارد، همان تست را داخل سرویس واقعی نیز انجام دهید:

docker exec CONTAINER_NAME getent hosts example.com

سپس لاگ برنامه را بررسی کنید تا مطمئن شوید خطاهایی مانند Temporary failure in name resolution یا Could not resolve host تکرار نمی‌شوند.

جدول عیب‌یابی سریع DNS در Docker

نشانه، علت محتمل و اقدام پیشنهادی
نشانه علت محتمل بررسی
IP کار می‌کند، دامنه نه DNS resolv.conf و nslookup را بررسی کنید.
IP و دامنه هر دو قطع‌اند شبکه، NAT یا Firewall Bridge، Forwarding و Firewall را بررسی کنید.
127.0.0.11 دیده می‌شود ممکن است کاملاً طبیعی باشد روی شبکه سفارشی این آدرس resolver داخلی Docker است.
DNS سفارشی مشکل را حل می‌کند مسیر DNS پیش‌فرض DNS Compose یا daemon را با توجه به نیاز شبکه تنظیم کنید.
خود Host هم Resolve نمی‌کند DNS میزبان ابتدا systemd-resolved یا DNS سیستم‌عامل را بررسی کنید.

پرسش‌های متداول

آیا 127.0.0.11 داخل resolv.conf کانتینر اشتباه است؟

خیر. روی شبکه‌های سفارشی Docker این آدرس مربوط به DNS داخلی Docker است و مشاهده آن می‌تواند کاملاً طبیعی باشد.

چطور بفهمیم مشکل Docker از DNS است؟

دسترسی شبکه را مستقل از نام دامنه آزمایش کنید. اگر ارتباط IP برقرار است ولی Resolve نام دامنه شکست می‌خورد، DNS یکی از علت‌های اصلی قابل بررسی است. اگر IP نیز قابل دسترس نیست، شبکه و Firewall باید بررسی شوند.

آیا می‌توان DNS را در docker-compose.yml مشخص کرد؟

بله. Docker Compose گزینه dns دارد و می‌توانید یک یا چند DNS Server برای سرویس موردنظر تعریف کنید.

آیا باید DNS را در daemon.json تغییر دهیم؟

نه همیشه. ابتدا مشکل را تشخیص دهید. اگر فقط یک سرویس مشکل دارد، تنظیم DNS همان کانتینر یا Compose تغییر محدودتری است. تنظیم daemon.json زمانی منطقی‌تر است که نیاز سراسری و مشخصی وجود داشته باشد.

چرا تغییر DNS مشکل را حل نکرد؟

ممکن است مشکل اصلاً DNS نباشد. خرابی NAT، IP Forwarding، nftables، iptables، UFW، Route یا شبکه Bridge می‌تواند دسترسی اینترنت کانتینر را به‌طور کامل قطع کند.

آیا می‌توان 127.0.0.1 را DNS کانتینر قرار داد؟

معمولاً نه، مگر اینکه واقعاً DNS Server داخل همان namespace کانتینر روی آن آدرس اجرا شود. 127.0.0.1 داخل کانتینر به خود کانتینر اشاره می‌کند، نه به Loopback میزبان.

منابع رسمی

🔹 مستندات رسمی Docker درباره Networking و DNS

🔹 راهنمای رسمی عیب‌یابی Docker daemon و DNS

🔹 تنظیم DNS سرویس‌ها در Docker Compose

🔹 مرجع رسمی تنظیمات dockerd

جمع‌بندی: برای رفع DNS داخل Docker Container، ابتدا ارتباط IP را از Resolve دامنه جدا کنید. اگر فقط DNS خراب است، /etc/resolv.conf و resolver میزبان را بررسی کنید و سپس با –dns یک تست موقت انجام دهید. در صورت تأیید مشکل، DNS را در Docker Compose یا daemon.json به‌شکل پایدار تنظیم کنید. اگر IP نیز در دسترس نیست، به‌جای DNS سراغ NAT، Firewall، Forwarding و شبکه Docker بروید.

برای عیب‌یابی Docker به کمک فنی نیاز دارید؟

اگر بعد از بررسی DNS همچنان کانتینر به شبکه دسترسی ندارد، می‌توانید برای بررسی تنظیمات Docker، شبکه و سرویس سرور درخواست کانفیگ ثبت کنید.

تماس با پشتیبانی ایرانیکاسرور: 021-91302467

اشتراک‌گذاری مقاله
گفت‌وگو درباره آموزش

دیدگاه‌ها (۰)

هنوز دیدگاهی ثبت نشده است.

دیدگاه یا سؤال خود را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *