Lietuvių

Išsami Kubernetes Operatorių apžvalga, paaiškinanti, kaip jie supaprastina ir automatizuoja sudėtingų programų bei individualių išteklių valdymą. Sužinokite, kaip kurti ir diegti savo Operatorius.

Kubernetes Operatoriai: Individualių Išteklių Valdymo Automatizavimas

Kubernetes sukėlė revoliuciją programų diegimo ir valdymo srityje. Tačiau sudėtingų, būseną išsaugančių (stateful) programų valdymas vis dar gali būti iššūkis. Būtent čia į pagalbą ateina Kubernetes Operatoriai, suteikiantys galingą būdą automatizuoti programų valdymą ir išplėsti Kubernetes galimybes.

Kas yra Kubernetes Operatoriai?

Kubernetes Operatorius yra specifinei programai skirtas valdiklis (controller), kuris išplečia Kubernetes API, kad galėtų valdyti sudėtingas programas. Įsivaizduokite jį kaip automatizuotą sistemos administratorių, specialiai pritaikytą konkrečiai programai. Operatoriai apima specifinės programos eksploatavimo srities žinias, leidžiančias ją valdyti deklaratyviai, automatizuotai ir pakartojamai.

Skirtingai nuo tradicinių Kubernetes valdiklių, kurie valdo pagrindinius išteklius, tokius kaip Pod'ai ir Service'ai, Operatoriai valdo individualius išteklius, apibrėžtus per Individualių Išteklių Apibrėžimus (Custom Resource Definitions – CRD). Tai leidžia jums apibrėžti savo, specifinius programai skirtus išteklius, ir leisti Kubernetes juos valdyti automatiškai.

Kodėl verta naudoti Kubernetes Operatorius?

Operatoriai siūlo keletą pagrindinių privalumų valdant sudėtingas programas:

Individualių Išteklių Apibrėžimų (CRD) supratimas

Individualių Išteklių Apibrėžimai (CRD) yra Kubernetes Operatorių pagrindas. CRD leidžia išplėsti Kubernetes API, apibrėžiant savo individualių išteklių tipus. Šie ištekliai traktuojami kaip bet kuris kitas Kubernetes išteklius, pavyzdžiui, Pod'ai ar Service'ai, ir gali būti valdomi naudojant `kubectl` bei kitus Kubernetes įrankius.

Štai kaip veikia CRD:

  1. Jūs apibrėžiate CRD, kuris nurodo jūsų individualaus ištekliaus schemą ir patvirtinimo taisykles.
  2. Jūs įdiegiate CRD į savo Kubernetes klasterį.
  3. Jūs sukuriate savo individualaus ištekliaus egzempliorius, nurodydami norimą konfigūraciją.
  4. Operatorius stebi šių individualių išteklių pakeitimus ir imasi veiksmų, kad suderintų norimą būseną su faktine būsena.

Pavyzdžiui, tarkime, norite valdyti duomenų bazės programą naudodami Operatorių. Galėtumėte apibrėžti CRD pavadinimu `Database` su laukais, tokiais kaip `name`, `version`, `storageSize` ir `replicas`. Tuomet Operatorius stebėtų `Database` išteklių pakeitimus ir atitinkamai sukurtų ar atnaujintų pagrindinius duomenų bazės egzempliorius.

Kaip veikia Kubernetes Operatoriai

