العربية

نظرة معمقة على عوامل تشغيل Kubernetes، وشرح كيفية تبسيط وأتمتة إدارة التطبيقات المعقدة والموارد المخصصة. تعلم كيفية بناء ونشر عوامل التشغيل الخاصة بك.

عوامل تشغيل Kubernetes: أتمتة إدارة الموارد المخصصة

لقد أحدث Kubernetes ثورة في طريقة نشرنا وإدارتنا للتطبيقات. ومع ذلك، لا تزال إدارة التطبيقات المعقدة وذات الحالة (stateful) تمثل تحديًا. وهنا يأتي دور عوامل تشغيل Kubernetes، حيث توفر طريقة قوية لأتمتة إدارة التطبيقات وتوسيع قدرات Kubernetes.

ما هي عوامل تشغيل Kubernetes؟

عامل تشغيل Kubernetes هو وحدة تحكم خاصة بالتطبيق تعمل على توسيع واجهة برمجة تطبيقات Kubernetes (API) لإدارة التطبيقات المعقدة. فكر فيه كمسؤول نظام آلي، مصمم خصيصًا لتطبيق معين. تغلف عوامل التشغيل المعرفة المتخصصة بتشغيل تطبيق معين، مما يتيح لك إدارته بطريقة تعريفية وآلية وقابلة للتكرار.

على عكس وحدات تحكم Kubernetes التقليدية، التي تدير الموارد الأساسية مثل Pods و Services، تدير عوامل التشغيل موارد مخصصة تم تعريفها من خلال تعريفات الموارد المخصصة (CRDs). يتيح لك هذا تحديد مواردك الخاصة بالتطبيق وجعل Kubernetes يديرها تلقائيًا.

لماذا نستخدم عوامل تشغيل Kubernetes؟

تقدم عوامل التشغيل العديد من الفوائد الرئيسية لإدارة التطبيقات المعقدة:

فهم تعريفات الموارد المخصصة (CRDs)

تُعد تعريفات الموارد المخصصة (CRDs) أساس عوامل تشغيل Kubernetes. تسمح لك CRDs بتوسيع واجهة برمجة تطبيقات Kubernetes عن طريق تحديد أنواع الموارد المخصصة الخاصة بك. يتم التعامل مع هذه الموارد مثل أي مورد آخر في Kubernetes، مثل Pods أو Services، ويمكن إدارتها باستخدام `kubectl` وأدوات Kubernetes الأخرى.

إليك كيفية عمل CRDs:

  1. تقوم بتعريف CRD يحدد المخطط وقواعد التحقق من الصحة لموردك المخصص.
  2. تقوم بنشر CRD إلى مجموعة Kubernetes الخاصة بك.
  3. تقوم بإنشاء مثيلات من موردك المخصص، وتحديد التكوين المطلوب.
  4. يراقب عامل التشغيل التغييرات التي تطرأ على هذه الموارد المخصصة ويتخذ الإجراءات اللازمة لمطابقة الحالة المرغوبة مع الحالة الفعلية.

على سبيل المثال، لنفترض أنك تريد إدارة تطبيق قاعدة بيانات باستخدام عامل تشغيل. يمكنك تحديد CRD يسمى `Database` بحقول مثل `name` و `version` و `storageSize` و `replicas`. سيقوم عامل التشغيل بعد ذلك بمراقبة التغييرات على موارد `Database` وإنشاء أو تحديث مثيلات قاعدة البيانات الأساسية وفقًا لذلك.

كيف تعمل عوامل تشغيل Kubernetes

