Docker: ضبط الأداء واستكشاف الأخطاء وإصلاحها
آخر تحديث: 2026-08-26
هل تواجه مشكلات مع الحاويات في بيئة الإنتاج — استخدام CPU مرتفع؟ حمل ذاكرة زائد؟ I/O بطيء؟ تحتاج إلى نهج منهجي لاستكشاف الأخطاء.
1. ما ستتعلمه
- طرق تحديد اختناقات الأداء
- سيناريوهات الفشل الشائعة والأسباب الجذرية
- أدوات تصحيح الحاويات
- استكشاف أخطاء زمن انتقال الشبكة
- إدارة مساحة القرص
2. قصة عن تنبيه في الصباح الباكر
(1) نقطة الألم: زمن استجابة API قفز من 50 مللي ثانية إلى 5 ثوانٍ
ارتفع زمن استجابة API في بيئة الإنتاج من 50 مللي ثانية إلى 5 ثوانٍ، مما أدى إلى سيل من شكاوى المستخدمين. استخدمت أليس docker stats لاكتشاف أنه على الرغم من أن استخدام CPU لم يكن مرتفعًا، إلا أن أوقات انتظار I/O كانت مرتفعة للغاية، وبدت الحاويات وكأنها "عالقة".
(2) نهج منهجي لاستكشاف الأخطاء
استخدمت أليس iostat لتحديد أن محرك السجلات كان يتسبب في وصول I/O القرص إلى الحد الأقصى؛ بعد تبديل محرك السجلات، تم حل المشكلة.
BASH
# الخطوة 1: التحقق من استخدام الموارد
docker stats --no-stream
# الخطوة 2: التحقق من I/O المضيف
iostat -x 1 5
# الخطوة 3: تحديد الاختناق
docker system df -v
(3) الفوائد: 5 ثوانٍ ← 50 مللي ثانية، 10 دقائق وقت استرداد
استغرق الأمر 10 دقائق فقط من التنبيه إلى الحل — استكشاف الأخطاء المنهجي أكثر كفاءة بـ 100 مرة من مجرد "محاولة إعادة التشغيل".
3. شجرة قرار استكشاف أخطاء الأداء
(1) الاختناقات الأربعة الرئيسية وأدواتها المقابلة
graph TB
START["مشكلة أداء"] --> CPU{"CPU مرتفع؟"}
CPU -->|نعم| C1["docker stats<br/>top / htop"]
CPU -->|لا| MEM{"استخدام ذاكرة مرتفع؟"}
MEM -->|نعم| M1["docker stats<br/>/proc/meminfo"]
MEM -->|لا| IO{"انتظار I/O مرتفع؟"}
IO -->|نعم| I1["iostat -x<br/>docker system df"]
IO -->|لا| NET{"شبكة بطيئة؟"}
NET -->|نعم| N1["iperf / ping<br/>tcpdump"]
(2) أدوات استكشاف الأخطاء الشائعة
| الأداة | الوظيفة | حالة الاستخدام |
|---|---|---|
docker stats |
استخدام موارد الحاوية | نظرة عامة على CPU/ذاكرة/I/O |
docker system df |
استخدام قرص Docker | استكشاف امتلاء القرص |
docker events |
تدفق أحداث الحاوية | OOM/إعادة تشغيل/خروج غير طبيعي |
docker logs |
سجلات الحاوية | أخطاء التطبيق |
docker inspect |
تكوين الحاوية | الحالة/كود الخروج/الشبكة |
iostat |
إحصائيات I/O القرص | اختناقات I/O |
iperf |
اختبار نطاق الشبكة | اختناقات الشبكة |
nsenter |
دخول namespace الحاوية | تصحيح متقدم |
4. استكشاف اختناقات CPU
▶ مثال: مراقبة الموارد بـ docker stats (الصعوبة: ⭐)
BASH
# إحصائيات في الوقت الفعلي لجميع الحاويات
docker stats
# لقطة واحدة
docker stats --no-stream
# تنسيق مخصص
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}"
▶ مثال: حاوية stress تحاكي حمل CPU (الصعوبة: ⭐⭐)
BASH
# تشغيل stress لمحاكاة حمل CPU
docker run --rm --name stress-test \
--cpus=1 \
progrium/stress --cpu 1 --timeout 30s
# المراقبة بـ docker stats (في طرفية أخرى)
docker stats stress-test --no-stream
5. استكشاف اختناقات الذاكرة
(1) مشكلات الذاكرة الشائعة
| العرض | كود الخروج | السبب | الحل |
|---|---|---|---|
| OOM Kill | 137 | تجاوز حد --memory | زيادة الحد أو تحسين استخدام الذاكرة |
| تسرب الذاكرة | زيادة تدريجية | خطأ في التطبيق | تحليل Heap Dump |
| استخدام cache مرتفع | 0 | ذاكرة نظام الملفات المؤقتة | سلوك طبيعي (يمكن استعادته) |
▶ مثال: محاكاة OOM في حاوية (الصعوبة: ⭐⭐⭐)
BASH
# بدء حاوية بحد ذاكرة 50 ميجابايت
docker run -d --name oom-test \
--memory=50m \
--restart=on-failure:3 \
progrium/stress --vm 1 --vm-bytes 100M --timeout 10s
# مراقبة أحداث OOM
docker events --filter event=oom --since 1m
# التحقق من كود الخروج
docker inspect oom-test --format='ExitCode: {{.State.ExitCode}}, OOMKilled: {{.State.OOMKilled}}'
6. استكشاف اختناقات I/O القرص
▶ مثال: تحليل القرص بـ docker system df (الصعوبة: ⭐⭐)
BASH
# عرض استخدام قرص Docker
docker system df
# تفصيل شامل
docker system df -v
💻 المخرجات:
TEXT
📖 للعرض فقط
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 12 5 4.2GB 2.8GB (66%)
Containers 8 3 350MB 280MB (80%)
Local Volumes 5 3 1.2GB 500MB (41%)
Build Cache 45 0 800MB 800MB (100%)
▶ مثال: سياسة تنظيف القرص (الصعوبة: ⭐⭐)
BASH
# إزالة البيانات غير المستخدمة (الصور، الحاويات، وحدات التخزين، ذاكرة البناء المؤقتة)
docker system prune
# أكثر قوة: إزالة جميع الصور غير المستخدمة (ليس فقط المعلقة)
docker system prune -a
# إزالة ذاكرة البناء المؤقتة فقط
docker builder prune
# إزالة وحدات التخزين (تحذير: يحذف البيانات)
docker volume prune
(1) مقارنة محركات التخزين
| المحرك | الأداء | الاستقرار | التوصية |
|---|---|---|---|
| overlay2 | عالٍ | ✅ مستقر | ✅ التوصية الافتراضية |
| aufs | متوسط | ❌ نواة قديمة | ❌ مهمل |
| devicemapper | منخفض | ❌ تكوين معقد | ❌ غير موصى به |
| zfs | متوسط | ✅ مستقر | سيناريوهات محددة |
| btrfs | متوسط | ❌ غير مستقر | ❌ غير موصى به |
7. استكشاف مشكلات الشبكة
▶ مثال: اختبار نطاق الشبكة بـ iperf (الصعوبة: ⭐⭐⭐)
BASH
# بدء خادم iperf3 في حاوية
docker run -d --name iperf-server --network host networkstatic/iperf3 -s
# تشغيل عميل iperf3 من حاوية أخرى
docker run --rm --network host networkstatic/iperf3 -c localhost -t 10
# اختبار بين حاويتين على شبكات مختلفة
docker run --rm --network app-net networkstatic/iperf3 -c db -t 5
▶ مثال: تتبع الأحداث مع Docker Events (الصعوبة: ⭐⭐)
BASH
# مراقبة أحداث دورة حياة الحاوية
docker events --filter type=container
# تصفية لأحداث محددة
docker events --filter event=oom --filter event=die --filter event=restart
# مرشح زمني
docker events --since "2024-01-15T03:00:00" --until "2024-01-15T04:00:00"
8. تصحيح متقدم: nsenter
▶ مثال: nsenter للدخول إلى namespace الحاوية (الصعوبة: ⭐⭐⭐)
BASH
# الحصول على PID الرئيسي للحاوية
PID=$(docker inspect --format='{{.State.Pid}}' myapp)
# دخول namespace الشبكة للحاوية للتصحيح
nsenter -t $PID -n tcpdump -i eth0 -c 100 port 8080
# دخول namespace العمليات للحاوية
nsenter -t $PID -p -m strace -p 1
💡 نصيحة: nsenter يعمل على مستوى أدنى من
docker exec — يدخل مباشرة إلى namespace Linux للحاوية، دون الحاجة إلى shell داخل الحاوية. مناسب لتصحيح صور scratch أو distroless.
9. دليل استكشاف الأخطاء: المشكلات الشائعة والحلول
| العرض | أمر التشخيص | الأسباب الشائعة | الحل |
|---|---|---|---|
| إعادة تشغيل متكررة للحاوية | docker ps -a + docker logs |
OOM / أعطال التطبيق | زيادة الذاكرة / إصلاح الأخطاء / سياسة إعادة التشغيل |
| امتلاء مساحة القرص | docker system df -v |
تراكم السجلات/الصور/وحدات التخزين | docker system prune + تدوير السجلات |
| انتهاء مهلة اتصال الشبكة | docker exec ping + nc |
خطأ في تكوين الشبكة | التحقق من الشبكة/DNS/المنفذ |
| بناء بطيء | docker build --progress=plain |
ذاكرة مؤقتة منتهية | ضبط ترتيب COPY |
| فشل بدء الحاوية | docker logs + docker inspect |
خطأ تكوين/تبعيات مفقودة | إصلاح التكوين/التحقق من التبعيات |
| انتظار I/O مرتفع | iostat -x |
محرك السجلات/كتابات ثقيلة | تبديل محرك السجلات/تحسين الكتابات |
10. مثال كامل: استكشاف وحل مشكلات OOM في الحاويات
BASH
# ============================================
# شرح كامل: تشخيص وإصلاح OOM
# يغطي: stats, events, logs, inspect, fix
# ============================================
# 1. نشر الحاوية التي بها مشكلة
docker run -d \
--name leaky-app \
--memory=100m \
--restart=on-failure:5 \
-p 8080:8080 \
myapp:1.0
# 2. مراقبة استخدام الموارد
docker stats leaky-app --no-stream
# 3. محاكاة تسرب الذاكرة (تفعيل OOM)
docker exec leaky-app python -c "
import itertools
data = []
for i in itertools.count():
data.append('x' * 1024 * 1024) # 1 ميجابايت لكل منها
if i % 10 == 0:
import time; time.sleep(0.1)
"
# 4. التقاط حدث OOM
docker events --filter container=leaky-app --filter event=oom --since 1m
# 5. التحقق من كود الخروج وحالة OOM
docker inspect leaky-app --format='
ExitCode: {{.State.ExitCode}}
OOMKilled: {{.State.OOMKilled}}
Memory Limit: {{.HostConfig.Memory}}
'
# 6. التحقق من سجلات التطبيق لأنماط الذاكرة
docker logs --tail 100 leaky-app 2>&1 | grep -i "memory\|alloc\|oom"
# 7. إصلاح: زيادة حد الذاكرة
docker stop leaky-app && docker rm leaky-app
docker run -d \
--name leaky-app \
--memory=512m \
--restart=on-failure:5 \
--log-opt max-size=10m \
--log-opt max-file=3 \
-p 8080:8080 \
myapp:1.0
# 8. إعداد تنبيه المراقبة
docker events --filter event=oom | while read event; do
echo "ALERT: OOM detected at $(date)" >> /var/log/docker-alerts.log
done
❓ أسئلة شائعة
س كيف تستكشف مشكلات أداء الحاويات بشكل طبقي؟
ج طريقة من أربع خطوات: ① استخدم
docker stats لعرض نظرة عامة على CPU والذاكرة و I/O؛ ② اختر الأداة المناسبة بناءً على أعلى مقياس (CPU → top، الذاكرة → smem، I/O → iostat، الشبكة → iperf)؛ ③ حدد الحاوية أو العملية المحددة؛ ④ حلل سجلات التطبيق للعثور على السبب الجذري.س أيهما أفضل، overlay2 أم aufs؟
ج overlay2 أفضل؛ إنه محرك التخزين الافتراضي والوحيد الموصى به من Docker. تم إهمال aufs ولم يعد مدعومًا في Docker 24 وما بعده. overlay2 يقدم أداءً أفضل، وتنفيذًا أبسط، ودعمًا مجتمعيًا أكثر نشاطًا.
س كيف أحرر مساحة عندما يكون قرص الحاوية ممتلئًا؟
ج
docker system df -v تحقق مما يشغل أكبر مساحة ← نظف وفقًا لذلك: ① الصور: docker image prune -a؛ ② ذاكرة البناء المؤقتة: docker builder prune؛ ③ الحاويات: docker container prune؛ ④ وحدات التخزين: docker volume prune (تابع بحذر — هذا سيحذف البيانات)؛ ⑤ الكل: docker system prune -a.س كيف أستكشف بطء I/O الحاويات؟
ج ①
docker stats تحقق من عمود BlockIO؛ ② على المضيف iostat -x 1، تحقق من %util و await؛ ③ docker system df -v تحقق من استخدام محرك التخزين؛ ④ الأسباب الشائعة: محرك السجلات ملأ القرص، طبقات overlay2 كثيرة جدًا، أو bind mount إلى قرص بطيء.س كيف أختبر زمن انتقال الشبكة للحاويات؟
ج استخدم iperf3: حاوية الخادم
iperf3 -s، حاوية العميل iperf3 -c server. اختبر معدل النقل وزمن الانتقال. للاختبار بين الحاويات، يجب أن تكون على نفس الشبكة أو تستخدم خيار --network host.📖 ملخص
- شجرة قرار استكشاف أخطاء الأداء: CPU ← الذاكرة ← I/O ← الشبكة؛ استكشف طبقة تلو الأخرى
docker statsمراقبة في الوقت الفعلي،docker system dfتحليل القرص- استكشاف OOM: استخدم
docker eventsوinspectللتحقق من المشكلة، ثم زد الذاكرة أو أصلح التطبيق - تنظيف القرص:
docker system pruneتنظيف بنقرة واحدة، تدوير السجلات لمنع التراكم - overlay2 هو محرك التخزين الوحيد الموصى به
- nsenter: ادخل إلى namespace الحاوية للتصحيح المتقدم
📝 تمارين
- تمرين أساسي (الصعوبة: ⭐): استخدم حاوية
stressلمحاكاة حمل CPU، واستخدمdocker statsلمراقبة التغيرات في استخدام CPU. - تمرين متقدم (الصعوبة: ⭐⭐): استخدم
docker system df -vلتحليل استخدام القرص، وشغلdocker system prune -aللتنظيف، وقارن الفرق في مساحة القرص قبل وبعد التنظيف. - تحدٍ (الصعوبة: ⭐⭐⭐): استخدم iperf3 لاختبار نطاق الشبكة بين حاويتين وقارن اختلافات الأداء بين شبكات bridge وشبكات host.