Kubernetes Operatoriai veikia derindami Individualių Išteklių Apibrėžimus (CRD) su individualiais valdikliais. Valdiklis stebi individualių išteklių pakeitimus ir imasi veiksmų, kad suderintų norimą būseną su faktine. Šis procesas paprastai apima šiuos veiksmus:

  1. Įvykių stebėjimas: Operatorius stebi su individualiais ištekliais susijusius įvykius, tokius kaip sukūrimas, ištrynimas ar atnaujinimas.
  2. Būsenos derinimas (Reconciling): Įvykus įvykiui, Operatorius derina programos būseną. Tai apima norimos būsenos (apibrėžtos Individualiame Ištekliuje) palyginimą su faktine būsena ir veiksmų, skirtų jas suderinti, ėmimąsi.
  3. Išteklių valdymas: Operatorius kuria, atnaujina arba trina Kubernetes išteklius (Pod'us, Service'us, Deployment'us ir kt.), kad pasiektų norimą būseną.
  4. Klaidų tvarkymas: Operatorius tvarko klaidas ir bando iš naujo atlikti nepavykusius veiksmus, kad užtikrintų, jog programa išliks nuoseklioje būsenoje.
  5. Grįžtamojo ryšio teikimas: Operatorius teikia grįžtamąjį ryšį apie programos būseną, pavyzdžiui, sveikatos patikras ir išteklių naudojimą.

Derinimo ciklas (reconcile loop) yra Operatoriaus logikos branduolys. Jis nuolat stebi programos būseną ir imasi veiksmų, kad palaikytų norimą būseną. Šis ciklas paprastai įgyvendinamas naudojant derinimo funkciją, kuri atlieka reikiamas operacijas.

Savo Kubernetes Operatoriaus kūrimas

Yra keletas įrankių ir karkasų, kurie gali padėti jums kurti Kubernetes Operatorius:

Štai supaprastinta Operatoriaus kūrimo su Operator Framework apžvalga:

  1. Apibrėžkite Individualaus Išteklių Apibrėžimą (CRD): Sukurkite CRD, kuris aprašo norimą jūsų programos būseną. Tai apibrėš jūsų individualaus ištekliaus schemą ir patvirtinimo taisykles.
  2. Generuokite Operatoriaus kodą: Naudokite Operator SDK, kad sugeneruotumėte pradinį Operatoriaus kodą, remiantis jūsų CRD. Tai sukurs reikiamus valdiklius ir išteklių apibrėžimus.
  3. Įgyvendinkite derinimo logiką: Įgyvendinkite derinimo logiką, kuri lygina norimą būseną (apibrėžtą Individualiame Ištekliuje) su faktine būsena ir imasi veiksmų joms suderinti. Tai yra jūsų Operatoriaus funkcionalumo branduolys.
  4. Sukurkite ir įdiekite Operatorių: Sukurkite Operatoriaus atvaizdą (image) ir įdiekite jį į savo Kubernetes klasterį.
  5. Testuokite ir tobulinkite: Kruopščiai testuokite savo Operatorių ir tobulinkite kodą, kad pagerintumėte jo funkcionalumą ir patikimumą.

Pailiustruokime tai paprastu pavyzdžiu naudojant Operator Framework. Tarkime, norite sukurti Operatorių, kuris valdo paprastą `Memcached` diegimą.

1. Apibrėžkite CRD:

Sukurkite `memcached.yaml` failą su šiuo CRD apibrėžimu:


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"]

Šis CRD apibrėžia `Memcached` išteklių su `size` lauku, kuris nurodo, kiek `Memcached` egzempliorių reikia paleisti.

2. Generuokite Operatoriaus kodą:

Naudokite Operator SDK, kad sugeneruotumėte pradinį Operatoriaus kodą:


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

Tai sugeneruos reikiamus failus ir katalogus jūsų Operatoriui, įskaitant valdiklio kodą ir išteklių apibrėžimus.

3. Įgyvendinkite derinimo logiką:

Redaguokite `controllers/memcached_controller.go` failą, kad įgyvendintumėte derinimo logiką. Ši funkcija kurs, atnaujins arba trins `Memcached` diegimus, remiantis norima būsena, apibrėžta `Memcached` ištekliuje.


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

	// Gauname Memcached egzempliorių
	memcached := &cachev1alpha1.Memcached{}
	err := r.Get(ctx, req.NamespacedName, memcached)
	if err != nil {
		if errors.IsNotFound(err) {
			// Užklausos objektas nerastas, galėjo būti ištrintas po derinimo užklausos.
			// Priklausantys objektai automatiškai surenkami šiukšlių rinkiklio. Papildomai valymo logikai naudokite finalizatorius.
			// Grįžtame ir nededame į eilę iš naujo
			log.Info("Memcached išteklius nerastas. Ignoruojama, nes objektas tikriausiai buvo ištrintas")
			return ctrl.Result{}, nil
		}
		// Klaida skaitant objektą - dedame užklausą į eilę iš naujo.
		log.Error(err, "Nepavyko gauti Memcached")
		return ctrl.Result{}, err
	}

	// Apibrėžiame naują Deployment objektą
	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,
								},
							},
						},
					},
				},
			},
		},
	}

	// Nustatome Memcached egzempliorių kaip savininką ir valdiklį
	if err := ctrl.SetControllerReference(memcached, deployment, r.Scheme);
		err != nil {
			log.Error(err, "Nepavyko nustatyti valdiklio nuorodos")
			return ctrl.Result{}, err
	}

	// Patikriname, ar šis Deployment jau egzistuoja
	found := &appsv1.Deployment{}
	err = r.Get(ctx, types.NamespacedName{
		Name:      deployment.Name,
		Namespace: deployment.Namespace,
	}, found)
	if err != nil && errors.IsNotFound(err) {
		log.Info("Kuriama nauja Deployment", "Deployment.Namespace", deployment.Namespace, "Deployment.Name", deployment.Name)
		err = r.Create(ctx, deployment)
		if err != nil {
			log.Error(err, "Nepavyko sukurti naujos Deployment", "Deployment.Namespace", deployment.Namespace, "Deployment.Name", deployment.Name)
			return ctrl.Result{}, err
		}

		// Deployment sėkmingai sukurtas - grįžtame ir dedame į eilę iš naujo
		return ctrl.Result{Requeue: true}, nil
	} else if err != nil {
		log.Error(err, "Nepavyko gauti Deployment")
		return ctrl.Result{}, err
	}

	// Užtikriname, kad diegimo dydis atitinka specifikaciją
	size := memcached.Spec.Size
	if *found.Spec.Replicas != size {
		log.Info("Atnaujinama Deployment", "Deployment.Namespace", deployment.Namespace, "Deployment.Name", deployment.Name)
		found.Spec.Replicas = &size
		err = r.Update(ctx, found)
		if err != nil {
			log.Error(err, "Nepavyko atnaujinti Deployment", "Deployment.Namespace", deployment.Namespace, "Deployment.Name", deployment.Name)
			return ctrl.Result{}, err
		}
		// Specifikacija atnaujinta - grįžtame ir dedame į eilę iš naujo
		return ctrl.Result{Requeue: true}, nil
	}

	// Deployment jau egzistuoja - nededame į eilę iš naujo
	log.Info("Praleidžiamas derinimas: Deployment jau egzistuoja", "Deployment.Namespace", deployment.Namespace, "Deployment.Name", deployment.Name)
	return ctrl.Result{}, nil
}

