0%
إدارة الأسرار والإعدادات في Kubernetes

إدارة الأسرار والإعدادات في Kubernetes

تعرّف على كيفية إدارة الأسرار والإعدادات في Kubernetes بكفاءة لتأمين تطبيقاتك وتسهيل نشرها.

I

InSkillCoach

· دقيقة

مقدمة

في بيئة Kubernetes، تُعدّ إدارة الإعدادات والأسرار جانبًا أساسيًا في نشر التطبيقات وصيانتها. يستعرض هذا المقال مختلف الطرق لإدارة هذه العناصر بشكل آمن وفعّال.

ConfigMaps: إدارة الإعدادات

ConfigMaps هي كائنات في Kubernetes تتيح تخزين البيانات غير السرية على شكل أزواج مفتاح-قيمة. وهي مثالية لفصل إعدادات التطبيق عن الشيفرة، مما يسهّل إجراء التعديلات دون إعادة بناء الصورة.

إنشاء ConfigMap

الطريقة 1: من ملف

# Créer un fichier de configuration
cat > app-config.properties << EOF
APP_ENV=production
LOG_LEVEL=info
API_URL=https://api.example.com
EOF

# Créer un ConfigMap à partir du fichier
kubectl create configmap app-config --from-file=app-config.properties

الطريقة 2: من سطر الأوامر

kubectl create configmap app-config \
  --from-literal=APP_ENV=production \
  --from-literal=LOG_LEVEL=info \
  --from-literal=API_URL=https://api.example.com

الطريقة 3: تعريف YAML

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_ENV: production
  LOG_LEVEL: info
  API_URL: https://api.example.com

استخدام ConfigMaps

1. متغيرات البيئة

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  template:
    spec:
      containers:
      - name: myapp
        image: myapp:1.0
        envFrom:
        - configMapRef:
            name: app-config

2. متغيرات البيئة الفردية

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  template:
    spec:
      containers:
      - name: myapp
        image: myapp:1.0
        env:
        - name: APP_ENV
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: APP_ENV
        - name: LOG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: LOG_LEVEL

3. ملفات الإعدادات

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  template:
    spec:
      containers:
      - name: myapp
        image: myapp:1.0
        volumeMounts:
        - name: config-volume
          mountPath: /app/config
      volumes:
      - name: config-volume
        configMap:
          name: app-config

Secrets: إدارة البيانات الحساسة

تشبه Secrets كائنات ConfigMaps، لكنها مصمَّمة لتخزين البيانات الحساسة مثل كلمات المرور ورموز API (tokens) والمفاتيح الخاصة. يخزّن Kubernetes الأسرار بترميز base64، لكن ذلك لا يُعدّ تشفيرًا حقيقيًا.

إنشاء Secret

الطريقة 1: من سطر الأوامر

kubectl create secret generic app-secrets \
  --from-literal=DB_USERNAME=admin \
  --from-literal=DB_PASSWORD=secretpassword

الطريقة 2: من ملف

# Créer un fichier de secrets
cat > app-secrets.txt << EOF
DB_USERNAME=admin
DB_PASSWORD=secretpassword
EOF

# Créer un Secret à partir du fichier
kubectl create secret generic app-secrets --from-file=app-secrets.txt

الطريقة 3: تعريف YAML (بقيم base64)

apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
type: Opaque
data:
  DB_USERNAME: YWRtaW4=  # base64 de "admin"
  DB_PASSWORD: c2VjcmV0cGFzc3dvcmQ=  # base64 de "secretpassword"

استخدام Secrets

1. متغيرات البيئة

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  template:
    spec:
      containers:
      - name: myapp
        image: myapp:1.0
        envFrom:
        - secretRef:
            name: app-secrets

2. متغيرات البيئة الفردية

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  template:
    spec:
      containers:
      - name: myapp
        image: myapp:1.0
        env:
        - name: DB_USERNAME
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: DB_USERNAME
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: DB_PASSWORD