تعمل عوامل تشغيل Kubernetes من خلال الجمع بين تعريفات الموارد المخصصة (CRDs) ووحدات التحكم المخصصة. تراقب وحدة التحكم التغييرات التي تطرأ على الموارد المخصصة وتتخذ الإجراءات اللازمة لمطابقة الحالة المرغوبة مع الحالة الفعلية. تتضمن هذه العملية عادةً الخطوات التالية:

  1. مراقبة الأحداث: يراقب عامل التشغيل الأحداث المتعلقة بالموارد المخصصة، مثل الإنشاء أو الحذف أو التحديثات.
  2. مطابقة الحالة: عند وقوع حدث، يقوم عامل التشغيل بمطابقة حالة التطبيق. يتضمن ذلك مقارنة الحالة المرغوبة (المحددة في المورد المخصص) مع الحالة الفعلية واتخاذ الإجراءات لتحقيق التوافق بينهما.
  3. إدارة الموارد: يقوم عامل التشغيل بإنشاء أو تحديث أو حذف موارد Kubernetes (Pods, Services, Deployments, إلخ) لتحقيق الحالة المرغوبة.
  4. معالجة الأخطاء: يعالج عامل التشغيل الأخطاء ويعيد محاولة العمليات الفاشلة لضمان بقاء التطبيق في حالة متسقة.
  5. توفير التغذية الراجعة: يوفر عامل التشغيل تغذية راجعة حول حالة التطبيق، مثل فحوصات الصحة واستخدام الموارد.

حلقة المطابقة (reconcile loop) هي جوهر منطق عامل التشغيل. فهي تراقب باستمرار حالة التطبيق وتتخذ الإجراءات اللازمة للحفاظ على الحالة المرغوبة. يتم تنفيذ هذه الحلقة عادةً باستخدام دالة مطابقة تقوم بالعمليات اللازمة.

بناء عامل تشغيل Kubernetes الخاص بك

تساعد العديد من الأدوات والأطر في بناء عوامل تشغيل Kubernetes:

فيما يلي نظرة عامة مبسطة على الخطوات المتبعة في بناء عامل تشغيل باستخدام Operator Framework:

  1. تعريف تعريف المورد المخصص (CRD): قم بإنشاء CRD يصف الحالة المرغوبة لتطبيقك. سيحدد هذا المخطط وقواعد التحقق من الصحة لموردك المخصص.
  2. توليد كود عامل التشغيل: استخدم Operator SDK لتوليد كود عامل التشغيل الأولي بناءً على CRD الخاص بك. سيؤدي هذا إلى إنشاء وحدات التحكم وتعريفات الموارد اللازمة.
  3. تنفيذ منطق المطابقة: قم بتنفيذ منطق المطابقة الذي يقارن الحالة المرغوبة (المحددة في المورد المخصص) مع الحالة الفعلية ويتخذ الإجراءات اللازمة لتحقيق التوافق بينهما. هذا هو جوهر وظائف عامل التشغيل الخاص بك.
  4. بناء ونشر عامل التشغيل: قم ببناء صورة عامل التشغيل ونشرها في مجموعة Kubernetes الخاصة بك.
  5. الاختبار والتكرار: اختبر عامل التشغيل الخاص بك جيدًا وكرر العمل على الكود لتحسين وظائفه وموثوقيته.

دعنا نوضح بمثال أساسي باستخدام Operator Framework. لنفترض أنك تريد إنشاء عامل تشغيل يدير نشر `Memcached` بسيط.

1. تعريف CRD:

أنشئ ملف `memcached.yaml` بالتعريف التالي لـ CRD:


apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: memcacheds.cache.example.com
spec:
  group: cache.example.com
  versions:
    - name: v1alpha1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                size:
                  type: integer
                  description: Size is the number of Memcached instances
              required: ["size"]
  scope: Namespaced
  names:
    plural: memcacheds
    singular: memcached
    kind: Memcached
    shortNames: ["mc"]

يحدد هذا CRD مورد `Memcached` بحقل `size` الذي يحدد عدد مثيلات Memcached التي سيتم تشغيلها.

2. توليد كود عامل التشغيل:

استخدم Operator SDK لتوليد كود عامل التشغيل الأولي:


operator-sdk init --domain=example.com --repo=github.com/example/memcached-operator
operator-sdk create api --group=cache --version=v1alpha1 --kind=Memcached --resource --controller

سيؤدي هذا إلى إنشاء الملفات والمجلدات اللازمة لعامل التشغيل الخاص بك، بما في ذلك كود وحدة التحكم وتعريفات الموارد.

