DEV Community

Cover image for K8s Operator - Annotations
Maxime Guilbert
Maxime Guilbert

Posted on

K8s Operator - Annotations

Now that we know how to manage resources status and conditions, it's time to see annotations.

All the annotations comes from Kubebuilder.

There are a lot of different annotations, and we already saw some of them because we defined RBAC rights for our operator with annotations.

// +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

Today, we will see 4 annotations which will help us to be more efficient when using custom resources and/or to debug them.


1. Resource

This annotation must be above the resource struct definition. (in api/.../xxx_types.go)

Composed with 3 major parts, they are used to :

  • Define the operator "scope" (if the operator is Namespace-scope or Cluster-scope)
  • Define the list of alternate names that can be used to access the resource (When you do kubectl get ...). Each name must be separated by ;
  • Define the singular for the resource name (Also to use it when you do 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

Having custom resources is good, but being able to display important informations with kubectl get is better!

Still above the resource struct definition (in api/.../xxx_types.go), you can define custom columns with the following pattern

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

NAME : The name of the custom column.

TYPE : To define the type of data you want to display. (ex: String, number...)
Check the OpenAPI Specification to know which type can be used.

JSONPATH : To define the JSONPath to use to access the information in the custom resource. If the information isn't available in the resource, you won't be able to display it.
Check the Kubernetes documentation to know how to write a JSONPath value.

Example

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

Here are 3 more specific cases about this annotation!

2.1. Priority

When we want to get the information of a resource, we can use the option -o wide to get more informations than default.

To do it with the operator, you just need to add ,priority=10 (or any value strictly greater than 0) in the printcolumn definition of the value you only want to display with the option -o wide.

Example

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

2.2. Age

By default when you do kubectl get ... on your custom resource, their age is shown. But once you've added one printcolumn, the information isn't displayed anymore.

So if you want to keep the information, here is the annotation you must add.

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

2.3. Ready

Previously in this serie, we talked about conditions and we said that it can be useful to know if everything goes well. With the following column, we will be able to easily see if everything goes well or not.

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

3. Validation

The following annotation simply add validations on your spec fields.

Here are a bunch of them :

  • Make mandatory a field : //+kubebuilder:validation:Required
  • Make a field optional : // +kubebuilder:validation:Optional
  • Define the minimum length of a string : //+kubebuilder:validation:MinLength=8
  • Define the maximum length of a string : //+kubebuilder:validation:MaxLength=20
  • Check if the value is contain in a Enum list : // +kubebuilder:validation:Enum=earth;wind;fire
  • Define the minimum number of elements in an array : //+kubebuilder:validation:MinItems=2
  • For a number, check if the value is a multiple of a particular value : //+kubebuilder:validation:MultipleOf=15

There are a lot more, and if you are interested, go check the KubeBuilder documentation. But with all these examples, you have a great idea about what can be done or not.


4. Default

The last annotation we will see today is the one which defines a default value for a spec field.

It can be really useful in case of an optional field..

Examples

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

Now that you know all of these annotations, you will be able to easily do a lot more with your operator.

In the next part of this serie, we will leave the tutorial part to talk about an operator which already exists : Crossplane!

I hope it will help you and if you have any questions (there are not dumb questions) or some points are not clear for you, don't hesitate to add your question in the comments or to contact me directly on LinkedIn.


You want to support me?

Buy Me A Coffee

Top comments (0)