3. ملفات الإعدادات

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  template:
    spec:
      containers:
      - name: myapp
        image: myapp:1.0
        volumeMounts:
        - name: secret-volume
          mountPath: /app/secrets
          readOnly: true
      volumes:
      - name: secret-volume
        secret:
          secretName: app-secrets

أفضل الممارسات لإدارة الأسرار

1. استخدام مدير أسرار خارجي

يخزّن Kubernetes الأسرار بترميز base64، وهذا لا يُعدّ تشفيرًا حقيقيًا. للحصول على أمان أقوى، استخدم مدير أسرار خارجيًا مثل:

  • HashiCorp Vault: حل متكامل لإدارة الأسرار
  • AWS Secrets Manager: خدمة مُدارة لأسرار AWS
  • Azure Key Vault: خدمة إدارة الأسرار في Azure
  • Google Secret Manager: خدمة إدارة الأسرار في GCP

التكامل مع Vault

apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
  name: vault-auth
spec:
  method: kubernetes
  mount: kubernetes
  kubernetes:
    role: application
    serviceAccount: vault-auth
    tokenReviewerJWT: ""
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultSecret
metadata:
  name: app-secrets
spec:
  vaultAuthRef: vault-auth
  path: secret/data/application
  type: Opaque

2. استخدام الأسرار لسجلات الحاويات

للوصول إلى سجلات الحاويات الخاصة (container registries)، استخدم أسرارًا من النوع docker-registry:

kubectl create secret docker-registry regcred \
  --docker-server=<your-registry-server> \
  --docker-username=<your-username> \
  --docker-password=<your-password> \
  --docker-email=<your-email>

ثم أشِر إليه في عملية النشر (Deployment):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  template:
    spec:
      imagePullSecrets:
      - name: regcred
      containers:
      - name: myapp
        image: private-registry.example.com/myapp:1.0

3. استخدام الأسرار لشهادات TLS

بالنسبة لشهادات TLS، استخدم أسرارًا من النوع tls:

kubectl create secret tls tls-secret \
  --cert=path/to/tls.cert \
  --key=path/to/tls.key

ثم استخدمه في Ingress الخاص بك:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-ingress
spec:
  tls:
  - hosts:
    - example.com
    secretName: tls-secret
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-service
            port:
              number: 80

4. تدوير الأسرار

اعتمد استراتيجية لتدوير الأسرار بشكل دوري:

apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
  annotations:
    kubernetes.io/change-cause: "Rotation des secrets - 2024-05-10"
type: Opaque
data:
  DB_PASSWORD: <new-base64-encoded-password>

إدارة الإعدادات المتقدمة

1. ConfigMaps لملفات الإعدادات

للتطبيقات التي تتطلب ملفات إعدادات كاملة:

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  nginx.conf: |
    server {
      listen 80;
      server_name example.com;
      location / {
        proxy_pass http://backend;
      }
    }
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  template:
    spec:
      containers:
      - name: nginx
        image: nginx:1.19
        volumeMounts:
        - name: config-volume
          mountPath: /etc/nginx/conf.d
      volumes:
      - name: config-volume
        configMap:
          name: app-config

2. ConfigMaps لسكربتات التهيئة

لسكربتات التهيئة أو الإعداد:

apiVersion: v1
kind: ConfigMap
metadata:
  name: init-scripts
data:
  init.sh: |
    #!/bin/bash
    echo "Initializing application..."
    # Script d'initialisation
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  template:
    spec:
      initContainers:
      - name: init
        image: busybox
        command: ["/scripts/init.sh"]
        volumeMounts:
        - name: scripts-volume
          mountPath: /scripts
      containers:
      - name: myapp
        image: myapp:1.0
      volumes:
      - name: scripts-volume
        configMap:
          name: init-scripts
          defaultMode: 0755

3. استخدام Helm لإدارة الإعدادات

Helm هو مدير حزم لـ Kubernetes يبسّط إدارة الإعدادات:

# values.yaml
config:
  APP_ENV: production
  LOG_LEVEL: info
secrets:
  DB_PASSWORD: secretpassword
