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

التركيبات وتعريفات الموارد المركبة

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

التركيبات وتعريفات الموارد المركبة (XRDs) هي طبقة التجريد في Crossplane. تسمح لفرق المنصة بإنشاء واجهات برمجية مبسطة ومُحددة الرأي تخفي تعقيد السحابة عن المطورين.

تحدي التجريد

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

بدون التركيبات:
┌─────────────────────────────────────────────────────────┐
│  المطور: "أحتاج قاعدة بيانات PostgreSQL"                │
│                                                          │
│  يجب أن يفهم:                                           │
│  ├── تكوين VPC                                          │
│  ├── وضع الشبكة الفرعية                                 │
│  ├── مجموعات الأمان                                     │
│  ├── أدوار IAM                                          │
│  ├── معلمات مثيل RDS                                    │
│  ├── مجموعات المعلمات                                   │
│  ├── مجموعات الشبكات الفرعية                            │
│  └── إعدادات التشفير                                    │
│                                                          │
│  النتيجة: 200+ سطر من YAML                               │
└─────────────────────────────────────────────────────────┘

مع التركيبات:
┌─────────────────────────────────────────────────────────┐
│  المطور: "أحتاج قاعدة بيانات PostgreSQL"                │
│                                                          │
│  apiVersion: platform.acme.com/v1alpha1                 │
│  kind: Database                                          │
│  metadata:                                               │
│    name: my-db                                           │
│  spec:                                                   │
│    size: small                                           │
│    engine: postgres                                      │
│                                                          │
│  النتيجة: 8 أسطر من YAML                                 │
└─────────────────────────────────────────────────────────┘

فهم XRDs والتركيبات

┌─────────────────────────────────────────────────────────┐
│                    فريق المنصة                           │
│                                                          │
│  ينشئ:                                                   │
│  ┌─────────────────────────────────────────────────┐    │
│  │  XRD (تعريف المورد المركب)                      │    │
│  │  - يحدد مخطط API                                │    │
│  │  - ما المعلمات التي يمكن للمطورين تعيينها       │    │
│  │  - مثال: "Database" مع size, engine             │    │
│  └─────────────────────────────────────────────────┘    │
│                          │                               │
│  ┌─────────────────────────────────────────────────┐    │
│  │  Composition (التركيب)                          │    │
│  │  - تفاصيل التنفيذ                               │    │
│  │  - يربط معلمات XRD بموارد السحابة              │    │
│  │  - مثال: "small" → db.t3.micro + 20GB          │    │
│  └─────────────────────────────────────────────────┘    │
│                                                          │
├─────────────────────────────────────────────────────────┤
│                       المطور                             │
│                                                          │
│  ينشئ:                                                   │
│  ┌─────────────────────────────────────────────────┐    │
│  │  Claim (المطالبة) أو Composite Resource         │    │
│  │  - يستخدم API المبسط                            │    │
│  │  - فقط يحدد: size=small, engine=postgres        │    │
│  └─────────────────────────────────────────────────┘    │
│                                                          │
└─────────────────────────────────────────────────────────┘

إنشاء XRD

حدد API قاعدة بيانات منصتك:

# xrd-database.yaml
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
  name: xdatabases.platform.acme.com
spec:
  group: platform.acme.com
  names:
    kind: XDatabase
    plural: xdatabases
  claimNames:
    kind: Database
    plural: databases
  versions:
    - name: v1alpha1
      served: true
      referenceable: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                size:
                  type: string
                  enum: ["small", "medium", "large"]
                  description: "طبقة حجم قاعدة البيانات"
                engine:
                  type: string
                  enum: ["postgres", "mysql"]
                  default: "postgres"
                  description: "محرك قاعدة البيانات"
                version:
                  type: string
                  default: "15"
                  description: "إصدار المحرك"
                storageGB:
                  type: integer
                  minimum: 20
                  maximum: 1000
                  default: 20
                  description: "حجم التخزين بالجيجابايت"
              required:
                - size
            status:
              type: object
              properties:
                endpoint:
                  type: string
                port:
                  type: integer
                status:
                  type: string

