توفير البنية التحتية مع 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 وأنماط التسليم المستمر التي تكمل نهج البنية التحتية ذاتية الخدمة هذا. :::