---
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-deployment
spec:
  template:
    spec:
      containers:
      - name: myapp
        image: myapp:{{ .Values.image.tag }}
        env:
        - name: APP_ENV
          value: {{ .Values.config.APP_ENV }}
        - name: LOG_LEVEL
          value: {{ .Values.config.LOG_LEVEL }}
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: {{ .Release.Name }}-secrets
              key: DB_PASSWORD

أمان الأسرار

1. التشفير أثناء التخزين (Encryption at Rest)

فعّل التشفير أثناء التخزين للأسرار في etcd:

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
    - secrets
    providers:
    - aescbc:
        keys:
        - name: key1
          secret: <base64-encoded-key>
    - identity: {}

2. RBAC للأسرار

استخدم RBAC للحدّ من الوصول إلى الأسرار:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: secret-reader-binding
subjects:
- kind: ServiceAccount
  name: app-service-account
  namespace: default
roleRef:
  kind: Role
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

3. تدقيق الأسرار

فعّل التدقيق (audit) لتتبّع الوصول إلى الأسرار:

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
  users: ["system:serviceaccount"]
  verbs: ["get", "list", "watch"]
  resources:
  - group: ""
    resources: ["secrets"]

مثال كامل: تطبيق يستخدم ConfigMaps وSecrets

إليك مثالًا كاملًا لتطبيق يستخدم ConfigMaps وSecrets:

# ConfigMap pour la configuration de l'application
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_ENV: production
  LOG_LEVEL: info
  API_URL: https://api.example.com
  nginx.conf: |
    server {
      listen 80;
      server_name example.com;
      location / {
        proxy_pass http://backend;
      }
    }
---
# Secret pour les données sensibles
apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
type: Opaque
data:
  DB_USERNAME: YWRtaW4=  # base64 de "admin"
  DB_PASSWORD: c2VjcmV0cGFzc3dvcmQ=  # base64 de "secretpassword"
---
# Déploiement de l'application
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:1.0
        ports:
        - containerPort: 8080
        envFrom:
        - configMapRef:
            name: app-config
        - secretRef:
            name: app-secrets
        volumeMounts:
        - name: config-volume
          mountPath: /app/config
        - name: nginx-config-volume
          mountPath: /etc/nginx/conf.d
      volumes:
      - name: config-volume
        configMap:
          name: app-config
      - name: nginx-config-volume
        configMap:
          name: app-config
---
# Service pour exposer l'application
apiVersion: v1
kind: Service
metadata:
  name: app-service
spec:
  selector:
    app: myapp
  ports:
  - port: 80
    targetPort: 8080
  type: LoadBalancer

خاتمة

تُعدّ الإدارة الفعّالة للأسرار والإعدادات أمرًا أساسيًا لنشر التطبيقات بشكل آمن في Kubernetes. فباستخدام ConfigMaps للبيانات غير السرية وSecrets للبيانات الحساسة، يمكنك فصل الإعدادات عن الشيفرة وتسهيل إجراء التعديلات دون إعادة بناء الصور.

للحصول على أمان أقوى، فكّر في استخدام مدير أسرار خارجي مثل HashiCorp Vault، الذي يوفّر تشفيرًا حقيقيًا وميزات متقدمة لإدارة الأسرار.

في المقال القادم، سنستعرض المراقبة (monitoring) وتسجيل السجلات (logging) في Kubernetes، وهما جانبان أساسيان للحفاظ على سلامة تطبيقاتك وأدائها.

InSkillCoach

نبذة عن InSkillCoach

خبير في التدريب والتقنيات

مدرّب متخصص في التقنيات المتقدمة والذكاء الاصطناعي، تدعمه شركة GNeurone Inc.

الشهادات:

  • AWS Certified Solutions Architect – Professional
  • شهادات Google Cloud
  • Microsoft Certified: DevOps Engineer Expert
  • Certified Kubernetes Administrator (CKA)
  • CompTIA Security+
857
340

التعليقات

التعليقات مدعومة عبر GitHub Discussions

سجّل الدخول باستخدام GitHub للمشاركة في النقاش

تم نسخ الرابط!