Monitorer son opérateur
Tags: kubernetes, devops, sre, monitoring
Published: 2023-08-28 14:01:00

Avoir un opérateur c'est bien sympa, mais encore faut-il que tout se passe bien. Pour surveiller ça et potentiellement mettre des alertes dessus, il faut avoir des métriques.

Ca tombe bien, par défaut avec Operator SDK en Go on va avoir un ensemble de métriques déjà présentes pour nous aider à surveiller notre opérateur.

## Métriques disponibles

Voici un aperçu des métriques disponibles, pour avoir la liste complète, veuillez aller regarder la [référence dans Kubebuilder](https://book.kubebuilder.io/reference/metrics-reference.html).

- `controller_runtime_reconcile_total` : Counter - Nombre total de réconciliations faites par un controller
- `controller_runtime_reconcile_errors_total` : Counter - Nombre de réconciliations en erreur par controller
- `controller_runtime_reconcile_time_seconds` : Histogram - Durée par réconciliation par controller
- `controller_runtime_webhook_requests_total` : Counter - Nombre d'appels au Webhook triés par code réponse HTTP

---

## Avoir plus de métriques
Bien que les métriques génériques de base soient très pratiques, il se peut qu'elles ne vous suffisent pas pour couvrir l'ensemble des cas d'utilisation que vous avez. 

Pour cela, il existe un moyen très simple d'ajouter de nouvelles métriques. A partir du package `github.com/prometheus/client_golang/prometheus`, créez l'ensemble des métriques dont vous avez besoin 

```go
import ( 
	"github.com/prometheus/client_golang/prometheus" 
)

var ( 
	goobers = prometheus.NewCounter( 
		prometheus.CounterOpts{ 
			Name: "goobers_total", 
			Help: "Number of goobers proccessed", 
		}, 
	) 
	gooberFailures = prometheus.NewCounterVec( 
		prometheus.CounterOpts{ 
			Name: "goober_failures_total",
			Help: "Number of failed goobers", 
		}, []string{"label_1"}
	)
)
```

Puis déclarez-les dans le registre des métriques de l'opérateur

```go
import ( 
	"sigs.k8s.io/controller-runtime/pkg/metrics" 
)

func init() { 
	metrics.Registry.MustRegister(goobers, gooberFailures) 
}
```

Une fois que c'est fait, vous pouvez utiliser ces métriques dans votre code!
```go
goobers.Inc()
goobers.Add(2)

gooberFailures.WithLabelValues("toto").Inc()
gooberFailures.WithLabelValues("titi").Add(2)
```

> ## Métriques avec labels
> Comme vous avez pu le constater dans l'exemple précédent, si vous voulez créer une métrique avec des labels, vous pouvez utiliser `New...Vec`. Cela va vous demander la liste des labels que vous voulez pour votre métrique, et ça va vous demander de remplir les valeurs de ces labels avec `WithLabelValues` quand vous voudrez mettre à jour une métrique. Plutôt pratique si vous avez toujours les mêmes labels sur votre métrique.
>
> Autrement, vous pouvez utiliser `.With()` pour ajouter des labels comme vous le souhaitez.
> ex: `.With(map[string]string{"toto": "titi"}).Inc()`
>
> En dehors de ça le fonctionnement est strictement identique à une métrique sans labels.

---

En conclusion, un opérateur reste un service comme un autre et il doit lui aussi être surveillé pour s'assurer que tout se passe bien dans votre système. Et comme pas mal de choses avec Operator SDK et Kubebuilder, les choses nous sont pas mal simplifiées avec l'intégration de la librairie golang de Prometheus!

---

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](https://www.linkedin.com/in/maxime-guilbert-14b6a5128/) *(même pour parler d'autres sujets!)*.