Au cours des exercices précédents, nous avons créé un service en façade de 2 pods que nous avons créés manuellement.

Kubernetes nous offre de nombreuses solutions pour simplifier la réplication des pods, que nous allons manipuler une à une.

ReplicaSets

Les ReplicaSets s'assurent qu'un certain nombre d'instances de pods tournent à tout moment. Ils sont généralement manipulés par les Deployments et on ne les manipule que très rarement directement.

Nous allons cependant en créer un pour bien comprendre l'intelligence apportée par les Deployments

Création

À sa création, le ReplicaSet est pris en compte par Kubernetes et de nouveaux pods sont créés (si besoin) selon le manifeste spécifié dans spec.template.

Le ReplicaSet est associé à un ensemble de Pods grâce à son selecteur de labels. Nous allons commencer par créer un ReplicaSet au dessus de Pods pré-éxistants. Pour ce faire, il faut indiquer un sélecteur de labels qui corresponde aux labels des Pods existant.

  • Commencer par récupérer les labels des pods existants
kubectl get pod
kubectl get pod <nom du pod> -o yaml
  • Créer ensuite le ReplicaSet en s'appuyant sur le modèle ci-dessous.
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: echo-server-rs
  labels:
    ... # label du ReplicaSet 
spec:
  replicas: ... # nombre d'instances
  selector:
    ... # selecteur
  template:
    metadata:
      labels:
        app: ... # labels des pods
    spec:
      ... # définition des pods

Quel résultat observez-vous dans les situations suivantes :

  • metadata.labels différent de spec.template.labels
  • spec.template.spec différent de la spécification des pods déjà existants (essayer un port différent par exemple)
  • spec.replicas inférieur au nombre d'instances pré-éxistantes

Passage à l'échelle

Nous allons maintenant changer le nombre d'instances de Pods, il existe deux manière de le faire :

  • en modifiant le manifeste du ReplicaSet
  • en utilisant la commande scale

Commençons par modifier le manifeste.

kubectl edit replicaset <nom du replicaset>
# modifier spec.replicas
kubectl describe replicaset <nom du ReplicaSet>

Afficher la description du RepilcaSet, nous devrions voir l'évènement de création de pod dans la liste des évènements.

Replicas:     3 current / 3 desired
Pods Status:  3 Running / 0 Waiting / 0 Succeeded / 0 Failed
...
Events:
  Type    Reason            Age   From                   Message
  ----    ------            ----  ----                   -------
  Normal  SuccessfulCreate  13s   replicaset-controller  Created pod: echo-server-rs-z8lkv

L'opération est plus simple en utilisant la commande scale

kubectl scale replicaset <nom du ReplicaSet> --replicas=4
kubectl describe replicaset <nom du ReplicaSet>

De la même manière, la description doit afficher en évènement de création de pod.

Suppression

  • Supprimer le ReplicaSet.
kubectl delete replicaset <nom du ReplicaSet>

Que sont devenus les Pods ?

  • Recréer le ReplicaSet.
  • Le supprimer à nouveau en ajoutant l'option --cascade=orphan

Passage à l'échelle automatique

La possibilité de choisir manuellement et simplement le nombre d'instance du ReplicaSet nous offre déjà beaucoup de souplesse. Nous allons toutefois aller plus loin en mettant en place un Autoscaler dont le rôle est de mettre à jour automatiquement le nombre d'instances en fonction de la charge des conteneurs.

Pour ce faire nous allons utiliser une image docker exposant une route HTTP qui réalise un calcul intensif lorsqu'elle est requêtée.

L'image est question est k8s.gcr.io/hpa-example, qui exécute le code suivant lors d'une requête sur sa racine HTTP (port 80).

<?php
  $x = 0.0001;
  for ($i = 0; $i <= 1000000; $i++) {
    $x += sqrt($x);
  }
  echo "OK!";
?>
  • Créer un ReplicaSet qui maintient deux instances de l'image k8s.gcr.io/hpa-example.

Pour que l'Autoscaler fonctionne, il va falloir indiquer des limitations de ressources aux conteneurs du Pod. Ajouter la section suivante dans l'attribut containers du template de Pod.

resources:
  requests:
    cpu: "100m"
  • Créer un service pour atteindre les pods créés
  • Vérifier le bon déploiement et le bon fonctionnement des pods.

Nous allons maintenant créé l'autoscaler au dessus de ce ReplicaSet, l'opération est simple et se réalise en une commande.

kubectl autoscale replicaset <nom du replicaset> --cpu-percent=20 --min=1 --max=3

Pour vérifier le fonctionnement de l'auto-scaler, il ne reste qu'à effectuer des requêtes sur le service pour générer de la charge CPU. Nous allons effectuer ces requêtes depuis une image busybox.

kubectl run -i --tty --rm load-generator --image=busybox /bin/sh
while true; do wget -q -O- http://<ip du service>; done

Afficher l'autoscaler après avoir démarré la boucle de montée en charge.

kubectl get hpa

Au bout d'un certain temps, la charge indiquée devrait dépasser la limite de 20%, l'autoscaler va donc faire passer à l'échelle le ReplicaSet.

kubectl get replicaset <nom du replicaset>