ClickHouse pour YunoHost - Correctif pour certificat SSL¶
J'ai fait, il y a un an, un package YunoHost pour déployer Clickhouse.
J'avais besoin d'un certificat SSL pour le port secure 9440 et j'ai choisi d'utiliser celui du port HTTPS que YunoHost met à jour automatiquement grâce à Let's Encrypt.
Malheureusement, le certificat se met à jour sur le disque mais Clickhouse ne le prend en compte que si je redémarre son service.
Je voudrais faire une mofidication du package pour redémarrer le service une fois par semaine afin d'être sûr que le nouveau certificat sera pris en compte avant expiration de l'ancien.
Réflexions¶
J'ai vu dans le package de restic_ynh qu'il était possible d'ajouter un service systemd qui se déclenche à intervalle régulier comme un cron (voir le fichier conf/systemd.timer.j2).
Je vais utiliser cette technique pour redémarrer Clickhouse une fois par semaine.
Ajouter cela dans le package ne sera pas très complexe mais, par contre, je voudrais pouvoir mettre à jour le Clickhouse de mes autres YunoHost (ceux d'ISTA en priorité) et c'est certainement la partie la plus complexe.
YunoHost fait un backup avant de mettre à jour et je ne sais pas si le script de backup de mon package actuel fonctionne...
YunoHost utilise le script update et je ne sais pas s'il fonctionne non plus...
Je ne sais pas non plus si YunoHost utilise le script backup et le script update de l'ancien package ou du nouveau package...
Je vais utiliser la machine yunohost-josiane sur laquelle je dois déployer Clickhouse pour faire mes tests.
Mes tests¶
Installation version actuelle (23.8~ynh1)¶
Le domaine de yunohost-josiane est apps.josiane.computablefacts.io.
J'ai commencé par ajouter un sous-domaine pour clickhouse dans YunoHost :
sudo yunohost domain add clickhouse.apps.josiane.computablefacts.io
sudo yunohost domain cert install clickhouse.apps.josiane.computablefacts.io --no-check
J'ai taggé ma repo avec 23.8-ynh1, la version actuelle, ce qui doit me permettre d'installer cette version avec l'URL https://github.com/computablefacts/clickhouse_ynh/tree/23.8-ynh1.
Je peux commencer par installer cette version puis lancer le backup pour voir s'il fonctionne.
Installer la version 23.8-ynh1 :
sudo yunohost app install --force https://github.com/computablefacts/clickhouse_ynh/tree/23.8-ynh1 --args "domain=clickhouse.apps.josiane.computablefacts.io&path=/&init_main_permission=visitors&admin=twr_admin&password=TestBackup"
L'installation se déroule sans erreur
Info: Installing clickhouse…
Info: Provisioning sources...
Info: Provisioning system_user...
Info: Provisioning install_dir...
Info: Provisioning data_dir...
Info: Provisioning permissions...
Info: Provisioning ports...
Success! Firewall reloaded
Info: [+++.................] > Setting up source files...
Info: [###+++..............] > Adding clickhouse's configuration files...
Info: [######++++..........] > Adding system configurations related to clickhouse...
Info: [##########+++.......] > Starting clickhouse's systemd service...
Info: [#############+++....] > Finalizing installation...
Warning: <jemalloc>: Number of CPUs detected is not deterministic. Per-CPU arena disabled.
Warning: <jemalloc>: Number of CPUs detected is not deterministic. Per-CPU arena disabled.
Warning: <jemalloc>: Number of CPUs detected is not deterministic. Per-CPU arena disabled.
Info: [####################] > Installation of clickhouse completed
Success! Installation completed
J'ai une erreur quand je tente une requête depuis l'UI /play (AUTHENTICATION_FAILED). Mais ça fonctionne avec clickhouse-client (donc je n'ai pas cherché pourquoi ça ne fonctionnait pas avec /play).
clickhouse-client --secure --host clickhouse.apps.josiane.computablefacts.io --port 9440 --user twr_admin
Je peux faire une requête SQL avec clickhouse-client
ClickHouse client version 25.3.1.2703 (official build).
Connecting to clickhouse.apps.josiane.computablefacts.io:9440 as user twr_admin.
Password for user (twr_admin):
Connecting to clickhouse.apps.josiane.computablefacts.io:9440 as user twr_admin.
Connected to ClickHouse server version 23.3.22.
ClickHouse server version is older than ClickHouse client. It may indicate that the server is out of date and can be upgraded.
Warnings:
* Linux transparent hugepages are set to "always". Check /sys/kernel/mm/transparent_hugepage/enabled
apps.josiane.computablefacts.io :) show databases;
SHOW DATABASES
Query id: cdf813a7-49f1-4aec-8a8e-5fa107769abc
┌─name───────────────┐
1. │ INFORMATION_SCHEMA │
2. │ default │
3. │ information_schema │
4. │ system │
└────────────────────┘
4 rows in set. Elapsed: 0.003 sec.
apps.josiane.computablefacts.io :)
Test du backup de la version actuelle (23.8~ynh1)¶
Je fais un backup avec la commande :
sudo yunohost backup create --name backup01 --apps clickhouse
Backup réussi sans erreur
Info: Collecting files to be backed up for clickhouse…
Info: Declaring files to be backed up...
Info: Backup script completed for clickhouse. (YunoHost will then actually copy those files to the archive).
Info: Creating a backup archive from the collected files…
Info: The archive will contain about 726.6MB of data.
Success! Backup created: backup01
name: backup01
results:
apps:
clickhouse: Success
system:
size: 761894457
Puis je retrouve le nom du fichier :
$ sudo yunohost backup info backup01
created_at: 2025-04-02 14:17:34
description:
path: /home/yunohost.backup/archives/backup01.tar
size: 761894457
Et le fichier existe bien avec la taille annoncée :
$ sudo ls -alh /home/yunohost.backup/archives/backup01.tar
-rw-r--r-- 1 root root 727M Apr 2 14:17 /home/yunohost.backup/archives/backup01.tar
Je n'ai pas essayé de décompresser le backup...
Je suppose donc que le backup fait par YunoHost avant de mettre à jour une application va réussir.
Tests du timer systemd¶
Il est possible de configurer un timer systemd pour lancer des services à intervalle régulier.
Après quelques essais, un timer ne peut pas redémarrer un service directement. Il s'assure que le service est démarré au moment du déclenchement du timer.
Donc, il faut faire un nouveau service qui va redémarrer le service de Clickhouse puis un timer qui va lancer ce nouveau service à intervalle régulier.
J'aboutis donc à un service pour redémarrer clickhouse :
# clickhouse-restart.service
[Unit]
Description=Restart clickhouse service
[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl restart clickhouse-server.service
Et un timer pour lancer le démarrage :
# clickhouse-certificates.timer
[Unit]
Description=Restart clickhouse service to load new TLS certificate if exists
[Timer]
Persistant=true
OnCalendar=Sun *-*-* 01:00:00
RandomizedDelaySec=1h
Unit=clickhouse-restart.service
[Install]
WantedBy=timers.target
Test d'installation clickhouse avec ma nouvelle version¶
La commande pour désinstaller clickhouse :
sudo yunohost app remove clickhouse --purge
La commande pour installer la nouvelle version :
sudo yunohost app install --force https://github.com/computablefacts/clickhouse_ynh/tree/restart_for_certificate --args "domain=clickhouse.apps.josiane.computablefacts.io&path=/&init_main_permission=visitors&admin=twr_admin&password=TestBackup"
Après quelques correctifs, l'installation fonctionne : je peux me connecter à clickhouse avec clickhouse-client et je vois le service clickhouse-restart et le timer clickhouse-certificates. Comme, pour mes tests, j'ai réglé le timer toutes les minutes, je vois aussi clickhouse-server redémarrer toutes les minutes. Enfin, la désinstallation de clickhouse fonctionne aussi et supprime bien le service et le timer.
Test de mise à jour¶
La commande pour désinstaller clickhouse :
sudo yunohost app remove clickhouse --purge
La commande pour installer la version actuelle :
sudo yunohost app install --force https://github.com/computablefacts/clickhouse_ynh/tree/23.8-ynh1 --args "domain=clickhouse.apps.josiane.computablefacts.io&path=/&init_main_permission=visitors&admin=twr_admin&password=TestBackup"
La commande pour mettre à jour avec la nouvelle version :
sudo yunohost app upgrade clickhouse --force --url https://github.com/computablefacts/clickhouse_ynh/tree/restart_for_certificate
Ca ne s'est pas bien passé : quand la mise à jour échoue, YunoHost lance la restauration du backup, la restauration échoue et YunoHost enchaîne avec la désinstallation...
J'ai fini par faire un script qui stocke les md5 des fichiers de l'installation et le résultat de certaines commandes. En lançant ce script après l'installation, après la suppression ou après la restauration, je pourrais comparer les résultats pour savoir si les différents scripts fonctionnent correctement.
J'ai commencé par comparer entre installation et suppression et j'ai fait des correctifs. Puis j'ai amélioré le backup en ajoutant des fichiers, notamment ceux des services.
Mais je n'ai pas réussi à faire la restauration car j'ai des erreurs que je n'ai pas pu corriger.
Je pense que c'est dû à l'installation de clickhouse que je fais, d'après la doc officielle, en téléchargeant des .tar.gz puis en lançant les scripts d'installation.
Cela met en place le service (clickhouse-server.service) et les binaires dans /usr/bin.
Quand j'essaie de backuper le service depuis /lib/systemd/system/clickhouse-server.service puis de le restaurer, je me rends compte que YunoHost a backuppé /usr/lib/systemd/system/clickhouse-server.service et donc n'arrive pas à restaurer /lib/systemd/system/clickhouse-server.service...
Les 2 fichiers existent à ces 2 endroits. Ils sont identiques (mais ce n'est pas un lien).
Quand j'essaie de ne pas backupper ces fichiers mais de relancer les scripts d'installation de Clickhouse, j'ai des erreurs de clickhouse au démarrage du service.
Je pense qu'il y a un ordre à trouver entre arrêt des services et backup puis restauration et remise en place du service. Il y a peut-être aussi une attente à faire pour être sûr que le service est bien arrêté ou démarré car je ne suis pas sûr que YunoHost attende.
Le script que j'ai écrit pour capturer l'état de l'application :
check_install.sh
#!/bin/bash
# Vérifier si les deux arguments ont été fournis
if [ $# -ne 2 ]; then
echo "Usage : $0 <liste_fichiers.txt> <liste_commandes.txt>"
exit 1
fi
# Attribuer les noms de fichiers aux variables
LISTE_FICHIERS="$1"
LISTE_COMMANDES="$2"
# Lire la liste des fichiers et répertoires
while IFS= read -r ligne; do
# Ignorer les lignes vides et les commentaires
if [ -n "$ligne" ] && [ "${ligne:0:1}" != "#" ]; then
# Laisser le shell expander les wildcards
for file in $ligne; do
if [ -f "$file" ]; then
md5sum "$file"
elif [ -d "$file" ]; then
find "$file" -type f -exec md5sum {} \;
else
echo "Erreur : $file n'est ni un fichier ni un répertoire." >&2
fi
done
fi
done < "$LISTE_FICHIERS"
# Lire la liste des commandes
while IFS= read -r commande; do
# Ignorer les lignes vides et les commentaires
if [ -n "$commande" ] && [ "${commande:0:1}" != "#" ]; then
# Exécuter la commande et capturer sa sortie
sortie=$(eval "$commande")
status=$?
# Afficher la commande, son code de retour et sa sortie
echo "Command: $commande"
echo "Code: $status"
echo "$sortie"
fi
done < "$LISTE_COMMANDES"
Il utilise 2 fichiers. Un pour lister les fichiers et les dossiers dont je veux avoir le md5. Un autre pour lister les commandes dont je veux avoir le résultat.
La liste des fichiers pour clickhouse :
clickhouse_files.txt
# Les binaires clickhouse mis en place par l'installation
/usr/bin/clickhouse*
# Répertoire d'installation YunoHost
/var/www/clickhouse
# Répertoire data YunoHost
/home/yunohost.app/clickhouse
# Les répertoires user (liens dans /home/shared)
/home/shared/clickhouse
# Répertoire de configuration de Clickhouse
/etc/clickhouse-server
# Répertoire des logs
/var/log/clickhouse-server
# Configuration nginx de YunoHost
/etc/nginx/conf.d/clickhouse.apps.josiane.computablefacts.io.d/clickhouse.conf
# Le service mis en place par l'installation de Clickhouse
/lib/systemd/system/clickhouse-server.service
/usr/lib/systemd/system/clickhouse-server.service
# Les deux services pour redémarrer Clickhouse pour prendre en compte les certificats
/etc/systemd/system/clickhouse-restart.service
/etc/systemd/system/clickhouse-certificates.timer
La liste des commandes pour clickhouse :
clickhouse_commands.txt
# Check if Clickhouse services are enabled
sudo systemctl is-enabled clickhouse-server.service
sudo systemctl is-enabled clickhouse-restart.service
sudo systemctl is-enabled clickhouse-certificates.timer
# Check if Clickhouse services are started
sudo systemctl is-active clickhouse-server.service
sudo systemctl is-active clickhouse-restart.service
sudo systemctl is-active clickhouse-certificates.timer
# Check service known by YunoHost
sudo yunohost service status clickhouse-server
sudo yunohost service status clickhouse-restart
Pour utiliser le script, je le lance avec les 2 fichiers en paramètre et je redirige la sortie. Par exemple :
sudo ./check_install.sh clickhouse_files.txt clickhouse_commands.txt | tee clickhouse_before.txt
Puis j'utilise diff pour faire la comparaison entre 2 captures. diff -y permet d'avoir les 2 fichiers en regard. Et j'ai même installé colordiff pour que les différences soient plus faciles à voir.
Par exemple :
colordiff -y clickhouse_before.txt clickhouse_after_remove.txt
TODO: à terminer pour mettre au point une mise à jour qui ne plante pas.