3. تنفيذ منطق المطابقة:

قم بتحرير ملف `controllers/memcached_controller.go` لتنفيذ منطق المطابقة. ستقوم هذه الدالة بإنشاء أو تحديث أو حذف عمليات نشر Memcached بناءً على الحالة المرغوبة المحددة في مورد `Memcached`.


func (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
	log := r.Log.WithValues("memcached", req.NamespacedName)

	// Fetch the Memcached instance
	memcached := &cachev1alpha1.Memcached{}
	err := r.Get(ctx, req.NamespacedName, memcached)
	if err != nil {
		if errors.IsNotFound(err) {
			// Request object not found, could have been deleted after reconcile request.
			// Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
			// Return and don't requeue
			log.Info("Memcached resource not found. Ignoring since object must be deleted")
			return ctrl.Result{}, nil
		}
		// Error reading the object - requeue the request.
		log.Error(err, "Failed to get Memcached")
		return ctrl.Result{}, err
	}

	// Define a new Deployment object
	deployment := &appsv1.Deployment{
		ObjectMeta: metav1.ObjectMeta{
			Name:      memcached.Name,
			Namespace: memcached.Namespace,
		},
		Spec: appsv1.DeploymentSpec{
			Replicas: &memcached.Spec.Size,
			Selector: &metav1.LabelSelector{
				MatchLabels: map[string]string{
					"app": memcached.Name,
				},
			},
			Template: corev1.PodTemplateSpec{
				ObjectMeta: metav1.ObjectMeta{
					Labels: map[string]string{
						"app": memcached.Name,
					},
				},
				Spec: corev1.PodSpec{
					Containers: []corev1.Container{
						{
							Name:  "memcached",
							Image: "memcached:1.6.17-alpine",
							Ports: []corev1.ContainerPort{
								{
									ContainerPort: 11211,
								},
							},
						},
					},
				},
			},
		},
	}

	// Set Memcached instance as the owner and controller
	if err := ctrl.SetControllerReference(memcached, deployment, r.Scheme);
		err != nil {
			log.Error(err, "Failed to set controller reference")
			return ctrl.Result{}, err
	}

	// Check if this Deployment already exists
	found := &appsv1.Deployment{}
	err = r.Get(ctx, types.NamespacedName{
		Name:      deployment.Name,
		Namespace: deployment.Namespace,
	}, found)
	if err != nil && errors.IsNotFound(err) {
		log.Info("Creating a new Deployment", "Deployment.Namespace", deployment.Namespace, "Deployment.Name", deployment.Name)
		err = r.Create(ctx, deployment)
		if err != nil {
			log.Error(err, "Failed to create new Deployment", "Deployment.Namespace", deployment.Namespace, "Deployment.Name", deployment.Name)
			return ctrl.Result{}, err
		}

		// Deployment created successfully - return and requeue
		return ctrl.Result{Requeue: true}, nil
	} else if err != nil {
		log.Error(err, "Failed to get Deployment")
		return ctrl.Result{}, err
	}

	// Ensure the deployment size is the same as the spec
	size := memcached.Spec.Size
	if *found.Spec.Replicas != size {
		log.Info("Updating Deployment", "Deployment.Namespace", deployment.Namespace, "Deployment.Name", deployment.Name)
		found.Spec.Replicas = &size
		err = r.Update(ctx, found)
		if err != nil {
			log.Error(err, "Failed to update Deployment", "Deployment.Namespace", deployment.Namespace, "Deployment.Name", deployment.Name)
			return ctrl.Result{}, err
		}
		// Spec updated - return and requeue
		return ctrl.Result{Requeue: true}, nil
	}

	// Deployment already exists - don't requeue
	log.Info("Skip reconcile: Deployment already exists", "Deployment.Namespace", deployment.Namespace, "Deployment.Name", deployment.Name)
	return ctrl.Result{}, nil
}

