Letztes Jahr habe ich begonnen, mit kubebuilder Operatoren für eine Vielzahl von Dingen zu erstellen. Bei allen Operatoren habe ich Bedingungen ausgiebig genutzt, um jeden Schritt eines Abstimmungsprozesses für eine benutzerdefinierte Ressource zu verwalten.
Leider machten die Bedingungen von sigs.k8s.io bei mir Lust auf mehr. Ich hatte einige Probleme mit Konflikten, fehlerhaften Zuständen usw. Und als ich mich mehr mit dem Problem befasste, begann ich, eine Art Rahmen für meine Verwendung von Bedingungen zu schaffen.
Ich habe mir in letzter Zeit endlich die Zeit genommen, diese Erkenntnisse in einer Bibliothek zu packen, damit andere sie nutzen können. Ich nenne es Konditionner. Im Kern besteht das Ziel von Konditionner darin, Folgendes anzubieten:
import "github.com/pier-oliviert/konditionner/pkg/konditions" BuildCondition konditions.ConditionType = "Builds" NetworkCondition konditions.ConditionType = "Network" PodCondition konditions.ConditionType = "Pod" DependenciesCondition konditions.ConditionType = "Dependency" VariablesCondition konditions.ConditionType = "Variables" type MyCRD struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` Spec MySpec `json:"spec,omitempty"` Status MyStatus `json:"status,omitempty"` } // ConditionalResource interface, more about it in the Advisory Lock // section func (m MyCRD) *konditions.Conditions { return &m.Status.Conditions } type MySpec struct { // ... My Fields ... } type MyStatus struct { // ... My Fields ... Conditions konditions.Conditions `json:"conditions,omitempty"` }
Die benutzerdefinierte MyCRD-Ressource ist ziemlich dürftig, aber einsatzbereit! Für Konditionner ist kein Typ definiert, da dieser für jede Verwendung spezifisch ist. Hier habe ich 5 davon erstellt, was bedeutet, dass ich mit 5 Bedingungen in der Abgleichsschleife arbeiten werde.
Stellen wir uns vor, ich hätte eine Abgleichsschleife, in der ich einen Pod erstellen möchte. Das Ziel der Bedingung besteht darin, von „Initialisiert“ zu einem von zwei Ergebnissen zu gelangen: „Erstellt“, wenn die Bedingung erfolgreich war, und „Fehler“, wenn im Prozess ein Fehler aufgetreten ist.
Da die Abstimmungsschleife auf einer verteilten Datenbank (etcd) und einer Cache-Ebene basiert, habe ich festgestellt, dass es viel zuverlässiger ist, vor der Ausführung einer Aufgabe eine „Sperre“ für die Bedingung zu erstellen.
func (r Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { var record MyCRD if err := r.Get(ctx, req, &record); err != nil { return ctrl.Result{}, err } lock := konditions.NewLock(record, r.Client, PodCondition) if lock.Condition().Status == konditions.ConditionError { // Nothing to do return ctrl.Result{}, err } if lock.Condition().Status == konditions.ConditionInitialized { lock.Execute(ctx, func(condition konditions.Condition) error { pod, err := createPod() if err != nil { return err } condition.Status = konditions.ConditionCreated condition.Reason = fmt.Sprintf("Pod created: %s", pod.Name) record.Conditions().setCondition(condition) return nil }) } }
Damit die Sperre funktioniert, muss der Datensatz der Schnittstelle „konditions.ConditionalResource“ entsprechen. Aus diesem Grund ist oben in der benutzerdefinierten Ressource die Methode Conditions() definiert:
func (m MyCRD) *konditions.Conditions { return &m.Status.Conditions }
Die Dokumentation ist auf pkg.go.dev und die Quelle auf Github verfügbar.
Das obige ist der detaillierte Inhalt vonKonditionner: Verwalten Sie Bedingungen in Ihren kcustom-Ressourcen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!