Kubestr et CNPG Bench pour tester vos volumes persistants
Sommaire
"C'est lent", "Ça marche mieux sur mon poste local", des remarques que j'ai eues il y a quelque temps sur des bases de données hébergées sur Kubernetes, avec des Volumes Persistants. Souhaitant avoir des données objectives avant de râler contre ceux qui se plaignent, j'ai trouvé 2 outils sympa pour tester les performances des PV (Persistant Volumes) sur mes clusters. Voici un aperçu.
Note : Je ne vais pas expliquer ici comment tuner vos disques, ni tuner les applications de test pour optimiser les perfs.
Kubestr
Kubestr est une collection d'outils pour "découvrir, valider et évaluer les options de stockages sur Kubernetes". C'est un outil fournit par Kasten, un des leaders des solutions de protection des données en environnement Kubernetes.
Parmi les outils proposés par kubestr
, on retrouve le fameux fio, que les "vieux" sysadmin comme moi connaissent. Pour faire simple, fio
va faire des tests de lecture / écriture avec plusieurs paramètres, et en sortir des stats.
Ainsi, kubestr
va nous permettre assez simplement de :
- Créer un volume de taille définie à partir d'une classe de stockage choisie
- Lancer un test de performances avec FIO
- Nous donner les résultats.
Un schéma repris du blogpost de Kasten expliquant le process :
Installation
Kubestr est un binaire qui se télécharge directement depuis la page de releases GitHub. À la date d'écriture de l'article, nous sommes à la version v0.4.41. On récupère l'archive, on la décompresse et on lui donne les droits d'exécution :
1$ curl -LJO https://github.com/kastenhq/kubestr/releases/download/v0.4.41/kubestr_0.4.41_Linux_amd64.tar.gz
2$ tar zxvf kubestr_0.4.41_Linux_amd64.tar.gz kubestr
3$ chmod +x kubestr
4$ ./kubestr --help
5kubestr is a tool that will scan your k8s cluster
6 and validate that the storage systems in place as well as run
7 performance tests.
Utilisation
Il existe plusieurs options d'utilisation de l'outil, ce qui nous intéresse ici est le module "FIO". Plusieurs options de lancement sont possibles, notamment :
-f, --fiofile
: un fichier de configuration fio. On pourra trouver des exemples ici-z, --size
: taille du volume qui sera créé. Selon les providers, les I/O dépendent de la taille du volume (exemple avec le High Speed Gen2 de chez OVHCloud)-s, --storageclass
: type de StorageClass du volume persistant utilisé pour le test
Pour l'exemple, on va tester les 2 types de classe de stockage par défaut d'un cluster OVHCloud, avec un volume de 25Gb.
1$ ./kubestr fio -z 25Gi -s csi-cinder-high-speed
2PVC created kubestr-fio-pvc-wn4f6
3Pod created kubestr-fio-pod-hxfvs
4Running FIO test (default-fio) on StorageClass (csi-cinder-high-speed) with a PVC of Size (25Gi)
5Elapsed time- 1m20.178437269s
6FIO test results:
7
8FIO version - fio-3.34
9Global options - ioengine=libaio verify=0 direct=1 gtod_reduce=1
10
11JobName: read_iops
12 blocksize=4K filesize=2G iodepth=64 rw=randread
13read:
14 IOPS=1412.357544 BW(KiB/s)=5666
15 iops: min=1220 max=1724 avg=1427.666626
16 bw(KiB/s): min=4880 max=6896 avg=5711.066895
17
18JobName: write_iops
19 blocksize=4K filesize=2G iodepth=64 rw=randwrite
20write:
21 IOPS=825.023193 BW(KiB/s)=3316
22 iops: min=462 max=1292 avg=827.566650
23 bw(KiB/s): min=1848 max=5170 avg=3310.566650
24
25JobName: read_bw
26 blocksize=128K filesize=2G iodepth=64 rw=randread
27read:
28 IOPS=1657.303345 BW(KiB/s)=212667
29 iops: min=1490 max=1858 avg=1671.933350
30 bw(KiB/s): min=190720 max=237824 avg=214017.406250
31
32JobName: write_bw
33 blocksize=128k filesize=2G iodepth=64 rw=randwrite
34write:
35 IOPS=862.746399 BW(KiB/s)=110966
36 iops: min=692 max=1298 avg=865.000000
37 bw(KiB/s): min=88576 max=166144 avg=110755.734375
38
39Disk stats (read/write):
40 sdb: ios=51692/28087 merge=445/670 ticks=2147425/2151581 in_queue=4303451, util=99.532051%
41 - OK
La même commande sur une StorageClass "classic" :
1$ ./kubestr fio -z 25Gi -s csi-cinder-classic
2PVC created kubestr-fio-pvc-8pnmw
3Pod created kubestr-fio-pod-z9bnn
4Running FIO test (default-fio) on StorageClass (csi-cinder-classic) with a PVC of Size (25Gi)
5Elapsed time- 41.494978608s
6FIO test results:
7
8FIO version - fio-3.34
9Global options - ioengine=libaio verify=0 direct=1 gtod_reduce=1
10
11JobName: read_iops
12 blocksize=4K filesize=2G iodepth=64 rw=randread
13read:
14 IOPS=120.751854 BW(KiB/s)=498
15 iops: min=44 max=184 avg=123.064514
16 bw(KiB/s): min=176 max=736 avg=492.354828
17
18[...]
19
20Disk stats (read/write):
21 sdb: ios=4468/2655 merge=8/151 ticks=2224172/1996479 in_queue=4222117, util=99.475037%
22 - OK
L'application a créé à chaque fois un PVC avec la bonne taille, dans la bonne StorageClass, créé un pod, monté le volume persistant, fait les tests FIO et nous a sorti les résultats. Easy !
Résultats
Les résultats nous arrivent par défaut sur la console, et on peut voir que plusieurs tests ont été faits :
- read_iops
- write_iops
- read_bw
- write_bw
Je ne vais pas commenter les performances des volumes persistants ici, mais on voit bien que le "high-speed" est plus rapide que le "classic" ;)
Exemple sur les tests en lecture :
1# High-Speed
2JobName: read_iops
3 blocksize=4K filesize=2G iodepth=64 rw=randread
4read:
5 IOPS=1412.357544 BW(KiB/s)=5666
6 iops: min=1220 max=1724 avg=1427.666626
7 bw(KiB/s): min=4880 max=6896 avg=5711.066895
8
9# Classic
10JobName: read_iops
11 blocksize=4K filesize=2G iodepth=64 rw=randread
12read:
13 IOPS=120.751854 BW(KiB/s)=498
14 iops: min=44 max=184 avg=123.064514
15 bw(KiB/s): min=176 max=736 avg=492.354828
Il est possible de sortir les résultats au format JSON si besoin.
CloudNativePG Bench
En cherchant d'autres outils, je suis tombé sur l'opérateur CloudNativePG qui permet de gérer des bases de données PSQL. Au premier abord aucun lien avec les tests de performances des disques. Sauf que le projet propose un plugin kubectl
, avec la possibilité de benchmarker les disques sur lesquels pourront tourner les bases psql !
Le plugin cnpg
utilise comme l'outil précédent fio, plus d'infos sur les options du plugin ici.
Installation
Quand on parle de plugin kubectl
, le meilleur moyen d'installer est d'utiliser krew. On va donc utiliser cette méthode :
1$ kubectl krew install cnpg
2Updated the local copy of plugin index.
3Installing plugin: cnpg
4Installed plugin: cnpg
5\
6 | Use this plugin:
7 | kubectl cnpg
8 | Documentation:
9 | https://github.com/cloudnative-pg/cloudnative-pg
10/
11
12$ kubectl cnpg version
13Build: {Version:1.21.0 Commit:9bc5b9b2 Date:2023-10-12}
14
15$ kubectl cnpg fio --help
16Creates a fio deployment that will execute a fio job on the specified pvc.
Utilisation
On retrouve sensiblement les mêmes options que kubestr
pour tester les volumes :
--pvcSize
: taille du PVC--storageClass
: type de classe de stockage- Nom du job à fournir
Ici pas de possibilité de fournir un fichier de configuration FIO. Par contre, l'option --dry-run
permet de générer les manifests YAML qui seront utilisés pour le déploiement. On remarquera la création d'une ConfigMap qui contient les paramètres suivants :
1apiVersion: v1
2kind: ConfigMap
3metadata:
4 name: fio-job
5data:
6 job: |-
7 [read]
8 direct=1
9 bs=8k
10 size=1G
11 time_based=1
12 runtime=60
13 ioengine=libaio
14 iodepth=32
15 end_fsync=1
16 log_avg_msec=1000
17 directory=/data
18 rw=read
19 write_bw_log=read
20 write_lat_log=read
21 write_iops_log=read
On pourra modifier alors cela si besoin de lancer des jobs fio
différents.
On lance les 2 tests avec les mêmes caractéristiques que précédemment (les 2 StoragesClass, avec disque de 25Gb) :
1$ kubectl cnpg fio fio-job-high-speed --storageClass csi-cinder-high-speed --pvcSize 25Gi
2Running this directly to the cluster may produce a disruption in the service, are you sure you want to proceed? (y/n)
3y
4PersistentVolumeClaim/fio-job-high-speed created
5ConfigMap/fio-job-high-speed created
6Deployment/fio-job-high-speed created
7To remove this test you need to delete the Deployment, ConfigMap and PVC with the name fio-job-high-speed
8
9The most simple way to do this is to re-run the command that was runto generate the deployment with the --dry-run flag and pipe that output to kubectl delete, e.g.:
10
11kubectl cnpg fio <fio-job-name> --dry-run | kubectl delete -f
Tiens ! Ici pas de résultats... Mais un déploiement qui se crée, fait sa vie, et ne sera pas arrêté à la fin du test. On devra supprimer le déploiement nous-même.
Lançons le 2ème test :
1$ kubectl cnpg fio fio-job-classic --storageClass csi-cinder-classic --pvcSize 25Gi
2Running this directly to the cluster may produce a disruption in the service, are you sure you want to proceed? (y/n)
3y
4PersistentVolumeClaim/fio-job-classic created
5ConfigMap/fio-job-classic created
6Deployment/fio-job-classic created
7To remove this test you need to delete the Deployment, ConfigMap and PVC with the name fio-job-classic
8
9The most simple way to do this is to re-run the command that was runto generate the deployment with the --dry-run flag and pipe that output to kubectl delete, e.g.:
10
11kubectl cnpg fio <fio-job-name> --dry-run | kubectl delete -f -
Bon, on a bien nos 2 déploiements, avec mes 2 PVCs, il a dû se passer des "trucs" ?
1$ kubectl get deploy,pvc
2NAME READY UP-TO-DATE AVAILABLE AGE
3deployment.apps/fio-job-classic 0/1 1 0 83s
4deployment.apps/fio-job-high-speed 1/1 1 1 5m17s
5
6NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
7persistentvolumeclaim/fio-job-classic Bound ovh-managed-kubernetes-wqforj-pvc-fec4df30-b026-4f34-9dc2-6ad59dde805e 25Gi RWO csi-cinder-classic 83s
8persistentvolumeclaim/fio-job-high-speed Bound ovh-managed-kubernetes-wqforj-pvc-92f26269-6c0d-4953-9e5f-d4b4c88ab12e 25Gi RWO csi-cinder-high-speed 5m17s
Résultats
Pour voir les résultats, en fait le déploiement utilise fio-tools pour générer de "beaux" graphiques, et les données sont disponibles via un service web ! Il va falloir lancer un navigateur web pour voir cela, avec un coup de port-forwarding :
1$ kubectl port-forward deployment/fio-job-high-speed 8000
2Forwarding from 127.0.0.1:8000 -> 8000
3Forwarding from [::1]:8000 -> 8000
On va retrouver sur l'interface web :
- les résultats du job
fio
au format texte - les données de chaque job, au format brut/texte (fichiers .log)
- des graphes visuels montrant les perfs au format PNG
Voici, pour l'exemple, le résultat du précédent tests sur du disque "high-speed" :
Mes remarques
Avec ces tests, j'ai pu confirmer que les gens qui se plaignaient au début avaient raison, et j'ai pu adapter le type de PVC pour coller au besoin applicatif. Remarque pour celles & ceux travaillant sur des clusters OVHcloud, pensez à créer la StorageClass "high-speed-gen2" qui n'est pas activée par défaut ;)
Concernant les 2 outils, ma préférence pour les tests va au plugin cpng
, qui avec la ConfigMap & les graphes est plus sympa d'utilisation. Juste pensez-bien à supprimer les déploiements après tests.
Pour kubestr
, ne pas négliger les autres options de l'outil comme kubestr browse
qui permet de créer un snapshot de volume et naviguer dedans, très pratique !