Packaging de ClickHouse pour YunoHost¶
Ce document explique comment j'ai packagé ClickHouse pour YunoHost, les choix que j'ai faits pour ça et les difficultés que j'ai rencontrées.
APT, Sources et Version¶
Le package YunoHost a une version et il est d'usage de mettre la même version que celle du produit packagé. Par exemple si je package ClickHouse v24.3, je mettrais une version 24.3~ynh1 à mon package (~ynh1 correspond à la version du package lui-même pour le ClickHouse v24.3).
Mais cela veut dire que le package doit être capable d'installer une version particulière de ClickHouse.
J'ai commencé par vouloir installer ClickHouse avec l'aide des packages APT
(voir https://clickhouse.com/docs/en/install#install-from-deb-packages)
que j'ai définis dans manifest.toml :
#[resources.apt]
# This will automatically install/uninstall the following apt packages
# and implicitly define the $phpversion setting as 8.0 (if phpX.Y-foobar dependencies are listed)
packages = ["apt-transport-https", "ca-certificates", "curl", "gnupg"]
extras.clickhouse.repo = "deb https://packages.clickhouse.com/deb lts main"
extras.clickhouse.key = "https://packages.clickhouse.com/rpm/lts/repodata/repomd.xml.key"
extras.clickhouse.packages = ["clickhouse-server", "clickhouse-client"]
Ca fonctionne mais cela installe la dernière version disponible. J'ai tenté de fixer la version en changeant cette ligne :
extras.clickhouse.packages = ["clickhouse-server=23.3.22.3", "clickhouse-client=23.3.22.3"]
Mais l'installation échouait...
De plus, dans l'esprit des packages YunoHost, APT est utilisé pour installer les dépendances de l'application mais pas l'application elle-même.
J'ai donc basculé vers une installation à partir des "sources" en utilisant les archives .tgz (Voir https://clickhouse.com/docs/en/install#from-tgz-archives).
J'ai fini par cette définition dans manifest.toml :
[resources.sources]
[resources.sources.common-static]
amd64.url = "https://packages.clickhouse.com/tgz/lts/clickhouse-common-static-23.3.22.3-amd64.tgz"
amd64.sha256 = "46a0c6a2842315b750cc3bd1f9eba6b59ab2758595f7e8452814940d3f832360"
[resources.sources.server]
amd64.url = "https://packages.clickhouse.com/tgz/lts/clickhouse-server-23.3.22.3-amd64.tgz"
amd64.sha256 = "fad0ef056785263d7c7cb63bf484fba46aebea3e7e30aff803d503070400ebe2"
[resources.sources.client]
amd64.url = "https://packages.clickhouse.com/tgz/lts/clickhouse-client-23.3.22.3-amd64.tgz"
amd64.sha256 = "b5f52d12a322acfa13066801d195b5fc04e66df467befec908c1d486d8c7565e"
La procédure officielle installe aussi clickhouse-common-static-dbg mais ce n'est pas nécessaire si clickhouse-common-static est déjà installé.
J'ai choisi de rester sur les versions LTS de ClickHouse. On peut avoir la liste des versions de ClickHouse ici : https://github.com/ClickHouse/ClickHouse/tags
Pour une version donnée, on peut télécharger les .tgz correspondants dont la liste se trouve ici pour la version v23.3.22.3-lts : https://github.com/ClickHouse/ClickHouse/releases/tag/v23.3.22.3-lts
On y trouve les sha512 pour chaque package mais YunoHost utilise un sha256 pour vérifier chaque package. J'ai donc dû les calculer. Le plus rapide étant de mettre un sha256 bidon, de lancer l'installation qui va échouer, et de copier-coller le bon sha256 dans le message d'erreur.
Utilisateur debian¶
YunoHost crée un utilisateur linux pour chaque application installée. Cet utilisateur a le même nom que l'ID du package.
J'ai commencé par choisir l'ID clickhouse et j'ai vu à l'installation
de ClickHouse (avec les APT mais peut-être par avec les .tgz) que ClickHouse
créait l'utilisateur (et le groupe) lui aussi. Cela affichait des Warnings.
D'autre part, le modèle de package de YunoHost utilise $app, qui est l'ID,
dans les instructions par défaut comme :
ynh_secure_remove --file="/etc/$app"
ynh_secure_remove --file="/var/log/$app"
Mais ClickHouse utilise les répertoires /etc/clickhouse-server et
/var/log/clickhouse-server.
J'ai donc changé l'ID de clickhouse à clickhouse-server. Mais c'était une
mauvaise idée car l'installation de ClickHouse créait l'utilisateur
clickhouse alors que YunoHost créait l'utilisateur clickhouse-server.
Le service était démarré par clickhouse qui n'arrivait pas à accéder aux
répertoires de données qui appartenait à clickhouse-server...
J'ai donc remis l'ID à clickhouse.
Puis j'ai mis "en dur" les répertoires :
ynh_secure_remove --file="/etc/clickhouse-server"
ynh_secure_remove --file="/var/log/clickhouse-server"
Configuration¶
ClickHouse a 2 fichiers principaux pour sa configuration qui se trouvent dans
/etc/clickhouse-server/ : config.xml et users.xml.
Plutôt que de modifier directement ces fichiers, il est possible de les amender
en ajoutant des fichiers de conf dans /etc/clickhouse-server/config.d ou dans
/etc/clickhouse-server/users.d.
NOTA : les 2 répertoires config.d et users.d étaient créés par
l'installation avec les APT mais pas par l'installation avec les .tgz
J'ai repris les fichiers que j'avais déjà faits pour notre clickhouse pour le Docker Swarm swarm01 et je les ai adaptés.
Comme j'utilise le helper ynh_add_config, je peux utiliser les variables de
YunoHost dans les fichiers de configuration.
Par exemple, avec :
ynh_add_config --template="config.d/paths.xml" --destination="/etc/clickhouse-server/config.d/paths.xml"
Je peux avoir un fichier paths.xml contenant :
<?xml version="1.0"?>
<yandex>
<!-- Path to data directory, with trailing slash. -->
<path>__DATA_DIR__/</path>
<!-- Directory in <clickhouse-path> containing schema files for various input formats.
The directory will be created if it doesn't exist.
-->
<format_schema_path>__DATA_DIR__/format_schemas/</format_schema_path>
<!-- Path to temporary data for processing hard queries. -->
<tmp_path>__DATA_DIR__/tmp/</tmp_path>
<!-- Directory with user provided files that are accessible by 'file' table function. -->
<user_files_path>__DATA_DIR__/user_files/</user_files_path>
</yandex>
NOTA : la configuration résultant de la fusion du fichier config.xml avec
tous les fichiers du répertoire config.d se trouve dans
/home/yunohost.app/clickhouse/preprocessed_configs/config.xml. Idem pour
users.xml. C'est utile pour vérifier le résultat.
Répertoires des données¶
Nous voulons être capable de backuper ClickHouse avec la méthode de backup
intégrée à YunoHost. Cette méthode backupe le contenu du répertoire de données
($data_dir). Nous devons donc mettre les données de ClickHouse dans ce
répertoire.
Le répertoire des données de ClickHouse par défaut est /var/lib/clickhouse/.
J'ai donc remplacé ce répertoire par __DATA_DIR__ partout où il était
utilisé.
Certificats SSL¶
Pour que le port HTTPS (8443) et le port "secure" (9440) puissent fonctionner correctement, il faut fournir des certificats SSL dans la configuration de ClickHouse.
Générer un certificat n'est pas une solution car il serait auto-signé et posserait des problèmes.
L'idée est donc d'utiliser les certificats SSL de Let's Encrypt générés par
YunoHost à l'installation du package ClickHouse. Ces certificats se trouvent
dans le dossier /etc/yunohost/certs/__DOMAIN__/ et sont mis à jour
automatiquement par YunoHost. Il y a deux fichiers : crt.pem et key.pem.
La configuration permettant à ClickHouse d'utiliser ces fichiers est donc :
<yandex>
<openSSL>
<server>
<certificateFile>/etc/yunohost/certs/__DOMAIN__/crt.pem</certificateFile>
<privateKeyFile>/etc/yunohost/certs/__DOMAIN__/key.pem</privateKeyFile>
</server>
</openSSL>
</yandex>
Mais, par défaut, l'utilisateur clickhouse n'a pas l'accès à ce dossier. Je
l'ai donc ajouté au groupe ssl-cert durant la procédure d'installation :
usermod -a -G ssl-cert $app.
nginx¶
L'UI ClickHouse play utilise un Basic Auth pour envoyer les login et mot de passe vers l'API de ClickHouse. Cela entre en conflit avec l'authentification de ClickHouse qui utilise aussi le Basic Auth.
Donc, pour pouvoir utiliser le playground, il faut que l'URL soit accessible
aux visitors. J'ai également supprimé l'ajout pour le SSO. Le fichier de
configuration est donc :
location __PATH__/ {
include proxy_params;
proxy_pass http://127.0.0.1:__PORT__/;
}
Fichiers utilisateur avec le SFTP¶
ClickHouse met à disposition 3 répertoires où un utilisateur peut déposer des fichiers pour les utiliser ensuite depuis les requêtes à ClickHouse.
J'ai défini les 3 répertoires avec ce fichier de configuration :
<yandex>
<user_files_path>__DATA_DIR__/user_files/</user_files_path>
<user_defined_path>__DATA_DIR__/user_defined/</user_defined_path>
<user_scripts_path>__DATA_DIR__/user_scripts/</user_scripts_path>
</yandex>
Pour que les utilisateurs puissent déposer des fichiers dans ces répertoires,
nous voulons leur donner un accès SFTP.
D'abord, nous devons donner le "droit SFTP" depuis YunoHost (par exemple :
sudo yunohost user permission add sftp pbrisacier).
L'utilisateur peut alors se connecter en SFTP avec ses login et mot de passe.
La racine de ce qu'il voit correspond au répertoire /home de la machine.
Afin que tous les utilisateurs puissent déposer et/ou modifier les fichiers pour ClickHouse, nous voulons les rendre accessibles dans un répertoire partagé entre tous les utilisateurs.
La procédure d'install crée ce répertoire /home/shared, y crée un répertoire
clickhouse et donne l'accès en lecture et écriture à tout le monde.
Enfin, la procédure d'install crée les 3 répertoires utilisateur puis les liens vers le dossier data de ClickHouse :
mkdir -p /home/shared/clickhouse/user_files
ln -s /home/shared/clickhouse/user_files $data_dir/user_files
mkdir -p /home/shared/clickhouse/user_defined
ln -s /home/shared/clickhouse/user_defined $data_dir/user_defined
mkdir -p /home/shared/clickhouse/user_scripts
ln -s /home/shared/clickhouse/user_scripts $data_dir/user_scripts
DEBUG / Mise au point¶
Commandes pour installer / désinstaller¶
Depuis le répertoire contenant le package YunoHost, installer avec :
sudo yunohost app install . --debug --force --no-remove-on-failure --args "domain=sentinel-api.towerify.io&path=/clickhouse&init_main_permission=visitors&admin=twr_admin&password=twr-admin"
Désinstaller avec :
sudo yunohost app remove clickhouse --purge
sudo -u twr_admin¶
Voir https://clickhouse.com/docs/en/guides/troubleshooting#start-clickhouse-server-in-interactive-mode
Pour simuler le démarrage du service ClickHouse depuis ma ligne de commande
(en SSH avec l'utilisateur twr_admin), j'ai fait :
sudo -u clickhouse /usr/bin/clickhouse-server --config-file /etc/clickhouse-server/config.xml
NOTA : il faudra saisir le mot de passe de twr_admin
Pour que cela fonctionne, il faut aussi que twr_admin ait les droits sudo
suffisants. Je les ai modifiés (sudo nano /etc/sudoers) pour ajouter :
# User privilege specification
twr_admin ALL=(ALL:ALL) ALL
Utiliser ClickHouse¶
Voir https://clickhouse.com/docs/en/getting-started/quick-start#3-start-the-client
En local, depuis le SSH, je peux lancer clickhouse-client. Par défaut, il se
connecte au ClickHouse Server sur localhost et le port 9000.
On obtient un prompt où on peut faire des requêtes SQL :
twr_admin@sentinel-api:~$ clickhouse-client
ClickHouse client version 23.3.22.3 (official build).
Connecting to localhost:9000 as user default.
Connected to ClickHouse server version 23.3.22 revision 54462.
Warnings:
* Linux transparent hugepages are set to "always". Check /sys/kernel/mm/transparent_hugepage/enabled
sentinel-api.towerify.io :)
Pour tester la connexion sur le port sécurisé (9440), utiliser la commande :
clickhouse-client --secure
TODOs¶
Memory settings
Créer /etc/security/limits.d/clickhouse.conf ?