۷ اشتباه رایج در Kubernetes (و چطور یاد گرفتم از آن‌ها اجتناب کنم) با رویکردی که از kubectl logs برای بررسی لاگ‌ها استفاده می‌کنم 😊


خلاصه‌ای از 7 اشتباه رایج Kubernetes با اشاره به kubectl logs


کلیدِ جست‌وجوی اصلی برای بررسی و دیباگ لاگ‌ها در Kubernetes، kubectl logs است. استفاده از این فرمان به‌خصوص در کنار سایر ابزارها، به شما کمک می‌کند تا مشکلات را سریع‌تر پیدا و حل کنید.

۷ اشتباه رایج در Kubernetes (و چطور یاد گرفتم از آن‌ها اجتناب کنم) 😊

Kubernetes هم بسیار قدرتمنده و هم گاهی حسابی دست‌وپاگیر می‌شه. وقتی تازه با container orchestration کارم رو شروع کردم، اشتباهات زیادی کردم که شد یک لیست کامل از pitfalls. توی این نوشته می‌خوام هفت مشکل بزرگ و پرتکرار رو که خودم دیدم یا دیگران بهش برخوردن باهاتون درمیون بذارم و راهکارهایی عملی برای اجتناب ازشون بگم — مخصوص همکارای DevOps/SRE که می‌خوان بدون دردسر بیشتری کلاسترها رو مدیریت کنن. 🚀

1. ننوشتن resource requests و limits

مشکل: در specificationهای Pod مقدار CPU و memory رو مشخص نکردن. چون Kubernetes این فیلدها رو اجباری نمی‌کنه، در محیط توسعه خیلی وقت‌ها همه چیز استارت می‌خوره و این omission دیده نمیشه تا وقتی که در مقیاس بزرگ‌تر به مشکل برمی‌خورید.

چرا مهمه: resource requests باعث می‌شن scheduler مقدار کافی CPU و RAM رو برای هر Pod رزرو کنه و resource limits جلوی مصرف بیش از حد یک Pod رو می‌گیره. بدون درخواست و محدودیت: یا Podها دچار Resource Starvation می‌شن (عملکرد افت می‌کنه یا Fail می‌دن) یا بعضی Podها منابع رو hoard می‌کنن و باعث OOMKilled شدن بقیه می‌شن.

چطور اجتناب کنید: از مقادیر کم و محافظه‌کارانه شروع کنید (مثلاً 100m CPU و 128Mi memory) و عملکرد اپ رو رصد کنید. از HorizontalPodAutoscaler برای اتو-اسکِیل بر اساس metrics استفاده کنید و مرتباً با kubectl top pods یا ابزار مانیتورینگ خودتون بررسی کنید که under- یا over-provisioning ندارید. 📈

تجربه خودم: اوایل اصلاً محدودیت حافظه رو در نظر نمی‌گرفتم — همه‌چیز روی کلاستر محلی خوب بود؛ بعد که روی محیط بزرگ‌تر اجرا کردم، Pods یکی‌یکی OOMKilled شدند. درس گرفتم که limits رو دست‌کم نگیرم.

2. ساده گرفتن liveness و readiness probes

مشکل: کانتینرها رو بدون تعریف واضحِ نحوه چک سلامت یا آماده‌به‌کار گذاشتن، دیپلوی کردن. Kubernetes تا وقتی پروسس داخل کانتینر بیرون نیومده، اون رو running می‌دونه؛ اما اپ ممکنه unresponsive یا هنوز initializing باشه.

روان‌شناسی فنی: liveness probes برای فهمیدن اینکه اپ زنده است یا نه استفاده می‌شن — در صورت fail، کانتینر ریستارت میشه. readiness probes تعیین می‌کنه آیا اپ آماده دریافت ترافیک هست یا نه و تا زمانی که رد نشه، کانتینر از endpoints سرویس خارج میشه. startup probes هم به افتراق بین زمان طولانی startup و خطای واقعی کمک می‌کنه.

چطور اجتناب کنید: یک HTTP livenessProbe ساده برای endpoint ای مثل /healthz بذارید تا کانتینرهای هنگ‌شده ریستارت بشن. readinessProbe بذارید تا ترافیک قبل از warm-up به اپ نرسه. probes‌ رو ساده نگه دارید — چک‌های خیلی پیچیده ممکنه false positive ایجاد کنن و ریستارت بی‌دلیل.