إنشاء تركيب

تنفيذ تجريد قاعدة البيانات:

# composition-database-aws.yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: database-aws
  labels:
    provider: aws
    engine: postgres
spec:
  compositeTypeRef:
    apiVersion: platform.acme.com/v1alpha1
    kind: XDatabase

  writeConnectionSecretsToNamespace: crossplane-system

  patchSets:
    - name: common-tags
      patches:
        - type: FromCompositeFieldPath
          fromFieldPath: metadata.labels
          toFieldPath: spec.forProvider.tags
          policy:
            mergeOptions:
              appendSlice: true

  resources:
    # مجموعة الأمان
    - name: security-group
      base:
        apiVersion: ec2.aws.upbound.io/v1beta1
        kind: SecurityGroup
        spec:
          forProvider:
            region: us-east-1
            description: "مجموعة أمان قاعدة البيانات"
            vpcId: vpc-0123456789abcdef0
            ingress:
              - fromPort: 5432
                toPort: 5432
                protocol: tcp
                cidrBlocks:
                  - 10.0.0.0/16
      patches:
        - type: FromCompositeFieldPath
          fromFieldPath: metadata.name
          toFieldPath: metadata.name
          transforms:
            - type: string
              string:
                fmt: "%s-sg"

    # مجموعة الشبكات الفرعية
    - name: subnet-group
      base:
        apiVersion: rds.aws.upbound.io/v1beta1
        kind: SubnetGroup
        spec:
          forProvider:
            region: us-east-1
            description: "مجموعة الشبكات الفرعية لقاعدة البيانات"
            subnetIds:
              - subnet-0123456789abcdef0
              - subnet-0123456789abcdef1
      patches:
        - type: FromCompositeFieldPath
          fromFieldPath: metadata.name
          toFieldPath: metadata.name
          transforms:
            - type: string
              string:
                fmt: "%s-subnet-group"

    # مثيل RDS
    - name: rds-instance
      base:
        apiVersion: rds.aws.upbound.io/v1beta1
        kind: Instance
        spec:
          forProvider:
            region: us-east-1
            engine: postgres
            publiclyAccessible: false
            skipFinalSnapshot: true
            storageEncrypted: true
            storageType: gp3
            autoMinorVersionUpgrade: true
            backupRetentionPeriod: 7
            username: dbadmin
          writeConnectionSecretToRef:
            namespace: crossplane-system
      patches:
        # الاسم
        - type: FromCompositeFieldPath
          fromFieldPath: metadata.name
          toFieldPath: metadata.name

        # معرف المثيل
        - type: FromCompositeFieldPath
          fromFieldPath: metadata.name
          toFieldPath: spec.forProvider.instanceIdentifier

        # اسم قاعدة البيانات
        - type: FromCompositeFieldPath
          fromFieldPath: metadata.name
          toFieldPath: spec.forProvider.dbName
          transforms:
            - type: string
              string:
                type: Convert
                convert: ToLower
            - type: string
              string:
                type: Regexp
                regexp:
                  match: "-"
                  replace: "_"

        # إصدار المحرك
        - type: FromCompositeFieldPath
          fromFieldPath: spec.version
          toFieldPath: spec.forProvider.engineVersion

        # التخزين
        - type: FromCompositeFieldPath
          fromFieldPath: spec.storageGB
          toFieldPath: spec.forProvider.allocatedStorage

        # تعيين الحجم (small/medium/large → فئة المثيل)
        - type: FromCompositeFieldPath
          fromFieldPath: spec.size
          toFieldPath: spec.forProvider.dbInstanceClass
          transforms:
            - type: map
              map:
                small: db.t3.micro
                medium: db.t3.medium
                large: db.r6g.large

        # مرجع مجموعة الأمان
        - type: FromCompositeFieldPath
          fromFieldPath: metadata.name
          toFieldPath: spec.forProvider.vpcSecurityGroupIdRefs[0].name
          transforms:
            - type: string
              string:
                fmt: "%s-sg"

        # مرجع مجموعة الشبكات الفرعية
        - type: FromCompositeFieldPath
          fromFieldPath: metadata.name
          toFieldPath: spec.forProvider.dbSubnetGroupNameRef.name
          transforms:
            - type: string
              string:
                fmt: "%s-subnet-group"

        # سر الاتصال
        - type: FromCompositeFieldPath
          fromFieldPath: metadata.name
          toFieldPath: spec.writeConnectionSecretToRef.name
          transforms:
            - type: string
              string:
                fmt: "%s-connection"

        # كتابة نقطة النهاية إلى الحالة
        - type: ToCompositeFieldPath
          fromFieldPath: status.atProvider.endpoint
          toFieldPath: status.endpoint

        # كتابة المنفذ إلى الحالة
        - type: ToCompositeFieldPath
          fromFieldPath: status.atProvider.port
          toFieldPath: status.port

      connectionDetails:
        - name: endpoint
          fromFieldPath: status.atProvider.endpoint
        - name: port
          fromFieldPath: status.atProvider.port
        - name: username
          fromFieldPath: spec.forProvider.username
        - name: password
          fromConnectionSecretKey: attribute.password

