ویرگول
ورودثبت نام
mohammad javad farahnak
mohammad javad farahnakبرنامه نویس پایتون :) با من میتونید از طریق fhot707@gmail.com در ارتباط باشید.
mohammad javad farahnak
mohammad javad farahnak
خواندن ۴ دقیقه·۴ ماه پیش

آموزش رفع مشکل "Host not found" در OpenResty/NGINX در محیط کوبرنیتز

آموزش رفع مشکل "Host not found" در OpenResty/NGINX در محیط کوبرنیتز

مشکل: خطای "Host not found" در اتصال به سرویس‌ها در NGINX

وقتی از OpenResty یا NGINX در یک محیط کوبرنیتز استفاده می‌کنید و سعی دارید به یک سرویس داخلی (مثل Redis یا دیتابیس) متصل شوید، ممکن است با خطای زیر مواجه شوید:

Failed to connect to Redis: <service-name> could not be resolved (3: Host not found)

این خطا به این معنی است که NGINX نمی‌تواند نام دامنه سرویس کوبرنیتز (مثل service-name.namespace.svc.cluster.local) را به آدرس IP تبدیل کند. دلیل اصلی این مشکل، عدم تنظیم رزالور DNS در تنظیمات NGINX است. در کوبرنیتز، نام‌های سرویس توسط سرویس DNS داخلی (معمولاً kube-dns یا coredns) به IP تبدیل می‌شوند، اما NGINX به‌طور پیش‌فرض از این تنظیمات استفاده نمی‌کند و نیاز به پیکربندی دستی دارد.

این مشکل به‌خصوص در اسکریپت‌های Lua رایج است. بدون تنظیم رزالور DNS، NGINX نمی‌تواند نام سرویس را resolve کند و اتصال با شکست مواجه می‌شود.

چرا این مشکل پیش می‌آید؟

در کوبرنیتز، سرویس‌ها از طریق نام‌های DNS (مثل service-name.namespace.svc.cluster.local) قابل دسترسی هستند. این نام‌ها توسط سرویس DNS داخلی کوبرنیتز به IP پودها یا ClusterIP سرویس‌ها ترجمه می‌شوند. اما NGINX/OpenResty به‌طور پیش‌فرض از تنظیمات DNS سیستم عامل (مثل /etc/resolv.conf) استفاده نمی‌کند و باید رزالور DNS را در تنظیمات خود مشخص کنید. بدون این تنظیم، تلاش برای اتصال به سرویس‌های کوبرنیتز با خطای "Host not found" مواجه می‌شود.

این مشکل ممکن است حتی زمانی رخ دهد که ابزارهایی مثل ping یا nslookup از داخل پود به‌درستی کار می‌کنند، چون این ابزارها از تنظیمات DNS سیستم استفاده می‌کنند، اما NGINX خیر.

راه‌حل: تنظیم رزالور DNS در NGINX

برای رفع این مشکل، باید آدرس رزالور DNS کوبرنیتز را پیدا کرده و آن را در تنظیمات NGINX اضافه کنید. مراحل زیر را دنبال کنید:

۱. پیدا کردن آدرس رزالور DNS

آدرس رزالور DNS در کوبرنیتز معمولاً ClusterIP سرویس kube-dns در namespace kube-system است. برای پیدا کردن این آدرس، دستور زیر را اجرا کنید:

kubectl get svc -n kube-system kube-dns

خروجی نمونه:

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 30d

در این مثال، 10.96.0.10 آدرس رزالور DNS است. این آدرس را یادداشت کنید.

نکته: اگر سرویس kube-dns در cluster شما نام دیگری دارد (مثل coredns)، از همان نام استفاده کنید.

۲. بررسی /etc/resolv.conf (اختیاری)

برای اطمینان از اینکه پود شما به رزالور DNS درست دسترسی دارد، فایل /etc/resolv.conf را بررسی کنید:

kubectl exec -it <your-pod-name> -n <your-namespace> -- cat /etc/resolv.conf

خروجی نمونه:

nameserver 10.96.0.10 search <namespace>.svc.cluster.local svc.cluster.local cluster.local options ndots:5

خط nameserver نشان‌دهنده آدرس رزالور DNS است که باید با ClusterIP سرویس kube-dns مطابقت داشته باشد.

