DEV Community

Cover image for K8s Operator - Annotations
Maxime Guilbert
Maxime Guilbert

Posted on

K8s Operator - Annotations

Maintenant que l'on sait gérer le statut et les conditions de nos ressources personnalisées, il est de bon ton de faire le tour des annotations.

Toutes celles qu'on va utiliser proviennent de Kubebuilder.

Il en existe de différentes sortes, et on en a déjà vu dans les articles précédents car c'est via les annotations kubebuilder qu'on a pu configurer les droits RBAC pour notre opérateur.

// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete  
// +kubebuilder:rbac:groups=core,resources=services,verbs=get;list;watch;create;update;patch;delete
Enter fullscreen mode Exit fullscreen mode

Aujourd'hui, on va voir 4 annotations qui vont vous permettre d'être plus efficace lors de l'utilisation et/ou du débuggage de votre opérateur.


1. Resource

Cette annotation va se retrouver au dessus de la définition de la structure d'une ressource personnalisée. (dans api/.../xxx_types.go)

Composée de 3 parties principales, ces parties vont vous permettre de :

  • Définir le scope de l'opérateur via le paramètre "scope"
  • Définir la liste des noms par lesquels vous voudrez accéder aux ressources (quand vous faites kubectl get ...) Et les différents noms doivent être séparés par un ;
  • Définir le singulier pour la ressource (Aussi pour quand vous effectuez un kubectl get ...)
//+kubebuilder:resource:scope=Cluster,shortName=myproxies;mp,singular=myproxy
type MyProxy struct {  
   metav1.TypeMeta   `json:",inline"`  
   metav1.ObjectMeta `json:"metadata,omitempty"`  

   Spec   MyProxySpec   `json:"spec,omitempty"`  
   Status MyProxyStatus `json:"status,omitempty"`  
}
Enter fullscreen mode Exit fullscreen mode

2. Printcolumn

Avoir des ressources personalisées c'est bien, mais être capable d'afficher des informations importantes quand on fait un kubectl get, c'est mieux!

Toujours au dessus de la définition de la structure d'une ressource personnalisée (dans api/.../xxx_types.go), vous allez pouvoir définir les annotations en suivant le modèle suivant

// +kubebuilder:printcolumn:name="NAME",type=TYPE,JSONPath=JSONPATH
Enter fullscreen mode Exit fullscreen mode

NAME sera à remplacer par le nom de l'information que vous souhaitez afficher. Ce nom sera utilisé comme nom de colonne.

TYPE sera à remplacer par le type de valeur à afficher. (ex: String, number...)
Référez-vous à la Spécification OpenAPI pour savoir quel type choisir en fonction de vos besoins.

JSONPATH sera à remplacer par le JSONPath pour accéder à l'information dans votre ressource. L'information doit obligatoirement se trouver dans la ressource, que ça soit dans sa spécification ou son statut.
Référez-vous à la documentation de Kubernetes concernant la manière d'écrire cette partie en JSONPath.

Exemple

// +kubebuilder:printcolumn:name="Name",type=string,JSONPath=`.spec.name`
Enter fullscreen mode Exit fullscreen mode

Déjà avec ça, on est plutôt gâté, mais voici 3 petits points supplémentaires concernant cette annotation!

2.1. Priority

En effet quand on veut récupérer les informations d'une ressource dans Kubernetes, il est possible d'utiliser l'option -o wide afin d'en afficher plus.

Afin de pouvoir le faire avec votre opérateur, il vous suffit d'ajouter ,priority=10 (ou n'importe quel autre nombre strictement supérieur à 0) dans la définition du printcolumn que vous souhaitez avoir que lors de l'utilisation de l'option -o wide.

Exemple

// +kubebuilder:printcolumn:name="Name",type=string,JSONPath=`.spec.name`,priority=10
Enter fullscreen mode Exit fullscreen mode

2.2. Age

Par défaut, quand vous faites un kubectl get ... de vos ressources l'age de vos ressources est affiché. Cependant, dès que vous définissez un printcolumn, cette information n'est plus affichée.

Par conséquent, si vous voulez conserver cette information, vous devez rajouter l'annotation suivante

// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=.metadata.creationTimestamp
Enter fullscreen mode Exit fullscreen mode

2.3. Ready

Dans la partie précédente de cette série, nous avons évoqué les conditions. Avec la colonne ci-dessous, on va être capable d'afficher si l'ensemble des conditions de la ressource sont remplies.

// +kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].status`
Enter fullscreen mode Exit fullscreen mode

3. Validation

L'annotation suivante permet d'ajouter simplement des validations sur les différents champs de votre spécification.

Il en existe de différents types, en voici quelques exemples :

  • Rendre obligatoire un champ : //+kubebuilder:validation:Required
  • Rendre optionel un champ : // +kubebuilder:validation:Optional
  • Définir une longueur minimum à la valeur saisie : //+kubebuilder:validation:MinLength=8
  • Définir une longueur maximum à la valeur saisie : //+kubebuilder:validation:MaxLength=20
  • S'assurer que la valeur fait bien parti d'une certaine liste de possibilités : // +kubebuilder:validation:Enum=earth;wind;fire
  • Pour définir le nombre minimum d'éléments dans un tableau : //+kubebuilder:validation:MinItems=2
  • Pour une valeur numérique, s'assurer que la valeur saisie est le multiple d'un certain nombre : //+kubebuilder:validation:MultipleOf=15

Et là encore j'en oublie plein, pour voir tous les autres existants, allez sur la documentation de KubeBuilder. Mais ça vous montre quand même ce qui est possible de faire avec!


4. Default

La derrnière annotation qui vous sera bien utile est celle pour pouvoir définir une valeur par défaut à un champ.

En effet, si certains de vos champs sont optionnels, vous aimerez peut être définir une valeur par défaut.

Exemples

// +kubebuilder:default:=test
Enter fullscreen mode Exit fullscreen mode
// +kubebuilder:default:=0
Enter fullscreen mode Exit fullscreen mode

Conclusion

Maintenant que vous connaissez ces annotations, vous êtes en mesure de pouvoir mieux configurer votre opérateur et notamment de gérer un certain nombre de vérifications sans créer un webhook.

Dans la prochaine partie de cette série, nous allons parler sortir un peu du tutoriel pour parler d'un opérateur déjà existant : Crossplane!

J'espère que ça vous aidera et si jamais vous avez des questions, quelles qu'elles soient (Il n'y a jamais de questions bêtes!) ou des points qui ne sont pas clairs pour vous, n'hésitez pas à laisser un message dans les commentaires ou à me joindre directement sur LinkedIn (même pour parler d'autres sujets!).


Vous voulez me supporter?

Buy Me A Coffee

Top comments (0)