هذا المثال هو نسخة مبسطة جدًا من منطق المطابقة. سيحتاج عامل التشغيل الجاهز للإنتاج إلى معالجة أخطاء وتسجيل وخيارات تكوين أكثر قوة.

4. بناء ونشر عامل التشغيل:

قم ببناء صورة عامل التشغيل ونشرها في مجموعة Kubernetes الخاصة بك باستخدام `make deploy`.

5. إنشاء مورد Memcached:

أنشئ ملف `memcached-instance.yaml` بالمحتوى التالي:


apiVersion: cache.example.com/v1alpha1
kind: Memcached
metadata:
  name: memcached-sample
spec:
  size: 3

طبق هذا الملف على مجموعتك باستخدام `kubectl apply -f memcached-instance.yaml`.

سيقوم عامل التشغيل الآن بإنشاء Deployment بثلاثة مثيلات من Memcached.

أفضل الممارسات لتطوير عوامل تشغيل Kubernetes

يتطلب تطوير عوامل تشغيل Kubernetes فعالة تخطيطًا وتنفيذًا دقيقين. فيما يلي بعض أفضل الممارسات التي يجب وضعها في الاعتبار:

أمثلة من العالم الحقيقي لعوامل تشغيل Kubernetes

تستخدم العديد من المنظمات عوامل تشغيل Kubernetes لإدارة التطبيقات المعقدة في بيئة الإنتاج. فيما يلي بعض الأمثلة:

هذه مجرد أمثلة قليلة من العديد من عوامل تشغيل Kubernetes المتاحة. مع استمرار نمو اعتماد Kubernetes، يمكننا أن نتوقع ظهور المزيد من عوامل التشغيل، مما يبسط إدارة مجموعة أوسع من التطبيقات.

اعتبارات أمنية لعوامل تشغيل Kubernetes

تتطلب عوامل تشغيل Kubernetes، مثل أي تطبيق يعمل في مجموعة Kubernetes، اعتبارات أمنية دقيقة. نظرًا لأن عوامل التشغيل غالبًا ما تتمتع بامتيازات عالية لإدارة موارد المجموعة، فمن الأهمية بمكان تنفيذ تدابير أمنية مناسبة لمنع الوصول غير المصرح به والأنشطة الخبيثة.

فيما يلي بعض الاعتبارات الأمنية الرئيسية لعوامل تشغيل Kubernetes:

من خلال تنفيذ هذه التدابير الأمنية، يمكنك تقليل مخاطر الخروقات الأمنية بشكل كبير وحماية عوامل تشغيل Kubernetes الخاصة بك من الأنشطة الخبيثة.

مستقبل عوامل تشغيل Kubernetes

تتطور عوامل تشغيل Kubernetes بسرعة وتصبح جزءًا متزايد الأهمية من نظام Kubernetes البيئي. مع استمرار نمو اعتماد Kubernetes، يمكننا أن نتوقع رؤية المزيد من الابتكار في مجال عوامل التشغيل.

فيما يلي بعض الاتجاهات التي تشكل مستقبل عوامل تشغيل Kubernetes:

الخلاصة

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

من خلال تبني عوامل تشغيل Kubernetes، يمكن للمنظمات تبسيط إدارة التطبيقات، وتقليل العبء التشغيلي، وتحسين الموثوقية وقابلية التوسع الإجمالية لتطبيقاتها. سواء كنت تدير قواعد بيانات أو أنظمة مراقبة أو تطبيقات معقدة أخرى، يمكن لعوامل تشغيل Kubernetes مساعدتك في تبسيط عملياتك وإطلاق العنان للإمكانات الكاملة لـ Kubernetes.

هذا مجال متطور، لذا فإن البقاء على اطلاع بأحدث التطورات وأفضل الممارسات أمر حاسم للاستفادة بفعالية من عوامل تشغيل Kubernetes في مؤسستك. المجتمع المحيط بعوامل التشغيل نابض بالحياة وداعم، ويقدم ثروة من الموارد والخبرات لمساعدتك على النجاح.

عوامل تشغيل Kubernetes: أتمتة إدارة الموارد المخصصة | MLOG