المستوى: مبتدئ — الشرح ده مناسب لأي حد شغّل تطبيق على Kubernetes مرة واحدة على الأقل، وعارف يشغّل أمر kubectl. مش محتاج خبرة سابقة بالإعدادات.
افصل إعداداتك وأسرارك عن الكود في Kubernetes
لو حاطط كلمة سر قاعدة البيانات جوّه الكود أو جوّه صورة الحاوية، انت واقع في مشكلة أمان مش هتحسّ بيها دلوقتي. أول ما الصورة دي توصل لأي حد، السر بقى معاه للأبد. الحل اسمه ConfigMap وSecret، وهتفهمهم بالكامل في أقل من 8 دقايق، مع مثال تقدر تنسخه وتشغّله.
المشكلة باختصار
صورة الحاوية (Container Image) مفروض تبقى ثابتة. نفس الصورة تشتغل على جهازك، على بيئة الاختبار، وعلى الإنتاج. لكن الإعدادات بتتغيّر: رابط قاعدة البيانات مختلف، مستوى اللوج مختلف، وكلمة السر أكيد مختلفة. لو خبّيت الإعدادات دي جوّه الكود، هتضطر تبني صورة جديدة لكل بيئة، وهتسرّب أسرارك جوّه طبقات الصورة اللي بتفضل متخزّنة حتى بعد ما تمسحها.
الفكرة بمثال بسيط
تخيّل وصفة أكل مكتوبة في كتاب طبخ. الكتاب ده هو الكود: ثابت، مطبوع، مش بتعيد طباعته كل يوم. كمية الملح والتوابل مكتوبة على ورقة لاصقة جنب الكتاب — دي الإعدادات. عايز تزوّد الملح في بيت صاحبك؟ بتغيّر الورقة بس، مش بتعيد طباعة الكتاب كله. ده بالظبط الـ ConfigMap.
لكن فيه توابل سرّية بتاعة العيلة مقفولة في درج بمفتاح. المفتاح ده هو الـ Secret: قيمة حساسة مبتتكتبش على ورقة مكشوفة قدام أي حد، وبتتخزّن لوحدها بصلاحيات وصول محدودة. الفكرة كلها في جملة واحدة: خلّي الكتاب ثابت، وحطّ اللي بيتغيّر برّه.
التعريف الدقيق
الـ ConfigMap كائن (object) في Kubernetes بيخزّن إعدادات غير حساسة كأزواج مفتاح/قيمة، زي LOG_LEVEL أو API_URL. الـ Secret نفس الفكرة بالظبط لكن للقيم الحساسة: كلمات السر، التوكنز، ومفاتيح الـ API. الاتنين بيتحقنوا في الحاوية بطريقتين: إما متغيّرات بيئة (environment variables)، وإما ملفات مركّبة على مسار جوّه الحاوية (mounted volume).
نقطة مهمة جدًا لازم تعرفها من دلوقتي: الـ Secret مش مشفّر افتراضيًا. هو مجرد مكوّد بـ base64، واللي أي حد يقدر يفكّه في ثانية بأمر واحد. يعني الفصل بيحصل فعلًا، لكن الأمان الحقيقي محتاج خطوة زيادة هنشرحها تحت.
مثال تنفيذي تقدر تنسخه
هنعمل ConfigMap للإعدادات، Secret لكلمة السر، وبعدين نربطهم بالتطبيق في ملف الـ Deployment.
أولًا، الـ ConfigMap في ملف config.yaml:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
LOG_LEVEL: "debug"
API_URL: "https://api.example.com"ثانيًا، الـ Secret. متكتبوش في ملف YAML عادي يروح على Git — اعمله بأمر مباشر:
# إنشاء Secret من قيمة مباشرة بدون ما تكتبها في أي ملف
kubectl create secret generic db-credentials \
--from-literal=DB_PASSWORD='S3cureP@ss'ثالثًا، اربطهم بالتطبيق في deployment.yaml: الـ ConfigMap كله بيتحوّل لمتغيّرات بيئة عبر envFrom، وكلمة السر بتتحقن من الـ Secret عبر secretKeyRef:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: myregistry/web:1.4.0
envFrom:
- configMapRef:
name: app-config
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: DB_PASSWORDطبّق الملفات وتأكّد إن الإعداد وصل جوّه الحاوية:
kubectl apply -f config.yaml
kubectl apply -f deployment.yaml
# تأكد إن LOG_LEVEL اتحقن فعلًا
kubectl exec deploy/web -- printenv LOG_LEVEL
# المخرج المتوقع: debugسيناريو واقعي بالأرقام
لو عندك 3 بيئات (تطوير، اختبار، إنتاج) وكل بناء صورة بياخد حوالي 4 دقايق، فبدل ما تبني 3 صور مختلفة (12 دقيقة بناء + 3 نسخ متخزّنة في الـ registry)، تبني صورة واحدة وتبدّل الـ ConfigMap لكل بيئة. النتيجة: صورة واحدة بدل 3، وصفر أسرار متخزّنة جوّه الصورة. والأهم: لو سرّبت صورة فيها كلمة سر مكتوبة، السر ده بيفضل موجود في تاريخ طبقات الصورة (image layers) حتى لو مسحته في طبقة بعده — أي حد يعمل docker history ممكن يطلّعه.
الـ trade-off اللي لازم تعرفه
بتكسب: صورة واحدة نظيفة، تبديل إعدادات من غير إعادة بناء، وتحكّم في مين يقدر يقرأ الأسرار عبر صلاحيات RBAC. بتخسر: الـ Secret لوحده مش حماية. لو ماعملتش حاجتين — تفعيل التشفير أثناء التخزين (Encryption at Rest) على قاعدة بيانات الكلاستر etcd، وضبط صلاحيات RBAC بمبدأ أقل امتياز — فأي حد عنده وصول لـ etcd أو صلاحية get secret بيقرأ كل أسرارك زي ما هي. حسب توثيق Kubernetes الرسمي، الـ Secrets بتتخزّن غير مشفّرة في etcd افتراضيًا، ولازم تفعّل التشفير بنفسك.
الافتراض هنا إنك بتشغّل Kubernetes حقيقي (EKS أو GKE أو AKS أو حتى minikube للتجربة المحلية) وإن kubectl بتاعك متصل بالكلاستر الصح.
متى لا تستخدم هذه الطريقة
لو مشروعك مش على Kubernetes أصلًا، الـ ConfigMap و Secret مالهومش لازمة — استخدم ملف .env أو مدير أسرار مناسب للـ VM. لو السر شديد الحساسية (مفاتيح دفع أو مفاتيح تشفير) في إنتاج جاد، الـ Secret العادي مش كفاية؛ روح لحل خارجي زي HashiCorp Vault أو Cloud KMS أو Sealed Secrets. ولو الإعداد ثابت ومش بيتغيّر بين البيئات، عادي يفضل جوّه الصورة ومتعقّدش الأمور من غير داعي.
الخطوة التالية
شغّل الأمر ده دلوقتي على أي Secret عندك في الكلاستر:
kubectl get secret db-credentials -o jsonpath='{.data.DB_PASSWORD}' | base64 -dهتلاقي كلمة السر بتظهر نص واضح في ثانية. ده بيثبتلك بعينك إن base64 مش تشفير. بعد ما تشوفها، فعّل Encryption at Rest على الكلاستر وابدأ تضبط RBAC بأقل امتياز. ابدأ بالخطوة دي النهارده قبل ما تضيف أي سر جديد.
المصادر
- Kubernetes Documentation — Secrets: kubernetes.io/docs/concepts/configuration/secret
- Kubernetes Documentation — Good practices for Kubernetes Secrets: kubernetes.io/docs/concepts/security/secrets-good-practices
- Kubernetes Documentation — ConfigMaps: kubernetes.io/docs/concepts/configuration/configmap
- The Twelve-Factor App — Config: 12factor.net/config