توفير البنية التحتية مع Crossplane

البنية التحتية ذاتية الخدمة

3 دقيقة للقراءة

الهدف النهائي لتركيبات Crossplane هو تمكين الخدمة الذاتية للمطورين. يوضح هذا الدرس كيفية إنشاء المطالبات التي يستخدمها المطورون، والتكامل مع Backstage لتجربة خدمة ذاتية كاملة.

المطالبات مقابل الموارد المركبة

┌─────────────────────────────────────────────────────────┐
│                   أنواع الموارد                          │
├─────────────────────────────────────────────────────────┤
│                                                          │
│  Composite Resource (XR):                                │
│  ├── نطاق المجموعة (بدون مساحة اسم)                     │
│  ├── وصول كامل لجميع ميزات التركيب                     │
│  ├── يستخدمه: فرق المنصة، الأتمتة                       │
│  └── apiVersion: platform.acme.com/v1alpha1             │
│      kind: XDatabase                                     │
│                                                          │
│  Claim (المطالبة):                                       │
│  ├── نطاق مساحة الاسم                                   │
│  ├── ينشئ XR خلف الكواليس                              │
│  ├── يستخدمه: المطورون (مساحات أسماء الفرق)            │
│  └── apiVersion: platform.acme.com/v1alpha1             │
│      kind: Database                                      │
│                                                          │
└─────────────────────────────────────────────────────────┘

إنشاء مطالبة

المطورون يطلبون البنية التحتية باستخدام المطالبات:

# database-claim.yaml
apiVersion: platform.acme.com/v1alpha1
kind: Database
metadata:
  name: orders-db
  namespace: team-orders
spec:
  size: small
  engine: postgres
  version: "15"
  storageGB: 50
  compositionSelector:
    matchLabels:
      provider: aws
  writeConnectionSecretToRef:
    name: orders-db-connection
# المطور ينشئ المطالبة
kubectl apply -f database-claim.yaml

# مراقبة حالة المطالبة
kubectl get database orders-db -n team-orders -w
# NAME        SYNCED   READY   CONNECTION-SECRET       AGE
# orders-db   True     False   orders-db-connection    10s
# orders-db   True     True    orders-db-connection    5m

# فحص XR المُنشأ (نطاق المجموعة)
kubectl get xdatabase
# NAME              SYNCED   READY   COMPOSITION    AGE
# orders-db-xxxxx   True     True    database-aws   5m

# عرض جميع الموارد المُنشأة
kubectl get managed -l crossplane.io/claim-name=orders-db

أسرار الاتصال

المطالبات تكتب تفاصيل الاتصال إلى أسرار نطاق مساحة الاسم:

# المطالبة مع سر الاتصال
apiVersion: platform.acme.com/v1alpha1
kind: Database
metadata:
  name: app-db
  namespace: my-app
spec:
  size: medium
  writeConnectionSecretToRef:
    name: db-credentials  # يُنشأ في مساحة اسم my-app
# استخدام السر في deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: my-app
spec:
  template:
    spec:
      containers:
        - name: app
          image: my-app:latest
          env:
            - name: DB_HOST
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: endpoint
            - name: DB_PORT
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: port
            - name: DB_USER
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: username
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: password

تكامل Backstage

إنشاء قالب Backstage يوفر البنية التحتية عبر Crossplane:

# backstage-template-database.yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: provision-database
  title: توفير قاعدة بيانات
  description: طلب قاعدة بيانات PostgreSQL أو MySQL لخدمتك
  tags:
    - database
    - infrastructure
    - crossplane
spec:
  owner: platform-team
  type: infrastructure

  parameters:
    - title: تكوين قاعدة البيانات
      required:
        - name
        - size
        - engine
      properties:
        name:
          title: اسم قاعدة البيانات
          type: string
          description: اسم لقاعدة بياناتك (أحرف صغيرة، شرطات فقط)
          pattern: '^[a-z][a-z0-9-]*$'
        size:
          title: الحجم
          type: string
          enum:
            - small
            - medium
            - large
          enumNames:
            - صغير (db.t3.micro - التطوير/الاختبار)
            - متوسط (db.t3.medium - المرحلة التجريبية)
            - كبير (db.r6g.large - الإنتاج)
          default: small
        engine:
          title: محرك قاعدة البيانات
          type: string
          enum:
            - postgres
            - mysql
          default: postgres
        version:
          title: إصدار المحرك
          type: string
          default: "15"
        storageGB:
          title: التخزين (جيجابايت)
          type: integer
          minimum: 20
          maximum: 1000
          default: 20

    - title: البيئة المستهدفة
      required:
        - namespace
        - owner
      properties:
        namespace:
          title: مساحة اسم Kubernetes
          type: string
          description: مساحة الاسم حيث سيُنشأ سر قاعدة البيانات
        owner:
          title: المالك
          type: string
          description: الفريق الذي يملك قاعدة البيانات هذه
          ui:field: OwnerPicker
          ui:options:
            catalogFilter:
              kind: Group

  steps:
    - id: create-claim
      name: إنشاء مطالبة قاعدة البيانات
      action: kubernetes:apply
      input:
        namespaced: true
        manifest:
          apiVersion: platform.acme.com/v1alpha1
          kind: Database
          metadata:
            name: ${{ parameters.name }}
            namespace: ${{ parameters.namespace }}
            labels:
              app.kubernetes.io/managed-by: backstage
              backstage.io/owner: ${{ parameters.owner }}
          spec:
            size: ${{ parameters.size }}
            engine: ${{ parameters.engine }}
            version: ${{ parameters.version }}
            storageGB: ${{ parameters.storageGB }}
            writeConnectionSecretToRef:
              name: ${{ parameters.name }}-connection

    - id: register-component
      name: التسجيل في الكتالوج
      action: catalog:register
      input:
        catalogInfoUrl: https://github.com/acme/infrastructure-catalog/blob/main/databases/${{ parameters.name }}/catalog-info.yaml

  output:
    links:
      - title: عرض قاعدة البيانات في الكتالوج
        url: ${{ steps['register-component'].output.entityRef }}
      - title: سر الاتصال
        url: /kubernetes/secrets/${{ parameters.namespace }}/${{ parameters.name }}-connection

