Comment minimiser votre emprunte carbone avec Kube-Green?
Tags: kubernetes, devops, sre, french
Published: 2023-07-31 13:00:00

On est dans une ère où le numérique est de plus en plus présent dans nos quotidiens, mais le numérique *(surtout tout le matériel qui peut être derrière et l'énergie qu'il consomme)* est une source de pollution. 

Tout comme vous pouvez participer au tri des déchets et à la réutilisation pour limiter votre emprunte carbone, on va voir comment vous pouvez le faire avec votre cluster Kubernetes! *(En plus ça peut vous sauvez des coûts si votre cluster est dans le cloud)*

---

## Kube-Green
**Kube-Green** est un opérateur qui vous permet de **réduire le nombre de réplicas de vos déploiements à 0** et de **suspendre vos CronJob en dehors de vos "journées de travail"**.

L'objectif est simple, couper les pods et jobs qui tourneraient pour rien la nuit et les weekends, avant de les redémarrer le matin des jours en semaine. De ce fait, l'ensemble de ces processus ne tournent pas "dans le vent", produisant du CO2 et peuvent vous permettre de scale-down votre cluster si il est sur AWS par exemple.

### Dans quels cas l'utiliser?
C'est sûr que ça n'est pas à utiliser sur votre production, à moins que cette dernière ne soit utilisée que durant les heures de travail. Cet opérateur s'oriente principalement pour tous les environnements de développement ou de tests qui restent souvent démarrés en permanence pour rien.

### Est-il possible d'exclure certains traitements?
En effet c'est une question que vous pouvez vous poser : "**Est-il possible d'exclure certain traitement?**" car en effet peut être qu'il y a certaines fonctionnalités de votre cluster de développement qui doit rester allumer en permanence. Sachez que **c'est possible**, on le verra au niveau de la configuration pour le détail, mais c'est possible.

---

## Mise en place
> Toutes les informations concernant l'installation proviennent de la [documentation de Kube-Green](https://kube-green.dev/docs/install/). N'hésitez pas à aller y faire un tour pour avoir la dernière version de la documentation.

### Prérequis
Sachez qu'à ce jour Kube-Green ne fonctionne qu'avec les versions **1.19 à 1.26** de Kubernetes et **OpenShift v4**.

