لو لسه بتعمل kubectl create secret يدويًا في كل namespace، وبتنسخ نفس DATABASE_URL في 3 ملفات YAML للـ dev والـ staging والـ prod، أنت بتشتغل ساعة في الأسبوع شغل ما يستاهلش، ومعرّض الـ cluster لتسرّب أول ما مطور جديد يطلع من الفريق.
External Secrets Operator: نهاية مرحلة "kubectl create secret يدويًا"
المشكلة باختصار
أي cluster بيوصل لـ 50 deployment فيما فوق، الـ secrets فيه بتعمل 3 مشاكل ثابتة لازم تتحل:
- نسخ يدوي بين namespaces: كل تغيير في password بيحتاج 3 commits وplaybook كامل.
- مفيش rotation تلقائي: الـ DB password بيقعد 9 شهور بدون تحديث لأن الـ rotation شغل يدوي مش بيعمله حد.
- صعوبة الـ audit: مش عارف مين قرى الـ secret، ولا متى، ولا من فين.
الـ Sealed Secrets بتحل النقطة الأولى جزئيًا (تشفير في Git)، لكن الـ rotation فيها يدوي والـ audit ضعيف. الـ External Secrets Operator (ESO) بيشتغل بالعكس: مصدر الحقيقة بيبقى خارج الـ cluster — في AWS Secrets Manager أو HashiCorp Vault أو Azure Key Vault — والـ ESO بيـ pull القيمة بشكل دوري ويصنع Secret فعلي داخل Kubernetes.
إزاي ESO بيشتغل فعليًا — مثال المكتبة
تخيل عندك مكتبة في الحي. الكتب الأصلية محفوظة في مخزن مركزي بكود تشفير ومسؤول واحد فقط بيعرف الكود (= AWS Secrets Manager). كل ما زائر يطلب كتاب، أمين المكتبة بيروح للمخزن، يسجّل اسم الزائر في كشف الزيارة، ويسلّمه نسخة مؤقتة للقراءة في الرف. لو الكتاب اتعدل في المخزن، أمين المكتبة بيلاحظ التغيير وبيستبدل النسخة الموجودة في الرف بدون ما الزائر يدري.
ESO هو "أمين المكتبة" ده بالظبط. بيقعد في الـ cluster، بيراقب CRD اسمه ExternalSecret، وكل refreshInterval (افتراضيًا ساعة) بيـ pull القيمة من المصدر الخارجي. لو القيمة اتغيرت، بيحدّث الـ Secret في etcd. الـ Pod بيقرأ من نفس Secret عادي ومش بيلاحظ إن في حد بيعمله sync من ورا الستار.
التعريف العلمي الدقيق: ESO هو Kubernetes Operator (custom controller مكتوب بـ Go) بيُحدّث Kubernetes Secret resources اعتمادًا على ExternalSecret manifests، عبر provider plugins تدعم AWS, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, 1Password, Akeyless، وأكثر من 20 provider تاني.
إعداد عملي بـ AWS Secrets Manager — 4 خطوات
الافتراض هنا إن الـ cluster بتاعك EKS بـ IRSA مفعّل، والـ secrets الجديدة هتترفع على نفس الـ AWS account. لو شغّال على GKE أو AKS، الخطوات تقريبًا نفسها مع تغيير الـ provider plugin.
1. ثبّت ESO عبر Helm
helm repo add external-secrets https://charts.external-secrets.io
helm repo update
helm install external-secrets external-secrets/external-secrets \
-n external-secrets \
--create-namespace \
--set installCRDs=trueبعد دقيقة، kubectl get pods -n external-secrets هيرجع 3 pods (controller + cert-controller + webhook).
2. أنشئ IAM Role مع IRSA يقدر يقرأ من Secrets Manager
السياسة الأدنى المطلوبة (least privilege، scope مقيّد لـ prefix محدد):
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret"
],
"Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/*"
}]
}3. عرّف ClusterSecretStore
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
name: aws-secrets
spec:
provider:
aws:
service: SecretsManager
region: us-east-1
auth:
jwt:
serviceAccountRef:
name: external-secrets-sa
namespace: external-secrets4. أنشئ ExternalSecret لكل secret تحتاجه
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: app-db-creds
namespace: production
spec:
refreshInterval: 15m
secretStoreRef:
name: aws-secrets
kind: ClusterSecretStore
target:
name: db-credentials
creationPolicy: Owner
data:
- secretKey: DATABASE_URL
remoteRef:
key: prod/checkout/db
property: connection_string
- secretKey: DATABASE_PASSWORD
remoteRef:
key: prod/checkout/db
property: passwordبعد دقيقتين، kubectl get secret db-credentials -n production -o yaml هيرجع Secret عادي يستخدمه أي Deployment عبر envFrom أو volume mount.
الأرقام الفعلية من cluster إنتاج
في cluster بـ 80 microservice و 6 namespaces (dev/staging/prod × backend/frontend)، بعد التحويل الكامل لـ ESO:
- وقت إضافة secret جديد: من 18 دقيقة (تعديل YAML + 3 PRs + مراجعة) إلى دقيقتين (تحديث Secrets Manager فقط).
- عدد الـ secrets المعرّفة في Git: من 240 entry إلى 80
ExternalSecretmanifest بس. - Rotation الفعلي: من حدث "كل 6 شهور بمناسبة audit" إلى rotation تلقائي كل 30 يوم عبر Lambda rotation function.
- التكلفة المضافة: ~$0.40 للـ secret في الشهر × 80 = $32 في الشهر، مقابل توفير حوالي 6 ساعات شغل DevOps شهريًا.
الـ trade-off هنا واضح: بتدفع تكلفة AWS Secrets Manager، بتكسب rotation تلقائي + audit log كامل + central source of truth + هجرة أسهل بين clusters.
trade-offs لازم تعرفها قبل ما تتبنّاها
أولًا، dependency جديد على الـ network: الـ cluster مبقاش يقدر يستهلك secrets جديدة بدون اتصال بـ AWS أو Vault. لو الـ network اتقطع، الـ Pods اللي عايزة secret جديد مش هتشتغل. الحل: استعمل VPC endpoints وفعّل caching محلي على ESO.
ثانيًا، الـ application لازم تدعم hot reload: لو app بتقرأ DATABASE_URL من environment variable مرة واحدة عند الـ start-up، تحديث الـ Secret في Kubernetes مش هيوصل لها أصلًا. الحل: استعمل volume mounts بدل env vars وراقب الملف بـ inotify، أو شغّل Reloader اللي بيعمل rollout restart تلقائي بعد كل تغيير في الـ Secret.
ثالثًا، صلاحيات IAM/Vault أخطر من قبل: أي حد عنده access للـ ClusterSecretStore يقدر يقرأ كل الـ secrets في الـ AWS path. لازم تعمل IAM scoping دقيق per namespace، أو تستعمل SecretStore (مش Cluster-scoped) عشان كل namespace يبقى ليها صلاحياتها لوحدها.
متى لا تستخدم ESO
- لو الـ cluster صغير بأقل من 10 deployments والـ secrets ثابتة لسنوات: Sealed Secrets أبسط ومش محتاج external dependency.
- لو ما عندكش external secret manager فعلًا (مفيش AWS أو Vault أو Azure): ESO بدون provider مفيش له معنى.
- لو الـ compliance بتاعتك بتمنع إن secrets تخرج من الـ cluster لأي external service: شغّل HashiCorp Vault داخل الـ cluster نفسه واستخدمه كـ provider.
- لو الفريق فيه developer واحد والـ rotation مش requirement فعلي: التعقيد المضاف مش هيستاهل المقابل.
الخطوة التالية
افتح cluster الـ staging بتاعك دلوقتي، نصّب ESO عبر الـ Helm chart، وحوّل secret واحد فقط — الأقل حساسية، يفضّل API key لخدمة third-party زي SendGrid أو Stripe test keys. سيب refreshInterval: 5m أيام كده وراقب الـ logs عبر kubectl logs -n external-secrets deploy/external-secrets. لو الـ sync شغّال نضيف، حط خطة هجرة على 4 sprints لباقي الـ secrets، وابدأ بأقل namespace حساسية.
مصادر
- التوثيق الرسمي: external-secrets.io — كل الـ providers والـ CRDs.
- AWS Containers Blog: Leverage AWS secrets stores from EKS Fargate with External Secrets Operator.
- دليل AWS Secrets Manager provider الرسمي: external-secrets.io/provider/aws-secrets-manager.
- مقارنة Sealed Secrets vs ESO vs CSI Driver: Shiv Rathore — Medium.
- SUSE Communities: Managing Sensitive Data in Kubernetes with ESO.
- Reloader للـ hot-reload: github.com/stakater/Reloader.