RBAC للخدمة الذاتية

تكوين Kubernetes RBAC للسماح للفرق بإنشاء المطالبات:

# rbac-database-claims.yaml
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: database-claim-creator
rules:
  - apiGroups: ["platform.acme.com"]
    resources: ["databases"]
    verbs: ["get", "list", "watch", "create", "update", "delete"]

---
# منح لمساحة اسم الفريق
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: database-claims
  namespace: team-orders
subjects:
  - kind: Group
    name: team-orders
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: database-claim-creator
  apiGroup: rbac.authorization.k8s.io

تدفق الخدمة الذاتية الكامل

┌─────────────────────────────────────────────────────────┐
│                   تدفق الخدمة الذاتية                    │
├─────────────────────────────────────────────────────────┤
│                                                          │
│  1. المطور                                               │
│     │                                                    │
│     ▼                                                    │
│  ┌─────────────────────┐                                │
│  │     BACKSTAGE       │                                │
│  │  "توفير قاعدة بيانات"│                               │
│  │   - size: medium    │                                │
│  │   - engine: postgres│                                │
│  └──────────┬──────────┘                                │
│             │                                            │
│  2. BACKSTAGE ينشئ                                       │
│     │                                                    │
│     ▼                                                    │
│  ┌─────────────────────┐                                │
│  │     المطالبة        │                                │
│  │  kind: Database     │                                │
│  │  namespace: team-x  │                                │
│  └──────────┬──────────┘                                │
│             │                                            │
│  3. CROSSPLANE يعالج                                     │
│     │                                                    │
│     ▼                                                    │
│  ┌─────────────────────┐                                │
│  │    التركيب          │                                │
│  │  ينشئ:              │                                │
│  │  - مجموعة الأمان    │                                │
│  │  - مجموعة الشبكات   │                                │
│  │  - مثيل RDS        │                                │
│  └──────────┬──────────┘                                │
│             │                                            │
│  4. مزود السحابة                                         │
│     │                                                    │
│     ▼                                                    │
│  ┌─────────────────────┐                                │
│  │       AWS           │                                │
│  │  RDS فعلي يُنشأ     │                                │
│  └──────────┬──────────┘                                │
│             │                                            │
│  5. سر الاتصال                                           │
│     │                                                    │
│     ▼                                                    │
│  ┌─────────────────────┐                                │
│  │       السر          │                                │
│  │  name: db-connection│                                │
│  │  namespace: team-x  │                                │
│  │  - endpoint         │                                │
│  │  - port             │                                │
│  │  - username         │                                │
│  │  - password         │                                │
│  └─────────────────────┘                                │
│                                                          │
│  الوقت: ~5 دقائق (مؤتمت بالكامل)                        │
│                                                          │
└─────────────────────────────────────────────────────────┘

مراقبة المطالبات

تتبع طلبات البنية التحتية:

# قائمة جميع المطالبات عبر مساحات الأسماء
kubectl get databases --all-namespaces

# فحص تفاصيل المطالبة
kubectl describe database orders-db -n team-orders

# عرض الأحداث
kubectl get events -n team-orders --field-selector involvedObject.name=orders-db

# فحص الموارد الأساسية
kubectl get managed -l crossplane.io/claim-namespace=team-orders

# مقاييس Prometheus (إذا تم تكوينها)
# crossplane_managed_resource_ready_total
# crossplane_managed_resource_synced_total

دورة حياة المطالبة

# عمليات دورة الحياة
lifecycle:

  update:
    description: "تعديل مواصفات المطالبة"
    example: "تغيير الحجم من small إلى medium"
    action: "Crossplane يحدث الموارد الأساسية"

  delete:
    description: "حذف المطالبة"
    behavior: "Crossplane يحذف جميع موارد السحابة المُنشأة"
    command: "kubectl delete database orders-db -n team-orders"

  orphan:
    description: "الإزالة من Crossplane دون حذف موارد السحابة"
    annotation: "crossplane.io/deletion-policy: Orphan"

في الوحدة التالية، سنستكشف GitOps وأنماط التسليم المستمر التي تكمل نهج البنية التحتية ذاتية الخدمة هذا. :::