نصائح عامل الميناء: قم بمسح جهازك من النفايات غير المرغوب فيها

نصائح عامل الميناء: قم بمسح جهازك من النفايات غير المرغوب فيها

يا هبر! أقدم انتباهكم إلى ترجمة المقال "نصائح عامل الميناء: تنظيف جهازك المحلي" автора لوك جوجيري.

سنتحدث اليوم عن كيفية استخدام Docker لمساحة القرص الخاصة بالجهاز المضيف، وسنكتشف أيضًا كيفية تحرير هذه المساحة من قصاصات الصور والحاويات غير المستخدمة.


نصائح عامل الميناء: قم بمسح جهازك من النفايات غير المرغوب فيها

إجمالي الاستهلاك

يعد Docker شيئًا رائعًا، وربما لا يشكك فيه سوى عدد قليل من الناس اليوم. منذ بضع سنوات فقط، قدم لنا هذا المنتج طريقة جديدة تمامًا لإنشاء أي بيئة وتقديمها وتشغيلها، مما يسمح لنا بتوفير موارد وحدة المعالجة المركزية وذاكرة الوصول العشوائي (RAM) بشكل كبير. بالإضافة إلى هذا (وهذا هو الشيء الأكثر أهمية بالنسبة للبعض) فقد سمح لنا Docker بتبسيط وتوحيد إدارة دورة الحياة لبيئات الإنتاج لدينا بشكل لا يصدق.

ومع ذلك، فإن كل هذه المسرات في الحياة الحديثة لها ثمن. عندما نقوم بتشغيل الحاويات، أو تنزيل أو إنشاء الصور الخاصة بنا، ونشر الأنظمة البيئية المعقدة، علينا أن ندفع الثمن. ونحن ندفع، من بين أمور أخرى، بمساحة القرص.

إذا لم تفكر أبدًا في مقدار المساحة التي يشغلها Docker فعليًا على جهازك، فقد تتفاجأ بشكل غير سار بمخرجات هذا الأمر:

$ docker system df

نصائح عامل الميناء: قم بمسح جهازك من النفايات غير المرغوب فيها

يوضح هذا استخدام قرص Docker في سياقات مختلفة:

  • الصور – الحجم الإجمالي للصور التي تم تنزيلها من مستودعات الصور والمبنية على نظامك؛
  • الحاويات – إجمالي مساحة القرص المستخدمة لتشغيل الحاويات (أي الحجم الإجمالي لطبقات القراءة والكتابة لجميع الحاويات)؛
  • الأحجام المحلية – حجم التخزين المحلي المثبت على الحاويات؛
  • إنشاء ذاكرة تخزين مؤقت - الملفات المؤقتة التي تم إنشاؤها بواسطة عملية إنشاء الصور (باستخدام أداة BuildKit، المتوفرة بدءًا من الإصدار 18.09 من Docker).

أراهن أنه بعد هذا النقل البسيط، فأنت حريص على تنظيف قرصك من القمامة وإعادة الجيجابايت الثمينة إلى الحياة (ملاحظة: خاصة إذا كنت تدفع إيجارًا مقابل هذه الجيجابايت كل شهر).

استخدام القرص بواسطة الحاويات

في كل مرة تقوم فيها بإنشاء حاوية على الجهاز المضيف، يتم إنشاء العديد من الملفات والأدلة في الدليل /var/lib/docker، ومن بينها ما يلي جدير بالملاحظة:

  • الدليل /var/lib/docker/containers/container_ID – عند استخدام برنامج تشغيل التسجيل القياسي، هذا هو المكان الذي يتم فيه حفظ سجلات الأحداث بتنسيق JSON. غالبًا ما تتسبب السجلات المفصلة جدًا، وكذلك السجلات التي لا يقرأها أحد أو يعالجها بطريقة أخرى، في امتلاء الأقراص.
  • يحتوي الدليل /var/lib/docker/overlay2 على طبقات القراءة والكتابة للحاوية (overlay2 هو برنامج التشغيل المفضل في معظم توزيعات Linux). إذا كانت الحاوية تقوم بتخزين البيانات في نظام الملفات الخاص بها، فسيتم وضعها في هذا الدليل.

لنتخيل نظامًا تم تثبيت Docker عليه، ولم يشارك مطلقًا في إطلاق الحاويات أو بناء الصور. سيبدو تقرير استخدام مساحة القرص الخاص به كما يلي:

$ docker system df
TYPE           TOTAL      ACTIVE     SIZE       RECLAIMABLE
Images         0          0          0B         0B
Containers     0          0          0B         0B
Local Volumes  0          0          0B         0B
Build Cache    0          0          0B         0B