۳. اضافه کردن رزالور به تنظیمات NGINX

فایل تنظیمات NGINX (مثل /etc/nginx/nginx.conf یا فایل مربوط به ConfigMap) را ویرایش کنید و رزالور را در بلوک http یا بلوک مرتبط اضافه کنید:

http { resolver 10.96.0.10 valid=30s; resolver_timeout 5s; server { listen 80; location /api/ { lua_code_cache on; content_by_lua_file /path/to/your-script.lua; } } }
  • resolver 10.96.0.10: آدرس IP سرویس kube-dns که در مرحله اول پیدا کردید.

  • valid=30s: نتایج DNS برای ۳۰ ثانیه کش می‌شوند تا تعداد درخواست‌های DNS کاهش یابد.

  • resolver_timeout 5s: حداکثر زمان انتظار برای پاسخ DNS را به ۵ ثانیه تنظیم می‌کند.

۴. اعمال تغییرات

بعد از ویرایش فایل تنظیمات، NGINX را ری‌لود کنید:

kubectl exec -it <your-pod-name> -n <your-namespace> -- nginx -s reload

اگر تنظیمات NGINX از طریق ConfigMap مدیریت می‌شود، ConfigMap را ویرایش کنید:

kubectl edit configmap <nginx-configmap-name> -n <your-namespace>

سپس پود را ری‌استارت کنید تا تغییرات اعمال شود:

kubectl delete pod <your-pod-name> -n <your-namespace>

۵. بررسی و تست

بعد از اعمال تغییرات، درخواست خود را دوباره تست کنید (مثلاً با curl یا ارسال درخواست به API). لاگ‌های NGINX را بررسی کنید تا مطمئن شوید خطای "Host not found" برطرف شده است:

kubectl logs <your-pod-name> -n <your-namespace>

اگر اسکریپت Lua شما پیام‌هایی مثل "service connected successfully" را لاگ می‌کند، یعنی اتصال برقرار شده است.

راه‌حل موقت: استفاده از آدرس IP به‌جای نام سرویس

اگر به هر دلیلی نمی‌توانید تنظیمات NGINX را تغییر دهید، می‌توانید به‌طور موقت آدرس IP سرویس را مستقیماً در اسکریپت Lua یا متغیرهای محیطی استفاده کنید.

هشدار: هاردکد کردن IP راه‌حل دائمی نیست، چون IP سرویس‌ها در کوبرنیتز ممکن است تغییر کند. بهتر است از رزالور DNS استفاده کنید.

نکات تکمیلی

  • بررسی NetworkPolicy: اگر مشکل همچنان پابرجاست، بررسی کنید که آیا NetworkPolicy در namespace شما ترافیک به سرویس مقصد را محدود کرده است:

    kubectl get networkpolicy -n <your-namespace>
  • دیباگ DNS در Lua: اگر نیاز به دیباگ بیشتر دارید، از ماژول resty.dns.resolver در اسکریپت Lua استفاده کنید تا مطمئن شوید نام سرویس به IP درست resolve می‌شود:

local resolver = require "resty.dns.resolver" local r, err = resolver:new{ nameservers = {{"10.96.0.10", 53}}, -- آدرس kube-dns retrans = 5, timeout = 2000, } local answers, err = r:query("<service-name>") if not answers then ngx.log(ngx.ERR, "DNS resolution failed: ", err) else for _, ans in ipairs(answers) do ngx.log(ngx.DEBUG, "Resolved IP: ", ans.address) end end

نتیجه‌گیری

با اضافه کردن رزالور DNS (مثل 10.96.0.10) به تنظیمات NGINX، می‌توانید مشکل "Host not found" را در OpenResty/NGINX برطرف کنید. این روش به NGINX اجازه می‌دهد تا نام‌های سرویس کوبرنیتز را به آدرس‌های IP درست ترجمه کند و اتصال به سرویس‌ها برقرار شود. همیشه از رزولوشن DNS به‌جای هاردکد کردن IP استفاده کنید تا سیستم شما در برابر تغییرات کوبرنیتز مقاوم باشد.

kubernetesnginx
۱
۰
mohammad javad farahnak
mohammad javad farahnak
برنامه نویس پایتون :) با من میتونید از طریق fhot707@gmail.com در ارتباط باشید.
شاید از این پست‌ها خوشتان بیاید