WIUNIX ACADEMY
عیبیابی CrashLoopBackOff و OOMKilled در Kubernetes؛ از شواهد تا رفع علت
علت توقف پیدرپی کانتینر را با بررسی وضعیت خروج، لاگ اجرای قبلی، پروبها و مصرف حافظه پیدا کنید و نتیجهٔ اصلاح را زیر بار واقعی بسنجید.
محیطت را انتخاب کنآموزش متناسب با محیط تو
کجا اجرا میکنی؟
سیستمعامل و نسخه را انتخاب کن تا مراحل، دستورها و راهحلها برای همان محیط نمایش داده شوند.
آموزش متناسب با مقادیر تو
تنظیمات این آموزش
مقادیر نمونه را برای محیط خودت تنظیم کن؛ متن و دستورهای مرتبط با هم تغییر میکنند. رمز، کلید خصوصی و توکن وارد نکن. مقادیر فقط در همین زبانه نگهداری میشوند و به سرور یا لینک اشتراکگذاری فرستاده نمیشوند. پیش از اجرا، DNS، گواهیها و سیاست شبکهٔ واقعی را بررسی کن.
آیپی، دامنه یا پورت مثالها با محیط تو فرق دارد؟ دکمهٔ زیر را باز کن، مقادیر را تغییر بده و «اعمال در آموزش» را بزن؛ سپس دستورهای بهروزشده را کپی کن.
تنظیم مقادیر برای محیط من7 مقدار قابلتغییر
از اینجا شروع کن
در پایان چه چیزی خواهی داشت؟
با شواهد قابل پیگیری تشخیص دهید توقف کانتینر از برنامه، کمبود حافظه، تنظیم پروب یا فشار روی نود ناشی میشود؛ سپس اصلاح یا بازگشت نسخه را با مسئول سرویس انجام دهید.
سیستمعاملها و نسخههای پوششدادهشده
فرمانها و تفاوتهای محیطهای منتخب با مستندات رسمی بررسی شدهاند؛ این بررسی به معنای اجرای عملی روی همهٔ سیستمها یا سرویس شما نیست. فرم فعلی نامهای ساده تا ۳۲کاراکتر را میپذیرد؛ این محدودیت فرم است، نه Kubernetes. اگر نام واقعی طولانیتر است، مقدار نمونه را کپی نکنید؛ فرمان را در ویرایشگر خودتان با نام کامل تنظیم کنید. نام منبع را تغییر ندهید.
قبل از شروع
- دسترسی مجاز به یک کلاستر موجود و Deployment مشخصی که مسئول آن اجازهٔ بررسی و تغییر را داده است.
- نسخهٔ سازگار kubectl و مجوز خواندن Pod، رویدادها و لاگ؛ دسترسی به نمودارهای تاریخی مصرف منابع در صورت وجود.
- شناخت مسیر انتشار سرویس و محدودیت بازگشت نسخه، بهویژه پس از تغییر ساختار داده.
قدم بعدی
ابزار میزبان انتخابشده را آماده کنید
ابزارهای لازم را روی کامپیوتر یا سروری آماده کنید که فرمانهای مدیریتی را از آن اجرا میکنید. پیش از تأیید، فهرست تغییر بستهها را بخوانید؛ داخل کانتینر برنامه ابزار نصب نکنید. کلاستر، سرویس و باینریهای اصلی باید از قبل با نسخهٔ مورد تأیید موجود باشند. پنلهای بعد را در Bash اجرا کنید. نصب بسته روی همین میزبان تغییر ایجاد میکند، اما سرور برنامهٔ تازهای راه نمیاندازد.
از kubectl لینوکسیِ موجود استفاده کنید که اختلاف آن با همهٔ نسخههای API Server حداکثر یک نسخهٔ فرعی باشد. پیش از ادامه نسخهٔ سرور را در کانتکست مجاز ببینید. برای این عیبیابی kubelet یا kubeadm نصب نکنید و مخزن بستهٔ کلاینت را بازنویسی نکنید.
میزبان انتخابشده؛ نصب بسته فقط با مجوز تغییر همین میزبان
sudo dnf install ca-certificates bash coreutils
if ! command -v curl >/dev/null 2>&1; then sudo dnf install curl; fi
cat /etc/os-release
command -v bash curl timeout
command -v kubectl
kubectl version --client --output=yamlنسخهٔ سیستم با انتخاب شما یکسان باشد، ابزارها پیدا شوند و نسخهٔ کلاینت و سرویس با شرایط بالا سازگار باشند. اگر باینری موجود نیست یا سازگار نیست، ادامه ندهید.
حفاظت میزبان و مسیرهای نصب موجود را حفظ کنید
SELinux را در حالت enforcing و قواعد firewalld را فعال نگه دارید. ابزار کلاینت به خروجی مجازِ API، TLS یا SFTP نیاز دارد و پورت ورودی تازهای لازم نیست. نتیجهٔ سرویس محدودشدهٔ systemd ممکن است با اجرای تعاملی فرق داشته باشد. خطای AVC، برچسب فایل و مجوز سرویس را با مسئول سیاست بررسی کنید؛ خاموشکردن SELinux یا دیوارهٔ آتش و مجوز گسترده راهحل نیست. خطای زنجیرهٔ اعتماد یا سیاست رمزنگاری به مقصد سازگار نیاز دارد، نه ضعیفکردن حفاظت سیستم. مسیر داده و پیکربندی سفارشی باید برچسب مناسب فعلی را حفظ کند؛ بازبرچسبگذاری بازگشتیِ کورکورانه انجام ندهید.
میزبان انتخابشده؛ فقط خواندن وضعیت حفاظت
if command -v getenforce >/dev/null 2>&1; then getenforce; fi
if command -v firewall-cmd >/dev/null 2>&1; then firewall-cmd --state; fiپیش از هر تغییر، معنای وضعیت را درست بخوانید
CrashLoopBackOff نام علت خرابی نیست. این وضعیت میگوید کانتینر چند بار متوقف شده و Kubernetes پیش از اجرای دوباره منتظر میماند. در مقابل، OOMKilled یکی از دلیلهای ثبتشده برای پایان اجراست. ممکن است وضعیت کلی Pod همچنان Running باشد، اما یکی از کانتینرهایش مرتب از کار بیفتد. کانتینر اصلی، کانتینر آغازین و کانتینر جانبی را از روی نام دقیق تشخیص دهید.
این راهنما بررسی یک Deployment موجود را دنبال میکند. برای جمعکردن شواهد، برنامه را عمداً خراب نکنید و با حذف Pod سرنخهای حادثه را از بین نبرید. نام کانتینر، زمان رخداد و نسخهٔ برنامه را در یادداشت داخلی ثبت کنید. لاگ ممکن است دادهٔ کاربر یا اطلاعات محرمانه داشته باشد؛ پیش از اشتراکگذاری آن را پالایش کنید.
قدم بعدی
کلاستر، فضای نام و مجوز بررسی را تأیید کنید
نام کانتکست در همهٔ فرمانها صریح آمده تا بررسی ناخواسته روی کلاستر دیگری انجام نشود. آدرس سرور و فضای نام را با محدودهٔ بررسی توافقشده تطبیق دهید؛ شباهت نام Pod کافی نیست. تنظیمات فرم فقط در همین زبانهٔ مرورگر میمانند و جای واردکردن رمز یا توکن نیستند.
خط فرمان؛ فقط در محیطی که مجوز بررسی آن را دارید
kubectl config get-contexts 'lab'
kubectl --context='lab' get namespace 'academy-lab'
kubectl --context='lab' auth can-i get pods -n 'academy-lab'
kubectl --context='lab' -n 'academy-lab' get pod 'api-example' -o wideکلاستر و Pod دقیقاً همان مقصد مجاز باشند و پاسخ بررسی مجوز yes باشد. اگر مقصد یا مجوز درست نیست، ادامه ندهید.
قدم بعدی
وضعیت آخرین توقف را پیش از اجرای بعدی ثبت کنید
به ستون STATUS اکتفا نکنید. وضعیت فعلی و آخرین وضعیت پایانیافتهٔ هر کانتینر را کنار هم بخوانید. کد خروج ۱۳۷ بهتنهایی کمبود حافظه را ثابت نمیکند؛ دریافت SIGKILL هم میتواند همین کد را ایجاد کند. دلیل ثبتشدهٔ توقف، سقف منابع، وضعیت نود و زمان حادثه باید یکدیگر را تأیید کنند. با اجرای دوباره ممکن است تنها لاگ قبلیِ در دسترس از بین برود.
خط فرمان؛ فقط در محیطی که مجوز بررسی آن را دارید
kubectl --context='lab' -n 'academy-lab' get pod 'api-example' -o jsonpath='{range .status.containerStatuses[*]}{.name}{"\nstate="}{.state}{"\nlastState="}{.lastState}{"\nrestarts="}{.restartCount}{"\n\n"}{end}'
kubectl --context='lab' -n 'academy-lab' describe pod 'api-example'
kubectl --context='lab' -n 'academy-lab' get pod 'api-example' -o jsonpath='{range .status.initContainerStatuses[*]}{.name}{"\nstate="}{.state}{"\nlastState="}{.lastState}{"\nrestarts="}{.restartCount}{"\n"}{end}'نام کانتینر، دلیل و کد خروج، زمان شروع و پایان و رویدادهای همزمان مشخص شده باشند.
قدم بعدی
لاگ اجرای فعلی و قبلی را با زمان توقف تطبیق دهید
ابتدا بخش محدودی از لاگ را همراه زمان هر پیام بخوانید. گزینهٔ previous فقط اجرای متوقفشدهٔ پیشین را برمیگرداند و آرشیو همهٔ اجراها نیست. اگر دیگر در دسترس نبود، به سامانهٔ لاگ مورد تأیید مراجعه کنید؛ نبود لاگ به معنای نبود خطا نیست. خطای نهایی را با زمان توقف و انتشار نسخهٔ تازه مقایسه کنید.
خط فرمان؛ فقط در محیطی که مجوز بررسی آن را دارید
kubectl --context='lab' -n 'academy-lab' logs 'api-example' -c 'app' --previous --timestamps --tail=200
kubectl --context='lab' -n 'academy-lab' logs 'api-example' -c 'app' --timestamps --tail=200مشخص شود برنامه هنگام شروع خطا میدهد، حین کار استثنا رخ میدهد یا بدون پیام خروج متوقف میشود.