لنبدأ بتشغيل بعض الحاويات، على سبيل المثال، NGINX:

$ docker container run --name www -d -p 8000:80 nginx:1.16

ماذا يحدث للقرص:

  • تشغل الصور 126 ميجابايت، وهذا هو نفس NGINX الذي أطلقناه في الحاوية؛
  • حاويات تشغل 2 بايت سخيفة.

$ docker system df
TYPE           TOTAL      ACTIVE     SIZE       RECLAIMABLE
Images         1          1          126M       0B (0%)
Containers     1          1          2B         0B (0%)
Local Volumes  0          0          0B         0B
Build Cache    0          0          0B         0B

إذا حكمنا من خلال الاستنتاج، ليس لدينا بعد أي مساحة يمكننا تحريرها. نظرًا لأن 2 بايت أمر تافه تمامًا، فلنتخيل أن NGINX الخاص بنا كتب بشكل غير متوقع ما يصل إلى 100 ميجابايت من البيانات وأنشأ ملف test.img بهذا الحجم تمامًا داخل نفسه.

$ docker exec -ti www 
  dd if=/dev/zero of=test.img bs=1024 count=0 seek=$[1024*100]

دعونا نفحص استخدام مساحة القرص على المضيف مرة أخرى. سنرى أن الحاوية (الحاويات) تشغل 100 ميجابايت هناك.

$ docker system df
TYPE           TOTAL      ACTIVE     SIZE       RECLAIMABLE
Images         1          1          126M       0B (0%)
Containers     1          1          104.9MB    0B (0%)
Local Volumes  0          0          0B         0B
Build Cache    0          0          0B         0B

أعتقد أن عقلك الفضولي يتساءل بالفعل عن مكان وجود ملف test.img الخاص بنا. دعونا نبحث عنه:

$ find /var/lib/docker -type f -name test.img
/var/lib/docker/overlay2/83f177...630078/merged/test.img
/var/lib/docker/overlay2/83f177...630078/diff/test.img

دون الخوض في التفاصيل، يمكننا أن نلاحظ أن ملف test.img يقع في مكان مناسب على مستوى القراءة والكتابة، ويتم التحكم فيه بواسطة برنامج التشغيل overlay2. إذا أوقفنا الحاوية الخاصة بنا، فسيخبرنا المضيف أنه يمكن، من حيث المبدأ، تحرير هذه المساحة:

# Stopping the www container
$ docker stop www

# Visualizing the impact on the disk usage
$ docker system df
TYPE           TOTAL      ACTIVE     SIZE       RECLAIMABLE
Images         1          1          126M       0B (0%)
Containers     1          0          104.9MB    104.9MB (100%)
Local Volumes  0          0          0B         0B
Build Cache    0          0          0B         0B

كيف يمكننا عمل ذلك؟ عن طريق حذف الحاوية، مما يستلزم مسح المساحة المقابلة على مستوى القراءة والكتابة.

باستخدام الأمر التالي، يمكنك إزالة جميع الحاويات المثبتة بضربة واحدة ومسح القرص الخاص بك من جميع ملفات القراءة والكتابة التي أنشأتها:

$ docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
5e7f8e5097ace9ef5518ebf0c6fc2062ff024efb495f11ccc89df21ec9b4dcc2

Total reclaimed space: 104.9MB

لذلك، قمنا بتحرير 104,9 ميغا بايت عن طريق حذف الحاوية. ولكن نظرًا لأننا لم نعد نستخدم الصورة التي تم تنزيلها مسبقًا، فإنها تصبح أيضًا مرشحة لحذف مواردنا وتحريرها:

$ docker system df
TYPE           TOTAL      ACTIVE     SIZE       RECLAIMABLE
Images         1          0          126M       126M (100%)
Containers     0          0          0B         0B
Local Volumes  0          0          0B         0B
Build Cache    0          0          0B         0B

ملحوظة: طالما أن الصورة قيد الاستخدام بواسطة حاوية واحدة على الأقل، فلن تتمكن من استخدام هذه الخدعة.

الأمر الفرعي Prune الذي استخدمناه أعلاه له تأثير فقط على الحاويات المتوقفة. إذا أردنا حذف ليس فقط الحاويات المتوقفة، بل أيضًا الحاويات قيد التشغيل، فيجب علينا استخدام أحد هذه الأوامر:

# Historical command
$ docker rm -f $(docker ps –aq)

# More recent command
$ docker container rm -f $(docker container ls -aq)

ملاحظات جانبية: إذا كنت تستخدم المعلمة -rm عند بدء تشغيل حاوية، فعندما تتوقف، سيتم تحرير كل مساحة القرص التي كانت تشغلها.

