Maison > Article > développement back-end > Konditionner : Gérez les conditions dans vos ressources kcustom
L'année dernière, j'ai commencé à créer des opérateurs avec kubebuilder pour diverses choses. Tout au long des opérateurs, j'ai largement utilisé les conditions pour gérer chaque étape d'un processus de réconciliation pour une ressource personnalisée.
Malheureusement, les conditions de sigs.k8s.io m'ont donné envie d'en savoir plus. J'ai eu quelques problèmes avec des conflits, des états brisés, etc. Et au fur et à mesure que j'approfondissais le problème, j'ai commencé à créer une sorte de cadre autour de mon utilisation des conditions.
J'ai finalement pris quelques instants récemment pour regrouper ces découvertes dans une bibliothèque que d'autres peuvent utiliser. Je l'appelle Konditionner. À la base, l'objectif de Konditionner est d'offrir :
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"` }
La ressource personnalisée MyCRD est assez simple mais elle est prête à être utilisée ! Konditionner n'est fourni avec aucun type défini, car celui-ci est spécifique à chaque utilisation. Ici, j'en ai créé 5, ce qui veut dire que je vais travailler avec 5 conditions dans la boucle de réconciliation.
Supposons que j'ai une boucle de réconciliation dans laquelle je souhaite créer un pod. L'objectif de la condition est de passer d'Initialisé et de progresser vers l'un des deux résultats : Créé s'il a réussi, Erreur s'il y a eu une erreur dans le processus.
Étant donné que la boucle de réconciliation fonctionne au-dessus d'une base de données distribuée (etcd) et d'une couche de cache, j'ai trouvé qu'il était beaucoup plus fiable de créer un « verrou » sur la condition avant d'exécuter une tâche.
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 }) } }
Pour que le verrou fonctionne, l'enregistrement doit respecter l'interface konditions.ConditionalResource. C'est pourquoi, en haut, la ressource personnalisée a la méthode Conditions() définie :
func (m MyCRD) *konditions.Conditions { return &m.Status.Conditions }
La documentation est disponible sur pkg.go.dev et la source est disponible sur Github.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!