وقتی پارتیشن Docker پر میشود، حذف تصادفی image یا volume ممکن است سرویس را متوقف یا داده را نابود کند. «Docker فضا گرفته» علت واحدی نیست: imageهای release قدیمی، build cache، log بدون rotation، writable layer یک container، volume دیتابیس یا حتی فایلی که حذف شده اما process هنوز باز نگه داشته، رفتار متفاوتی دارند.
پاسخ سریع: ابتدا با ابزار سیستمعامل مشخص کنید کدام filesystem پر است؛ سپس docker system df -v را برای تفکیک image، container، volume و build cache ببینید. mountها و log driver سرویس پرمصرف را شناسایی کنید. فقط پس از تعیین owner، نیاز rollback، وجود backup و اثر حذف، target دقیق را پاک یا retention را اصلاح کنید.
نشانههایی که کمبود Disk ساخته است
- خطای
no space left on deviceدر app یا Docker daemon - شکست pull، build یا ایجاد container جدید
- توقف write دیتابیس و queue
- کندی شدید بهعلت I/O یا filesystem نزدیک ظرفیت
- پر بودن inode با وجود فضای بایتی ظاهراً آزاد
اگر دیتابیس write را متوقف کرده، اول دامنه حادثه را محدود کنید و از restartهای پیاپی بپرهیزید. آزادکردن فضا بدون شناخت فایل میتواند WAL، transaction log یا داده فعال را حذف کند و خرابی بزرگتری بسازد.
مرحله اول: کدام filesystem پر شده؟
df -h ظرفیت بایتی mountها و df -i inode را نشان میدهد. Docker Root Dir ممکن است روی root یا mount جدا باشد؛ آن را از اطلاعات daemon بخوانید و مسیر را حدس نزنید. اگر volume از storage یا driver بیرونی استفاده میکند، مصرف آن لزوماً در همان filesystem دیده نمیشود. وضعیت read-only شدن filesystem و خطاهای kernel/storage را نیز بررسی کنید.
مرحله دوم: نمای خود Docker
docker system df -v
این فرمان خواندنی است و فضای image، container، local volume و build cache را گزارش میکند. ستون reclaimable به معنی «بیخطر برای کسبوکار» نیست؛ ممکن است image قدیمی برای rollback یا volume بدون container فعال برای بازیابی لازم باشد. اندازههای shared layer را نیز نباید ساده با هم جمع کرد. خروجی را با نام پروژه، container و زمان release تطبیق دهید.
Imageهای قدیمی و tagهای متعدد
CI/CD میتواند در هر release image تازه pull کند و نسخههای قبلی روی host بمانند. چند tag ممکن است layer مشترک داشته باشند، بنابراین شمارش tag با مصرف واقعی برابر نیست. policy نگهداری باید تعداد rollback لازم و سرعت pull از registry را در نظر بگیرد. image مورد استفاده container متوقفشده یا برنامه rollback را پیش از حذف مشخص کنید. راهنمای کاهش حجم Docker image جلوی رشد هر release را میگیرد.
Build Cache روی سرور
اگر روی production build انجام میشود، cache و intermediate stageها میتوانند رشد کنند. راه بهتر معمولاً ساخت در CI، انتشار artifact و deploy همان digest است. cache برای سرعت ارزش دارد و پاککردن کامل آن build بعدی را کند میکند. مصرف و زمان آخرین استفاده را بررسی و policy محدودکننده متناسب تعریف کنید؛ اجرای prune سراسری در cron بدون فیلتر و مانیتورینگ، درمان مطمئنی نیست.
Writable Layer کانتینر
برنامهای که upload، cache، dump یا log را داخل لایه کانتینر مینویسد، با رشد غیرمنتظره مواجه میشود. اندازه container و اختلاف آن با image سرنخ است. مسیرهای در حال رشد را داخل همان container بررسی کنید و تعیین کنید داده باید volume، object storage، tmpfs یا log pipeline باشد. recreate کردن ممکن است فضا را آزاد کند اما داده پنهان را هم از بین ببرد؛ ابتدا ماهیت آن را مشخص کنید.
Logهای Docker
driverهایی مثل json-file بدون تنظیم rotation میتوانند خروجی stdout/stderr را تا پرشدن Disk نگه دارند. log پرتکرار معمولاً علاوه بر retention، یک علت برنامهای مانند retry loop دارد. اندازه فایل را با ابزار و metadata Docker بررسی کنید و فایل فعال را با editor، truncate عجولانه یا logrotate خارجی دستکاری نکنید؛ Docker ممکن است مدیریت و offset خودش را داشته باشد. راهنمای Docker logs تنظیم پیشگیرانه را توضیح میدهد.
Volumeها: بزرگ، بدون owner یا واقعاً یتیم؟
Volume دیتابیس و upload طبیعی است که رشد کند. Volume بدون container فعال لزوماً یتیم نیست؛ ممکن است stack متوقف، پروژه تغییرنامیافته یا restore point باشد. mount و label و نام Compose و محتوای سطحبالا را بدون تغییر بررسی کنید. قبل از حذف، backup سازگار و Restore Test داشته باشید. راهنمای بکاپ Volume تفاوت archive فایل و dump دیتابیس را روشن میکند.
Overlay filesystem و فایل حذفشده
ممکن است فایل بزرگی حذف شده باشد ولی process هنوز file descriptor آن را باز نگه دارد؛ در این حالت du و df اختلاف دارند و فضا تا بستهشدن handle آزاد نمیشود. همچنین جزئیات overlay و storage driver را نباید دستی ویرایش کرد. با ابزارهای خواندنی سیستم process مالک را پیدا کنید و restart کنترلشده با درنظرگرفتن ترافیک و state انجام دهید.
Containerهای متوقف و خروجیهای موقت
jobهای batch، test و one-off میتوانند container متوقف، archive و cache باقی بگذارند. label پروژه و زمان ایجاد کمک میکند مالک مشخص شود. automation باید container موقت را با lifecycle درست اجرا کند و خروجی لازم را به storage مقصد منتقل کند. حذف گروهی بر اساس نام کوتاه یا wildcard میتواند پروژه دیگری را هدف بگیرد؛ شناسه و project را صریح کنترل کنید.
یک روند تشخیص کمخطر
- filesystem، درصد بایت و inode و نرخ رشد را ثبت کنید.
- Docker Root Dir و mountهای جدا را تعیین کنید.
docker system df -vرا ذخیره و دسته غالب را پیدا کنید.- برای هر مورد owner، سرویس، آخرین استفاده و نیاز rollback را مشخص کنید.
- قبل از Volume یا داده، backup و Restore را تأیید کنید.
- یک target محدود را تغییر دهید و فضای آزاد/سلامت را بسنجید.
- علت رشد و policy retention را اصلاح کنید.
در حادثه چه چیزی را اول آزاد کنیم؟
اولویت باید کمریسکترین داده قابلبازسازی و مشخص باشد، نه بزرگترین پوشه. artifact موقت تأییدشده یا cache مشخص معمولاً کمخطرتر از volume ناشناس است. برای سرویس تراکنشی، مقداری headroom ایجاد کنید تا backup یا shutdown سالم ممکن شود. اگر target روشن نیست، توقف تغییر و افزودن storage موقت کنترلشده از حذف حدسی امنتر است.
پیشگیری
برای ظرفیت، inode و نرخ رشد هشدار بگذارید؛ log rotation و retention image/build cache را تعریف کنید؛ build را از production خارج کنید؛ داده ماندگار را به volume دارای owner ببرید؛ backup را خارج host نگه دارید. alert فقط روی ۹۹٪ دیر است؛ زمان تخمینی تا پرشدن و روند روزانه کمک میکند پیش از حادثه اقدام شود.
بودجه فضای هر دسته را مشخص کنید
ظرفیت را فقط یک عدد کلی نبینید. برای داده اصلی، log، imageهای rollback، cache ساخت و فضای موقت backup سهم و نرخ رشد تعریف کنید. اگر هر release دو image و چند معماری pull میکند، retention را با تعداد releaseهای روزانه محاسبه کنید. برای دیتابیس نیز فضای عملیات maintenance و رشد transaction log لازم است؛ پرکردن Disk تا آستانه اسمی filesystem، حاشیه امن بازیابی را از بین میبرد. روند مصرف بعد از deploy یا campaign را با baseline معمول مقایسه کنید.
Registry با Host یک مسئله نیست
حذف image محلی، storage registry را آزاد نمیکند و حذف tag در registry هم لزوماً blob را فوراً garbage-collect نمیکند. policy این دو را جدا طراحی کنید. digest releaseهای فعال و rollback را در inventory نگه دارید تا cleanup نتواند artifact لازم را حذف کند. اگر pull از registry کند یا ناممکن است، تعداد نسخه محلی موردنیاز با شرایط بازیابی ارتباط مستقیم دارد.
اشتباههای رایج
- اجرای prune سراسری بدون مشاهده و backup
- حذف مستقیم فایلهای زیر Docker Root Dir
- فرض یتیم بودن هر volume بدون container فعال
- پاککردن log بدون اصلاح rotation و retry loop
- نادیدهگرفتن inode
- build دائمی روی production
- نگهداری backup روی همان filesystem پر
چه زمانی کمک تخصصی لازم است؟
اگر Disk نزدیک ۱۰۰٪ است، دیتابیس write نمیکند یا owner داده روشن نیست، آزمونوخطا میتواند recovery را سختتر کند. پشتیبانی ساعتی DevOps میتواند مصرف را بدون حذف کورکورانه تفکیک، فضای اضطراری ایجاد و علت رشد را اصلاح کند.
پرسشهای متداول
آیا docker system prune همیشه امن است؟
خیر؛ دامنه گزینهها و نیاز rollback/داده پروژه باید بررسی شود. از آن بهعنوان اولین اقدام استفاده نکنید.
چرا du و df متفاوتاند؟
فایل حذفشده اما باز، mount متفاوت، permission یا reserved blocks میتواند اختلاف بسازد.
آیا imageهای بدون tag قابل حذفاند؟
اول وابستگی container، build cache و نیاز rollback را بررسی کنید؛ ظاهر untagged بهتنهایی مجوز حذف نیست.
چه میزان فضای آزاد نگه داریم؟
به نرخ رشد، زمان واکنش و workload بستگی دارد؛ threshold ثابت را با پیشبینی زمان تا exhaustion ترکیب کنید.