محدودیت تعداد فایلهای باز در کانتینرها
پارامتر حداکثر تعداد فایل، یکی از پارامترهای مهم یک پردازه (Process) است. کرنل لینوکس رسیدن تعداد فایل به این مقدار حداکثر که میتواند در سطوح مختلفی مانند Process و User تنظیم شود، پردازه را با خطای too many open files متوقف (kill) میکند. در ادامه، تفاوت این پارامتر در نسخههای مختلف Kubernetes (از 1.23 با Docker به 1.24 و 1.25/6 با Containerd)، همچنین مراحل بررسی و رفع مشکلات احتمالی ناشی از این تغییرات توضیح داده شده است. برای دیدن این مقادیر در یک محیط اجرایی (مثلا داخل یک کانتینر در یک پاد) میتوانید از دستور ulimit استفاده نمایید.
بنا به مدل مسئولیت مشترک، بهینهسازی پارامترهای ماشینهای Worker، در کوبرنتیز ابری، بر عهدهی کاربران استفاده کننده از سرویسهای ابری است چرا که این مهندسان با شناخت دقیقی که از بار کاری (Application Workload) دارند میتوانند این پارامترها را مطابق نیاز بهینهسازی نمایند.
پارامترهای هسته (Kernel Parameters) که با sysctl میتوان آنها را تنظیم کرد:
- fs.nr_open: این پارامتر، حداکثر تعداد فایلهایی را که یک پردازه میتواند به طور همزمان باز کند، مشخص میکند.
- fs.file-max: این مقدار، حداکثر تعداد فایلهایی را که در سطح سیستم (System-Wide) میتوان باز کرد، تعیین میکند. مقدار پیشفرض این پارامتر بسیار بزرگ است.
- fs.inotify.max_queued_events: این پارامتر تعداد حداکثر رخدادهایی را که میتوان به طور همزمان در صف رخدادهای inotify نگهداری کرد، مشخص میکند. مقدار پیشفرض مورد انتظار برابر با 16384 است. اگر مقدار متفاوت باشد، ممکن است در پردازش رخدادها اختلال ایجاد شود.
- fs.inotify.max_user_instances: این پارامتر تعداد حداکثر instanceهای inotify قابل استفاده توسط هر کاربر را تعیین میکند. مقدار پیشفرض مورد انتظار برابر با 1024 است. افزایش یا کاهش این مقدار میتواند بر توانایی کاربر برای مانیتور کردن منابع تأثیر بگذارد.
- fs.inotify.max_user_watches: این پارامتر تعداد حداکثر فایلهایی که هر کاربر میتواند به طور همزمان مانیتور کند، را مشخص میکند. مقدار پیشفرض مورد انتظار برابر با 30217 است.
در سطح کاربران (user) لینوکس نیز میتوان این پارامترها را ست کرد، برای مثال میتوانید این فایلها را ببینید:
کوبرنیتز ستون از Containerd برای محیط اجرایی (CRI) استفاده میکند. کانتینردی برای پادها تنظیمات پیشفرضی دارد که با دستور زیر میتوانید آن را ببینید؛ به طور خاص در قسمت rlimit تنظیمات حداکثر تعداد فایل شده است.
در کوبرنتیز ستون از ورژن 1.25 به بعد نیز حداکثر تعداد فایل باز برابر 1048576 تنظیم شده است تا مطابق با مقدار پیشفرض قبلی در Docker باشد که در فایل /etc/containerd/cri-base.json میتوانید تنظیم مورد نظر را ببینید. این عدد برای بار کاری بالا به شکل عمومی مناسبتر است.
این محدودیت در سرویس Containerd نیز که به شکل یک سرویس systemd اجرا میشود، قابل تنظیم است که در نسخهی فعلی آن، نسبت به Pod Spec اولویت بالاتری دارد.
- عدد اول و دوم به ترتیب مقدار Soft limit و Hard limit را نشان میدهد.
- یک راه سریع تغییر محدودیت ulimit در پادها، تغییر تنظیم گفته شده در containerd و سپس restart سرویس containerd و ریستارت کردن pod مورد نظر است.
همانطور که در توضیح داده شد، این پارامتر در لایههای مختلفی قابل تنظیم است. ستون به عنوان فراهمآورندهی سرویس ابری برای ارائهی مشاوره برای تنظیم این پارامترها مطابق نیاز workload در خدمت کاربران است اما باید توجه کرد که تنظیم این پارامترها بر عهدهی کاربران است چرا که از طرفی نیاز هر نوع اپلیکیشن متفاوت است؛ مثلا اپلیکیشنهای Big-Data نیازهای متفاوتی از Web Application ها دارند و از طرف دیگر، در لایههای متفاوتی میتوان این پارامترها را تنظیم کرد که همهی این لایهها در اختیار ارائهدهندهی سرویس ابری نیست. مثلا در Pod میتوان با تنظیم spec.containers[].securityContext.runAsUser آن را با یک User خاص با محدودیتهای متفاوت اجرا نمود.
ستون به عنوان یک ارائهدهندهی سرویس ابری در استاندارد جهانی، Component های مختلف را مطابق Best-Practice های عمومی مورد توصیهی نگهدارندگان آن Component ارائه میدهد. تغییر این پارامترها Side Effect هایی دارد که نیازمند توجه است. مثلا ممکن است کاربر بخواهد برای یک سرویس Big-Data که به تعداد زیادی فایل باز نیاز دارد، این پارامتر را از مقدار پیشفرض بیشتر کند با این هزینه که حافظه (Memory) بیشتری مصرف میشود.