Šis pavyzdys yra labai supaprastinta derinimo logikos versija. Produkcinei aplinkai paruoštas Operatorius reikalautų patikimesnio klaidų tvarkymo, registravimo ir konfigūravimo parinkčių.

4. Sukurkite ir įdiekite Operatorių:

Sukurkite Operatoriaus atvaizdą ir įdiekite jį į savo Kubernetes klasterį naudodami `make deploy`.

5. Sukurkite Memcached išteklių:

Sukurkite `memcached-instance.yaml` failą su šiuo turiniu:


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

Pritaikykite šį failą savo klasteriui naudodami `kubectl apply -f memcached-instance.yaml`.

Dabar Operatorius sukurs Deployment su 3 `Memcached` egzemplioriais.

Geriausios Kubernetes Operatorių kūrimo praktikos

Efektyvių Kubernetes Operatorių kūrimas reikalauja kruopštaus planavimo ir vykdymo. Štai keletas geriausių praktikų, kurias reikėtų prisiminti:

Realūs Kubernetes Operatorių pavyzdžiai

Daugelis organizacijų naudoja Kubernetes Operatorius, kad valdytų sudėtingas programas produkcinėje aplinkoje. Štai keletas pavyzdžių:

Tai tik keli iš daugelio galimų Kubernetes Operatorių pavyzdžių. Kubernetes pritaikymui toliau augant, galime tikėtis, kad atsiras dar daugiau Operatorių, kurie supaprastins vis platesnio spektro programų valdymą.

Saugumo aspektai kuriant Kubernetes Operatorius

Kubernetes Operatoriams, kaip ir bet kuriai Kubernetes klasteryje veikiančiai programai, reikia atidžiai apsvarstyti saugumo klausimus. Kadangi Operatoriai dažnai turi padidintas privilegijas valdyti klasterio išteklius, labai svarbu įdiegti tinkamas saugumo priemones, siekiant išvengti neautorizuotos prieigos ir kenkėjiškos veiklos.

Štai keletas pagrindinių saugumo aspektų, susijusių su Kubernetes Operatoriais:

Įgyvendindami šias saugumo priemones, galite žymiai sumažinti saugumo pažeidimų riziką ir apsaugoti savo Kubernetes Operatorius nuo kenkėjiškos veiklos.

Kubernetes Operatorių ateitis

Kubernetes Operatoriai sparčiai vystosi ir tampa vis svarbesne Kubernetes ekosistemos dalimi. Kubernetes pritaikymui toliau augant, galime tikėtis dar daugiau inovacijų Operatorių srityje.

Štai keletas tendencijų, kurios formuoja Kubernetes Operatorių ateitį:

Išvada

Kubernetes Operatoriai suteikia galingą būdą automatizuoti sudėtingų programų valdymą ir išplėsti Kubernetes galimybes. Apibrėždami individualius išteklius ir įgyvendindami individualius valdiklius, Operatoriai leidžia jums valdyti programas deklaratyviu, automatizuotu ir pakartojamu būdu. Kubernetes pritaikymui toliau augant, Operatoriai taps vis svarbesne debesijos (cloud-native) kraštovaizdžio dalimi.

Pasinaudodamos Kubernetes Operatoriais, organizacijos gali supaprastinti programų valdymą, sumažinti veiklos sąnaudas ir pagerinti bendrą savo programų patikimumą bei mastelio keitimo galimybes. Nesvarbu, ar valdote duomenų bazes, stebėjimo sistemas ar kitas sudėtingas programas, Kubernetes Operatoriai gali padėti jums optimizuoti operacijas ir atskleisti visą Kubernetes potencialą.

Tai yra besivystanti sritis, todėl norint efektyviai išnaudoti Kubernetes Operatorius savo organizacijoje, būtina sekti naujausius pokyčius ir geriausias praktikas. Operatorių bendruomenė yra gyvybinga ir palaikanti, siūlanti gausybę išteklių ir patirties, padėsiančios jums pasiekti sėkmę.