De plus, il faut que [**cert-manager**](https://cert-manager.io/docs/installation/) soit déjà installé.

### Installation
Plusieurs possibilités d'installation sont offertes par Kube-Green, mais on va uniquement utiliser dans cet exemple l'installation via **kubectl apply**.

Si vous voulez installer la dernière version de Kube-Green, vous pouvez utiliser la commande suivante
```bash
kubectl apply -f https://github.com/kube-green/kube-green/releases/latest/download/kube-green.yaml
```

Par contre, si vous voulez installer une version précise de Kube-Green, utilisez la commande suivante en remplaçant `${RELEASE_TAG}` par le numéro de la version de la release qui vous intéresse.
```bash
kubectl apply -f https://github.com/kube-green/kube-green/releases/download/${RELEASE_TAG}/kube-green.yaml
```

> **/!\\ Attention : Si vous utilisez Kube-Green dans un cluster qui est dans le cloud /!\\**
> En effet la [documentation](https://kube-green.dev/docs/install/#cloud-compatibility) mentionne que certains problèmes peuvent être rencontrés dans GKE et AWS. Par conséquent, allez faire un tour dans la documentation pour vérifier vos configurations avant d'aller plus loin.

## Configuration
Une fois que l'opérateur est installé, vous pourrez créer une ressource `SleepInfo` qui vous  permettra de définir  quelles ressources  doivent être arrêtées,  quand, et quand est-ce qu'elles doivent être redémarrées.

Sachez que `SleepInfo` est une ressource qui **n'agit que dans le namespace dans lequel il est déployé** c'est à dire qu'il faut **déployer une instance de SleepInfo dans chacun des namespaces dans lequel on veut utiliser Kube-Green**. *(Ce qui permet d'éviter de couper l'ensemble des déploiements essentiels au bon fonctionnement du cluster)*

```yaml
apiVersion: kube-green.com/v1alpha1  
kind: SleepInfo  
metadata:  
	name: working-hours  
spec:  
	weekdays: "1-5"  
	sleepAt: "20:00"  
	wakeUpAt: "08:00"  
	timeZone: "Europe/Rome"
```
L'exemple précédent est le cas le plus simple d'utilisation de Kube-Green où tous les déploiements vont être arrêtés à 20h (heure de Rome) tous les soirs du lundi au vendredi, et redémarrés du  lundi au vendredi à 8h (heure de Rome).

Afin de mieux comprendre comment fonctionne SleepInfo, on va faire un tour de chacun de ses champs puis voir quelques exemples exposant différent cas.

### SleepInfo : Champs
- `weekdays` : Permet de définir les jours de la semaine où l'opérateur doit agir.
	- `1` est pour Lundi
	- `1-5` est du Lundi au Vendredi
	-  `2-6` est du Mardi au Samedi
	- `*` est pour tous les jours de la semaine
- `sleepAt` : Défini sous le format `HH:mm`, il permet de déterminer à quelle heure les ressources doivent être arrêtées. *(ex: 19:00, 08:53: 23:45)*
- `wakeUpAt` : [Optionnel] Défini sous le format `HH:mm`, il permet de déterminer à quelle heure les ressources doivent être redémarrées. *(ex: 19:00, 08:53: 23:45)* 
- `timeZone` : [Optionnel] Permet de définir le fuseau horaire auquel les heures données correspondent. 
	- Cette valeur doit correspondre au nom d'un **fuseau horaire défini par la spécification IANA**. *(Colonne TZ identifier dans [Wikipedia - Fuseau Horaire](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones))*
	- Par défaut cette valeur est à `UTC`. 
- `suspendDeployments` : [Optionnel] Booléen permettant de savoir si l'opérateur doit arrêter les déploiements du namespace.
	- Par défaut cette valeur est à `true`.
- `suspendCronJobs` : [Optionnel] Booléen permettant de savoir si l'opérateur doit arrêter les cron jobs du namespace
	- Par défaut cette valeur est à `false`
- `excludeRef` : [Optionnel] Tableau d'objets permettant de définir les références des déploiements ou cron jobs à ignorer pour la mise en sommeil.
	- `apiVersion` : Version de la ressource à exclure. Actuellement sont supportés : `apps/v1`, `batch/v1beta1` et `batch/v1`  *(à ne pas définir si vous utilisez `matchLabels`)*
	- `kind` : Type de la ressource à exclure. Actuellement sont supportés : `Deployment` et `CronJob`  *(à ne pas définir si vous utilisez `matchLabels`)*
	- `name` : Nom de la ressource à exclure *(à ne pas définir si vous utilisez `matchLabels`)*
	- `matchLabels` : Liste des labels pour identifier les ressources à exclure *(A ne pas définir si vous utilisez `name`, `apiVersion` et `kind`)*

### Cas d'utilisations
#### Tout arrêter sauf api-gateway
```yaml
apiVersion: kube-green.com/v1alpha1
kind: SleepInfo
metadata:
  name: working-hours
spec:
  weekdays: "1-5"
  sleepAt: "20:00"
  wakeUpAt: "08:00"
  timeZone: "Europe/Rome"
  suspendCronJobs: true
  excludeRef:
    - apiVersion: "apps/v1"
      kind:       Deployment
      name:       api-gateway  
```
Dans cet exemple, on peut voir que l'on cherche à tout éteindre (Déploiements & CronJob) à 20h chaque soir en semaine et à les redémarrer à 8h en semaine, à l'exception du déploiement "api-gateway".

Cas utile si vous avez peu de ressources à exclure du processus.

#### Tout arrêter sauf les ressources avec un label particulier
```yaml
apiVersion: kube-green.com/v1alpha1
kind: SleepInfo
metadata:
  name: working-hours
spec:
  weekdays: "1-5"
  sleepAt: "20:00"
  wakeUpAt: "08:00"
  timeZone: "Europe/Rome"
  suspendCronJobs: true
  excludeRef:
    - matchLabels: 
        kube-green.dev/exclude: true
```
Dans cet exemple on voit que cette fois-ci tout sera éteint, à l'exception de l'ensemble des ressources ayant le label `kube-green.dev/exclude: true`.

Ce cas est à privilégier si vous avez beaucoup de ressources dans un namespace et que nombre d'entre elles sont à exclures.

#### Arrêter que les CronJob
```yaml
apiVersion: kube-green.com/v1alpha1
kind: SleepInfo
metadata:
  name: working-hours
spec:
  weekdays: "*"
  sleepAt: "20:00"
  wakeUpAt: "08:00"
  suspendCronJobs: true
  suspendDeployments: false
```
Afin d'arrêter uniquement les CronJob, il vous suffit de mettre `suspendCronJobs` à `true` et `suspendDeployments` à `false`.

#### Sans redémarrage
```yaml
apiVersion: kube-green.com/v1alpha1
kind: SleepInfo
metadata:
  name: working-hours
spec:
  weekdays: "1-5"
  sleepAt: "20:00"
  timeZone: "Europe/Rome"
  suspendCronJobs: true
  excludeRef:
    - apiVersion: "apps/v1"
      kind:       Deployment
      name:       api-gateway
```

Cet exemple nous montre qu'il est possible de ne pas définir d'heure de redémarrage. Sur le coup on peut se demander en quoi ça peut être utile, et finalement il y a un cas simple : pour vos environnements de test.

Ca dépend de votre contexte, mais il se peut que vous ayez des environnements qui ne soient utilisés qu'une fois par mois pour effectuer des tests dessus. Si c'est le cas, le redémarrer tous les jours est inutile, et donc ne pas définir d'heure de démarrage est bien utile.

---

## Liens
- [Site Kube-Green](https://kube-green.dev/)
- [Projet Github Kube-Green](https://github.com/kube-green/kube-green)

## Conclusion
Kube-Green est un projet prometteur qui, je l'espère nous permettra d'aller plus loin dans la limitation de notre impact sur la planète. Dans l'immédiat je pense aux daemonsets qui pourraient être coupés si ils sont inutiles, le fait de scale down automatiquement à 0 une ressource non-exclue si on déploie pendant les heures de "sommeil", voir de pouvoir interagir avec d'autres opérateur pour aller couper d'autres ressources *(notamment des ressources dans AWS ou GCP avec Crossplane)*...

C'est peut être pas grand chose, mais comme pour tout le reste, si on fait tous un peu d'efforts par-ci et par là, toutes ces petites contributions vont nous permettre de faire quelque chose de grand! 

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!)*.

---

<center><h3>Vous voulez me supporter?</h3></center>
<a href="https://www.buymeacoffee.com/mxguilbert7" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>