تجربه خودم: یک‌بار readiness probe فراموش شده بود و سرویس وبِ ما طولانی بالا می‌اومد؛ کاربران زود به سرویس وصل می‌شدن و timeoutهای عجیب می‌دیدن. یک readinessProbe سه‌خطی مشکل رو حل می‌کرد. 🙈

3. “فقط از kubectl logs استفاده می‌کنیم” (جمله‌ای که همیشه آخرین جمله‌ست)

مشکل: اتکا صرف به kubectl logs برای لاگ گرفتن. این فرمان برای دیباگ سریع خوبه، اما تنها لاگ‌های کانتینرهای در حال اجرا یا اخیراً terminated رو برمی‌گردونه و لاگ‌ها روی دیسک نُد نگهداری می‌شن؛ به محض حذف کانتینر، evict یا ریبوت نُد، لاگ‌ها ممکنه از بین برن.

چطور اجتناب کنید: لاگ‌ها رو مرکزی کنید با ابزارهای CNCF مثل Fluentd یا Fluent Bit تا خروجی همه Podها جمع‌آوری بشه. از OpenTelemetry برای دید یکپارچه از logs، metrics و در صورت نیاز traces استفاده کنید تا بتونید همبستگی‌ها بین رویدادهای زیرساختی و اپ رو ببینید. لاگ‌ها رو با Prometheus metrics جفت کنید و برای distributed tracing اگر لازم بود از Jaeger استفاده کنید. 🔍

تجربه خودم: اولین بار که لاگ یک Pod رو به‌خاطر یک ریستارت سریع از دست دادم، فهمیدم که فقط اتکا به kubectl logs خیلی شکننده‌ست. بعد از اون برای هر کلاستر یک pipeline لاگ گذاشتم.

4. رفتار یکسان با dev و prod

مشکل: استفاده از یک مانِیفست واحد و یک تنظیمات در dev، staging و production. هدف داشتن consistency منطقیه، ولی تفاوت‌های محیطی—مثل pattern ترافیک، منابع موجود، نیازهای scaling یا کنترل دسترسی—می‌تونه باعث بشه تنظیمات مناسب dev در prod باعث instability یا مشکلات امنیتی بشه.

چطور اجتناب کنید: از overlays یا kustomize استفاده کنید تا یک base مشترک داشته باشید و برای هر environment مقادیر مختلف (requests، replicas، config) رو اعمال کنید. configهای environment-specific رو در ConfigMaps یا Secrets جدا کنید؛ برای Secretها از ابزارهایی مثل Sealed Secrets استفاده کنید. برای prod از قبل scale و resource planning داشته باشید — dev معمولاً با منابع کم تر کنار میاد ولی prod ممکنه نیاز به چندین برابر داشته باشه.

تجربه خودم: یک بار replicaCount رو از 2 به 10 توی یک dev کوچک بالا بردم تا تست کنم — سریع منابع تموم شد و نصف روز رو صرف cleanup کردم. Lesson learned. ⚠️

5. رها کردن منابع قدیمی توی کلاستر

مشکل: منابعی مثل Deployments، Services، ConfigMaps یا PersistentVolumeClaims که دیگه استفاده نمی‌شن و همچنان توی کلاستر باقی می‌مونن. چون Kubernetes خودش به‌صورت خودکار این‌ها رو حذف نمی‌کنه مگر صریح تنظیم شده باشه، این آبجکت‌ها به مرور جمع می‌شن و منابع رو مصرف، هزینه‌ها رو بالا و مدیریت رو پیچیده می‌کنن.

چطور اجتناب کنید: همه منابع رو با label شامل owner یا purpose ایجاد کنید تا بتونید راحت سرچ و cleanup کنید. به‌صورت منظم audit کنید (مثلاً kubectl get all -n <namespace>) تا ببینید چه چیزهایی در حال اجراست. از Garbage Collection کَـKubernetes و مستندسازی وابستگی‌ها استفاده کنید تا dependent objects خودکار حذف بشن. ابزارهای policy automation مثل Kyverno هم می‌تونن بعد از یک مدت مشخص منابع stale رو پاک کنن یا lifecycle policy اعمال کنن.