تطبيق XRD والتركيب

# تطبيق XRD أولاً
kubectl apply -f xrd-database.yaml

# انتظار إنشاء XRD
kubectl wait xrd xdatabases.platform.acme.com --for=condition=Established

# تطبيق التركيب
kubectl apply -f composition-database-aws.yaml

# التحقق
kubectl get xrd
kubectl get composition

أنواع الترقيعات

التركيبات تستخدم الترقيعات لتحويل وربط البيانات:

# مرجع أنواع الترقيعات
patches:

  # نسخ القيمة من المركب إلى المورد
  - type: FromCompositeFieldPath
    fromFieldPath: spec.size
    toFieldPath: spec.forProvider.instanceClass

  # نسخ القيمة من المورد إلى حالة المركب
  - type: ToCompositeFieldPath
    fromFieldPath: status.atProvider.endpoint
    toFieldPath: status.endpoint

  # تحويل القيم
  - type: FromCompositeFieldPath
    fromFieldPath: spec.size
    toFieldPath: spec.forProvider.instanceClass
    transforms:
      - type: map
        map:
          small: db.t3.micro
          medium: db.t3.medium
          large: db.r6g.large

  # تنسيق النص
  - type: FromCompositeFieldPath
    fromFieldPath: metadata.name
    toFieldPath: spec.forProvider.bucketName
    transforms:
      - type: string
        string:
          fmt: "acme-%s-bucket"

  # دمج حقول متعددة
  - type: CombineFromComposite
    combine:
      variables:
        - fromFieldPath: spec.region
        - fromFieldPath: metadata.name
      strategy: string
      string:
        fmt: "%s-%s"
    toFieldPath: spec.forProvider.instanceIdentifier

تركيبات متعددة

إنشاء تنفيذات مختلفة لنفس XRD:

# composition-database-aws.yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: database-aws
  labels:
    provider: aws
spec:
  compositeTypeRef:
    apiVersion: platform.acme.com/v1alpha1
    kind: XDatabase
  # ... تنفيذ AWS

---
# composition-database-gcp.yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: database-gcp
  labels:
    provider: gcp
spec:
  compositeTypeRef:
    apiVersion: platform.acme.com/v1alpha1
    kind: XDatabase
  # ... تنفيذ GCP مع CloudSQL
# اختيار التركيب عبر compositionSelector
apiVersion: platform.acme.com/v1alpha1
kind: Database
metadata:
  name: my-database
spec:
  compositionSelector:
    matchLabels:
      provider: aws  # يستخدم تركيب database-aws
  size: small
  engine: postgres

في الدرس التالي، سنجمع كل شيء معًا مع مطالبات البنية التحتية ذاتية الخدمة وتكامل Backstage. :::