Kubernetes وتنسيق الحاويات
داخليات Docker: Namespaces وCgroups والصور
فهم داخليات الحاويات يُميز المرشح الأقدم عن المبتدئ. دعنا نستكشف ما يجعل الحاويات تعمل.
لبنات بناء Linux
الحاويات ليست سحراً—هي مبنية على ميزات نواة Linux:
| الميزة | الغرض | ما تعزله |
|---|---|---|
| Namespaces | العزل | معرفات العمليات، الشبكة، التركيبات، المستخدمين |
| Cgroups | حدود الموارد | CPU، الذاكرة، I/O، عرض نطاق الشبكة |
| Union FS | التخزين الطبقي | طبقات نظام الملفات |
الغوص العميق في Namespaces
Namespaces في Linux توفر العزل:
# عرض namespaces لعملية
ls -la /proc/<pid>/ns/
# أنواع namespaces:
# PID - عزل العمليات (الحاوية ترى PID 1)
# NET - مكدس الشبكة (واجهات خاصة، توجيه)
# MNT - نقاط التركيب (رؤية نظام ملفات خاصة)
# UTS - اسم المضيف (اسم مضيف خاص)
# IPC - التواصل بين العمليات
# USER - معرفات المستخدم/المجموعة (root في الحاوية ≠ root على المضيف)
# CGROUP - جذر Cgroup (جديد في نواة 4.6)
سؤال مقابلة: "كيف للحاوية أن يكون لديها PID 1 بينما المضيف يرى PID مختلف؟"
الجواب: PID namespaces. الحاوية لديها namespace PID خاص بها حيث العملية الرئيسية هي PID 1. المضيف يرى PID الفعلي في namespace العالمي. استخدم
docker top <container>لرؤية PIDs المضيف.
Cgroups (مجموعات التحكم)
Cgroups تحد وتحسب استخدام الموارد:
# عرض حدود cgroup للحاوية
docker inspect <container> | jq '.[0].HostConfig.Memory'
# على المضيف، موقع cgroups v2
ls /sys/fs/cgroup/
# cgroup الحاوية
cat /sys/fs/cgroup/docker/<container-id>/memory.max
حدود الموارد في Docker
# حد CPU (1.5 نواة)
docker run --cpus="1.5" nginx
# حد الذاكرة (512MB)
docker run --memory="512m" nginx
# الذاكرة + التبديل
docker run --memory="512m" --memory-swap="1g" nginx
# حدود I/O
docker run --device-read-bps /dev/sda:10mb nginx
طبقات صور Docker
الصور مبنية من طبقات باستخدام Union FS:
FROM python:3.11-slim # الطبقة 1: الصورة الأساسية
WORKDIR /app # الطبقة 2: البيانات الوصفية
COPY requirements.txt . # الطبقة 3: ملف صغير
RUN pip install -r requirements.txt # الطبقة 4: التبعيات
COPY . . # الطبقة 5: كود التطبيق
+---------------------------+
| الطبقة 5: COPY . . | (قابلة للكتابة في الحاوية)
+---------------------------+
| الطبقة 4: RUN pip install| (مخزنة مؤقتاً إذا req لم تتغير)
+---------------------------+
| الطبقة 3: COPY req.txt |
+---------------------------+
| الطبقة 2: WORKDIR |
+---------------------------+
| الطبقة 1: python:3.11-slim|
+---------------------------+
تحسين الطبقات
# سيء: يُبطل الذاكرة المؤقتة عند أي تغيير في الكود
COPY . .
RUN pip install -r requirements.txt
# جيد: التبعيات مخزنة مؤقتاً بشكل منفصل
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
البناء متعدد المراحل
قلل حجم الصورة بشكل كبير:
# مرحلة البناء
FROM golang:1.21 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /app/server
# مرحلة التشغيل
FROM gcr.io/distroless/static-debian12
COPY /app/server /server
ENTRYPOINT ["/server"]
النتيجة: الصورة النهائية ~10MB بدلاً من ~1GB
شبكات Docker
# أوضاع الشبكة
docker run --network=bridge nginx # الافتراضي، NAT
docker run --network=host nginx # مكدس شبكة المضيف
docker run --network=none nginx # بدون شبكة
docker run --network=container:other nginx # مشاركة مع أخرى
# إنشاء شبكة مخصصة
docker network create --driver bridge my-network
docker run --network=my-network --name web nginx
docker run --network=my-network --name api my-api
# 'web' و 'api' يمكنهما التواصل بالاسم
أسئلة المقابلة
س: "حاوية تستخدم ذاكرة كثيرة وتُقتل بـ OOM. كيف تمنع هذا؟"
# ضبط حد الذاكرة
docker run --memory="512m" --memory-swap="512m" app
# في Kubernetes
resources:
limits:
memory: "512Mi"
requests:
memory: "256Mi"
س: "اشرح الفرق بين ENTRYPOINT وCMD"
| الجانب | ENTRYPOINT | CMD |
|---|---|---|
| الغرض | يُحدد البرنامج القابل للتنفيذ | الوسائط الافتراضية |
| التجاوز | علم --entrypoint |
إلحاق بـ docker run |
| الجمع | CMD يصبح وسائط لـ ENTRYPOINT | — |
# مثال: CMD كوسائط افتراضية لـ ENTRYPOINT
ENTRYPOINT ["python", "app.py"]
CMD ["--port", "8080"]
# docker run myapp → python app.py --port 8080
# docker run myapp --debug → python app.py --debug
س: "كيف تصحح حاوية تتعطل فوراً؟"
# تجاوز entrypoint للحصول على shell
docker run -it --entrypoint /bin/sh myimage
# تحقق من السجلات
docker logs <container>
# افحص الصورة
docker history myimage
docker inspect myimage
# شغّل مع مخرجات أكثر تفصيلاً
docker run --rm myimage 2>&1
التالي، سنستكشف معمارية Kubernetes—طبقة التنسيق فوق الحاويات. :::