باستخدام صور القرص

قبل بضعة أعوام، كان حجم الصورة الذي يصل إلى عدة مئات من الميجابايت أمراً طبيعياً تماماً: كانت صورة Ubuntu تزن 600 ميجابايت، وكانت صورة Microsoft .Net تزن عدة جيجابايت. في تلك الأيام المزدحمة، قد يؤدي تنزيل صورة واحدة فقط إلى التأثير بشكل كبير على مساحة القرص الحرة لديك، حتى لو كنت تشارك المستويات بين الصور. اليوم - ولله الحمد - الصور تزن أقل بكثير، ولكن مع ذلك، يمكنك ملء الموارد المتاحة بسرعة إذا لم تتخذ بعض الاحتياطات.

هناك عدة أنواع من الصور التي لا تكون مرئية مباشرة للمستخدم النهائي:

  • الصور الوسيطة، التي يتم على أساسها جمع الصور الأخرى - لا يمكن حذفها إذا كنت تستخدم حاويات تعتمد على هذه الصور "الأخرى"؛
  • الصور المتدلية هي صور وسيطة لا يتم الرجوع إليها بواسطة أي من الحاويات قيد التشغيل - ويمكن حذفها.
  • باستخدام الأمر التالي، يمكنك التحقق من وجود صور متدلية على نظامك:

$ docker image ls -f dangling=true
REPOSITORY  TAG      IMAGE ID         CREATED             SIZE
none      none   21e658fe5351     12 minutes ago      71.3MB

يمكنك إزالتها بالطريقة التالية:

$ docker image rm $(docker image ls -f dangling=true -q)

يمكننا أيضًا استخدام الأمر الفرعي Prune:

$ docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Deleted Images:
deleted: sha256:143407a3cb7efa6e95761b8cd6cea25e3f41455be6d5e7cda
deleted: sha256:738010bda9dd34896bac9bbc77b2d60addd7738ad1a95e5cc
deleted: sha256:fa4f0194a1eb829523ecf3bad04b4a7bdce089c8361e2c347
deleted: sha256:c5041938bcb46f78bf2f2a7f0a0df0eea74c4555097cc9197
deleted: sha256:5945bb6e12888cf320828e0fd00728947104da82e3eb4452f

Total reclaimed space: 12.9kB

إذا أردنا فجأة حذف جميع الصور تمامًا (وليس فقط الصور المتدلية) باستخدام أمر واحد، فيمكننا القيام بذلك:

$ docker image rm $(docker image ls -q)

استخدام القرص حسب وحدات التخزين

تُستخدم وحدات التخزين لتخزين البيانات خارج نظام ملفات الحاوية. على سبيل المثال، إذا أردنا حفظ نتائج أحد التطبيقات لاستخدامها بطريقة أخرى. ومن الأمثلة الشائعة قواعد البيانات.

لنقم بتشغيل حاوية MongoDB، وتركيب وحدة تخزين خارجية للحاوية، واستعادة نسخة احتياطية لقاعدة البيانات منها (متوفرة في ملف bck.json):

# Running a mongo container
$ docker run --name db -v $PWD:/tmp -p 27017:27017 -d mongo:4.0

# Importing an existing backup (from a huge bck.json file)
$ docker exec -ti db mongoimport 
  --db 'test' 
  --collection 'demo' 
  --file /tmp/bck.json 
  --jsonArray

سيتم وضع البيانات على الجهاز المضيف في الدليل /var/lib/docker/volumes. ولكن لماذا لا يكون على مستوى القراءة والكتابة للحاوية؟ لأنه في ملف Dockerfile لصورة MongoDB، يتم تعريف الدليل /data/db (حيث يقوم MongoDB بتخزين بياناته افتراضيًا) كوحدة تخزين.

نصائح عامل الميناء: قم بمسح جهازك من النفايات غير المرغوب فيها

ملاحظة جانبية: العديد من الصور التي يجب أن تنتج بيانات تستخدم وحدات تخزين لتخزين تلك البيانات.

عندما نلعب بما فيه الكفاية مع MongoDB ونوقف (أو حتى نحذف) الحاوية، لن يتم حذف المجلد. وسيستمر في شغل مساحة القرص الثمينة لدينا حتى نحذفها بشكل صريح باستخدام أمر مثل هذا:

$ docker volume rm $(docker volume ls -q)

حسنًا، أو يمكننا استخدام الأمر الفرعي Prune المألوف لنا بالفعل:

$ docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
d50b6402eb75d09ec17a5f57df4ed7b520c448429f70725fc5707334e5ded4d5
8f7a16e1cf117cdfddb6a38d1f4f02b18d21a485b49037e2670753fa34d115fc
599c3dd48d529b2e105eec38537cd16dac1ae6f899a123e2a62ffac6168b2f5f
...
732e610e435c24f6acae827cd340a60ce4132387cfc512452994bc0728dd66df
9a3f39cc8bd0f9ce54dea3421193f752bda4b8846841b6d36f8ee24358a85bae
045a9b534259ec6c0318cb162b7b4fca75b553d4e86fc93faafd0e7c77c79799
c6283fe9f8d2ca105d30ecaad31868410e809aba0909b3e60d68a26e92a094da

Total reclaimed space: 25.82GB
luc@saturn:~$

استخدام القرص لذاكرة التخزين المؤقت لبناء الصورة

في Docker 18.09، خضعت عملية إنشاء الصور لبعض التغييرات بفضل أداة BuildKit. يعمل هذا الشيء على زيادة سرعة العملية وتحسين تخزين البيانات وإدارة الأمان. لن نتناول هنا كافة تفاصيل هذه الأداة الرائعة، بل سنركز فقط على كيفية معالجتها لقضايا استخدام مساحة القرص.

لنفترض أن لدينا تطبيق Node.Js بسيط تمامًا:

  • يبدأ ملف Index.js خادم HTTP بسيطًا يستجيب بسطر لكل طلب يتم تلقيه:
  • يحدد ملف package.json التبعيات، والتي يتم استخدام Expressjs فقط منها لتشغيل خادم HTTP:

$ cat index.js
var express = require('express');
var util    = require('util');
var app = express();
app.get('/', function(req, res) {
  res.setHeader('Content-Type', 'text/plain');
  res.end(util.format("%s - %s", new Date(), 'Got Request'));
});
app.listen(process.env.PORT || 80);

$ cat package.json
    {
      "name": "testnode",
      "version": "0.0.1",
      "main": "index.js",
      "scripts": {
        "start": "node index.js"
      },
      "dependencies": {
        "express": "^4.14.0"
      }
    }

يبدو ملف Dockerfile لإنشاء الصورة كما يلي:

FROM node:13-alpine
COPY package.json /app/package.json
RUN cd /app && npm install
COPY . /app/
WORKDIR /app
EXPOSE 80
CMD ["npm", "start"]

لنقم ببناء الصورة بالطريقة المعتادة، دون استخدام BuildKit:

$ docker build -t app:1.0 .

إذا تحققنا من استخدام مساحة القرص، يمكننا أن نرى أن الصورة الأساسية فقط (العقدة:13-alpine) والصورة الوجهة (التطبيق:1.0) هي التي تشغل المساحة:

TYPE           TOTAL      ACTIVE     SIZE       RECLAIMABLE
Images         2          0          109.3MB    109.3MB (100%)
Containers     0          0          0B         0B
Local Volumes  0          0          0B         0B
Build Cache    0          0          0B         0B

لنقم ببناء الإصدار الثاني من تطبيقنا باستخدام BuildKit. للقيام بذلك، نحتاج فقط إلى تعيين المتغير DOCKER_BUILDKIT على 1:

$ DOCKER_BUILDKIT=1 docker build -t app:2.0 .

إذا تحققنا الآن من استخدام القرص، فسنرى أن ذاكرة التخزين المؤقت للإنشاء (buid-cache) موجودة الآن هناك:

$ docker system df
TYPE           TOTAL      ACTIVE     SIZE       RECLAIMABLE
Images         2          0          109.3MB    109.3MB (100%)
Containers     0          0          0B         0B
Local Volumes  0          0          0B         0B
Build Cache    11         0          8.949kB    8.949kB

لمسحها، استخدم الأمر التالي:

$ docker builder prune
WARNING! This will remove all dangling build cache.
Are you sure you want to continue? [y/N] y
Deleted build cache objects:
rffq7b06h9t09xe584rn4f91e
ztexgsz949ci8mx8p5tzgdzhe
3z9jeoqbbmj3eftltawvkiayi

Total reclaimed space: 8.949kB

امسح الكل!

لذلك، نظرنا في تنظيف مساحة القرص التي تشغلها الحاويات والصور والمجلدات. يساعدنا الأمر الفرعي Prune في هذا. ولكن يمكن استخدامه أيضًا على مستوى نظام الإرساء، وسينظف كل ما في وسعه:

$ docker system prune
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all dangling images
  - all dangling build cache

Are you sure you want to continue? [y/N]

إذا كنت تقوم، لسبب ما، بتوفير مساحة على القرص على جهاز يقوم بتشغيل Docker، فيجب أن يصبح تشغيل هذا الأمر بشكل دوري عادة.

المصدر: www.habr.com

إضافة تعليق