تجربه خودم: بعد از یک hackathon فراموش کردم یک “test-svc” که به یک external load balancer وصل شده بود رو حذف کنم — سه هفته بعد فهمیدم که دارم اون لودبالانسر رو پول پرداخت می‌کنم. Facepalm. 💸

6. رفتن عمیق توی networking خیلی زود

مشکل: قبل از درک کامل primitives شبکه در Kubernetes، پیاده‌سازی service mesh، CNI سفارشی یا multi-cluster communication. وقتی از ابزارهای خارجی برای routing، observability یا mTLS استفاده می‌کنید بدون اینکه جریان ترافیک پایه، ClusterIP، DNS و ingress رو بلد باشید، مشکلات شبکه سخت‌تر و مبهم‌تر می‌شن و لایه‌های اضافه failure point بیشتری وارد می‌کنن.

چطور اجتناب کنید: از پایه شروع کنید — یک Deployment، یک Service و یک ingress controller ساده مثل Ingress-NGINX. بفهمید ترافیک داخل کلاستر چطور جابه‌جا می‌شه، service discovery چطوری کار می‌کنه و DNS چگونه کانفیگ میشه. وقتی واقعاً نیاز بود و پیچیدگی توجیه‌پذیر بود، به سمت service mesh یا قابلیت‌های پیشرفته CNI برید، چون mesh هزینه و overhead مدیریتی داره.

تجربه خودم: یک بار Istio رو روی یک اپ داخلی کوچک تست کردم و بعد از اون بیشتر زمان رو صرف دیباگ کردن Istio کردم تا خود اپ. در نهایت Istio رو برداشتم و همه‌چیز درست شد. 🎯

7. امنیت و RBAC رو دست‌کم گرفتن

مشکل: دیپلوی workloads با تنظیمات ناامن مثل اجرای کانتینرها به عنوان root، استفاده از tag: latest، غیرفعال کردن security contexts یا اختصاص نقش‌های خیلی گسترده مثل cluster-admin. Kubernetes به‌صورت پیش‌فرض strict نیست و انعطاف‌پذیری داره، بنابراین تا وقتی که خودتون policy نگذارید، کلاستر ممکنه در معرض container escape، privilege escalation یا اشتباهات انسانی قرار بگیره.

چطور اجتناب کنید: همیشهNon-root user رو در کانتینرها تنظیم کنید و securityContext رو تکمیل کنید (capabilities، readOnlyRootFilesystem، runAsNonRoot و غیره). از ثابت بودن image tags و scanned images استفاده کنید — یعنی تا حد امکان از digest (sha) استفاده کنید نه latest. برای مدیریت دسترسی RBAC اصل کمترین دسترسی (least privilege) رو رعایت کنید و به‌جای دادن cluster-admin به سرویس‌ها یا CI، رول‌های خاص و namespace-limited بسازید. Policy engineهایی مثل Kyverno یا OPA/Gatekeeper می‌تونن policy enforcement و کلی rules خودکار براتون فراهم کنن. برای Secretها از ابزارهایی استفاده کنید که encryption at rest و access auditing رو ممکن کنن.

تجربه خودم: دیدم پروژه‌هایی که به راحتی cluster-admin به سرویس‌ها می‌دادن، بعدها وقتی نیاز به جداسازی و audit شدن داشتند، هزینهٔ بازسازی سیستمیِ دسترسی‌ها خیلی بالا رفت. از همون اول رول‌های دقیق و محدود در نظر گرفتن، کلی دردسر رو کم می‌کنه. 🔐

خلاصه و پیشنهاد نهایی: Kubernetes قدرتمنده اما پیچیدگی‌هاش می‌تونن باعث دردسر بشن اگر پایه‌ها رو درست نچیده باشید. از resource management شروع کنید، health probes ساده و مؤثر بذارید، لاگ‌ها و متریک‌ها رو مرکزی کنید، فرق بین dev و prod رو رعایت کنید، منابع قدیمی رو پاک نگه دارید، ابتدا networking پایه رو بلد باشید و امنیت و RBAC رو از روز اول جدی بگیرید. این‌ها اصول ساده‌ای هستن ولی اجرای پیوسته‌شون تجربه روزمره‌ی شما رو خیلی راحت‌تر و پایدارتَر می‌کنه. موفق باشید! 🙌