Lorsque tous les résultats des traitements de nuit, des tâche automatiques, sont envoyés vers votre adresse email
çà devient vite le bord… Contrôle de ceci, contrôle de cela, La lecture des emails devient très complexe et fatiguante.
Healtchecks, c’est un tableau de bord qui indique ce qui s’est bien passé et ce qui est en défaut.
Comment ca marche ? Vous exécuter la tâche, après son exécutionn vous ajouter simplement une ligne de code (curl par exemple) qui appelle l’application “healthchecks”, avec un identifiant unique et l’état du traitement (code retour de la commande par exemple 0 est OK en shell).
Cette identifiant est attribué à la tâche déclarée sur l’application “healthchecks”. Une fois la tâche créée sur l’application, celle-ci vous donne l’url unique à coller dans vos scripts (plusieurs langages supportés).
Donc le matin si tous s’est bien passé tout est vert, ou bien c’est la guirlande multicolore :)
Une tâche enregistrée sur “healthchecks” doit avoir été appellée dans le temps imparti, si ce n’est pas le cas, le tableau de bord devient rouge et il est possible d’envoyer des alertes vers plusieurs types de supports : mail, matrix,…
Installer “healthchecks” dans le cluster Kubernetes
En suivant les recommandations de “Pēteris Caune - Healthchecks Team”
Pré-requis
- Cluster kubernetes opérationnel
- Service Postgresql (persistence des données)
- Vous savez exposer un service réseau kubernetes (haproxy, traefic,…)
Base de données postgresql
Créer une base de données pour l’applicatif “healthchecks”. Cette base de donnée devra être accessible de tous les “Workers” du cluster kubernetes (paramétrage pg_hba.conf nécessaire).
Exemple :
- Nom de la base de données : hc
- Utilisateur postgresql : hc
- Mot de passe de l’utilisateur postgresql : mypassword
Connecté au serveur postgresql :
su - postgres
psql
CREATE USER hc with password 'mypassword';
CREATE DATABASE hc WITH TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'en_US.UTF-8' LC_CTYPE = 'en_US.UTF-8';
GRANT ALL PRIVILEGES ON DATABASE hc to hc;
\q
exit
Modifiez le fichier pg_hba.conf pour que la nouvelle base de données “healthchecks” soit accessible de tous les workers du cluster Kubernetes.
Exemple, mon cluster kubernetes comporte deux “Workers”, dont les adresses IP respectives sont :
- 192.168.1.20
- 192.168.1.21
Ajoutez au fichier pg_hba.conf :
host hc hc 192.168.1.20/32 md5
host hc hc 192.168.1.21/32 md5
puis exécuter : systemctl reload postgresql
Les informations de comptes (utilisateur/mot de passe, addresseIP/port du serveur postgresql) seront nécessaires pour effectuer le paramétrage de “healthchecks”.
Installation de “healthchecks”
Vous êtes maintenant habitués à utiliser les “manifests” Kubernetes, qui décrivent les opérations à réaliser dans le cluster. Nous allons créer le descriptif de déploiement de l’application “healthchecks”.
Manifest de déploiement
Dans cet ordre :
- Création du “namespace”
- Création du “Secret” pour les variables d’environnement
- Création d’une “ConfigMap” fichier de configurationt “uwsgi.ini”
- Création d’une “ConfigMap” optionel, seulement si vous ne pouvez pas agir sur la configuration des loadbalancers, Permet de résoudre le problème csrf django rencontré lors de la connexion à l’application, voir: chapitre TLS Termination
- Création de “LimitRange” à adapter selon votre architecture
- Création du “Deployment”, container readonly et user/group 999 (id user du container)
- Création du “Service”
Contenu du fichier “manifest.yml” :
apiVersion: "v1"
kind: "Namespace"
metadata:
name: "healthchecks"
labels:
name: "healthchecks"
---
apiVersion: v1
kind: "Secret"
metadata:
name: "healthchecks-secret-envvars"
namespace: "healthchecks"
type: "Opaque"
stringData:
# Needed if impossible to set loadbalancer : https://healthchecks.io/docs/self_hosted_docker/ - see TLS Termination
CSRF_TRUSTED_ORIGINS: "https://yourdomain"
SECRET_KEY: "xxxxxxxxxxxxxxxxxxxxx"
DEBUG: "False"
SITE_ROOT: "https://yourdomain"
SITE_NAME: "whatyouwant"
ALLOWED_HOSTS: "yourdomain"
DB: "postgres"
DB_TARGET_SESSION_ATTRS: "read-write"
DB_USER: "hc"
DB_HOST: "yourpostgresqlserver hostname or ip address"
DB_NAME: "hc"
DB_PASSWORD: "postgres hc user password"
# Ne pas autoriser les "auto inscriptions", vous pourriez avoir des surprises
# un healthcheck en libre service ??
REGISTRATION_OPEN: "False"
DEFAULT_FROM_EMAIL: "healthchecks@yourdomain"
EMAIL_HOST: "STMP host"
EMAIL_HOST_USER: "credential login smtp"
EMAIL_HOST_PASSWORD: "credential password smtp"
EMAIL_PORT: "Smtp port 465|587"
EMAIL_USE_TLS: "True"
---
apiVersion: "v1"
kind: "ConfigMap"
metadata:
name: "uwsgi-ini-configmap-healthchecks"
namespace: "healthchecks"
data:
uwsgi.ini: |+
[uwsgi]
master
die-on-term
http-socket = :8000
harakiri = 10
post-buffering = 4096
# la version originale indique processes = 4
# Performances ok sur raspberry PI4 avec 1 et limitrange max cpu 1000m
processes = 1
enable-threads
threads = 1
chdir = /opt/healthchecks
module = hc.wsgi:application
thunder-lock
disable-write-exception
hook-pre-app = exec:./manage.py migrate
attach-daemon = ./manage.py sendalerts
attach-daemon = ./manage.py sendreports --loop
---
# Needed if impossible to set loadbalancer : https://healthchecks.io/docs/self_hosted_docker/ - see TLS Termination
apiVersion: "v1"
kind: "ConfigMap"
metadata:
name: "local-settings-py-configmap-healthchecks"
namespace: "healthchecks"
data:
local_settings.py: |+
import os
CSRF_TRUSTED_ORIGINS = os.getenv("CSRF_TRUSTED_ORIGINS", "").split(",")
---
apiVersion: "v1"
kind: "LimitRange"
metadata:
name: "limitrange-healthchecks"
namespace: "healthchecks"
spec:
limits:
- default:
cpu: "1000m"
memory: "300Mi"
defaultRequest:
cpu: "150m"
memory: "200Mi"
max:
cpu: "1000m"
memory: "300Mi"
min:
cpu: "150m"
memory: "200Mi"
type: Container
---
apiVersion: "apps/v1"
kind: "Deployment"
metadata:
name: "healthchecks"
namespace: "healthchecks"
spec:
revisionHistoryLimit: 1
strategy:
type: "Recreate"
selector:
matchLabels:
app: "healthchecks"
replicas: 1
template:
metadata:
labels:
app: "healthchecks"
spec:
securityContext:
runAsUser: 999
runAsGroup: 999
containers:
- name: "healthchecks"
env:
- name: "CSRF_TRUSTED_ORIGINS"
valueFrom:
secretKeyRef:
name: "healthchecks-secret-envvars"
key: "CSRF_TRUSTED_ORIGINS"
optional: false
- name: "SECRET_KEY"
valueFrom:
secretKeyRef:
name: "healthchecks-secret-envvars"
key: "SECRET_KEY"
optional: false
- name: "DEBUG"
valueFrom:
secretKeyRef:
name: "healthchecks-secret-envvars"
key: "DEBUG"
optional: false
- name: "SITE_ROOT"
valueFrom:
secretKeyRef:
name: "healthchecks-secret-envvars"
key: "SITE_ROOT"
optional: false
- name: "SITE_NAME"
valueFrom:
secretKeyRef:
name: "healthchecks-secret-envvars"
key: "SITE_NAME"
optional: false
- name: "ALLOWED_HOSTS"
valueFrom:
secretKeyRef:
name: "healthchecks-secret-envvars"
key: "ALLOWED_HOSTS"
optional: false
- name: "DB"
valueFrom:
secretKeyRef:
name: "healthchecks-secret-envvars"
key: "DB"
optional: false
- name: "DB_TARGET_SESSION_ATTRS"
valueFrom:
secretKeyRef:
name: "healthchecks-secret-envvars"
key: "DB_TARGET_SESSION_ATTRS"
optional: false
- name: "DB_USER"
valueFrom:
secretKeyRef:
name: "healthchecks-secret-envvars"
key: "DB_USER"
optional: false
- name: "DB_HOST"
valueFrom:
secretKeyRef:
name: "healthchecks-secret-envvars"
key: "DB_HOST"
optional: false
- name: "DB_NAME"
valueFrom:
secretKeyRef:
name: "healthchecks-secret-envvars"
key: "DB_NAME"
optional: false
- name: "DB_PASSWORD"
valueFrom:
secretKeyRef:
name: "healthchecks-secret-envvars"
key: "DB_PASSWORD"
optional: false
- name: "REGISTRATION_OPEN"
valueFrom:
secretKeyRef:
name: "healthchecks-secret-envvars"
key: "REGISTRATION_OPEN"
optional: false
- name: "DEFAULT_FROM_EMAIL"
valueFrom:
secretKeyRef:
name: "healthchecks-secret-envvars"
key: "DEFAULT_FROM_EMAIL"
optional: false
- name: "EMAIL_HOST"
valueFrom:
secretKeyRef:
name: "healthchecks-secret-envvars"
key: "EMAIL_HOST"
optional: false
- name: "EMAIL_HOST_PASSWORD"
valueFrom:
secretKeyRef:
name: "healthchecks-secret-envvars"
key: "EMAIL_HOST_PASSWORD"
optional: false
- name: "EMAIL_HOST_USER"
valueFrom:
secretKeyRef:
name: "healthchecks-secret-envvars"
key: "EMAIL_HOST_USER"
optional: false
- name: "EMAIL_PORT"
valueFrom:
secretKeyRef:
name: "healthchecks-secret-envvars"
key: "EMAIL_PORT"
optional: false
- name: "EMAIL_USE_TLS"
valueFrom:
secretKeyRef:
name: "healthchecks-secret-envvars"
key: "EMAIL_USE_TLS"
optional: false
image: "healthchecks/healthchecks:v2.1"
# imagePullPolicy : Always IfNotPresent None
imagePullPolicy: "Always"
securityContext:
readOnlyRootFilesystem: true
ports:
- containerPort: 8000
protocol: "TCP"
name: "port-8000"
volumeMounts:
- mountPath: "/opt/healthchecks/docker/uwsgi.ini"
name: "configmapvol-uwsgi-ini"
subPath: "uwsgi.ini"
# Needed if impossible to set loadbalancer : https://healthchecks.io/docs/self_hosted_docker/ - see TLS Termination
- mountPath: "/opt/healthchecks/hc/local_settings.py"
name: "configmapvol-local-settings-py"
subPath: "local_settings.py"
volumes:
- name: "configmapvol-uwsgi-ini"
configMap:
name: "uwsgi-ini-configmap-healthchecks"
# Needed if impossible to set loadbalancer : https://healthchecks.io/docs/self_hosted_docker/ - see TLS Termination
- name: "configmapvol-local-settings-py"
configMap:
name: "local-settings-py-configmap-healthchecks"
---
apiVersion: "v1"
kind: "Service"
metadata:
name: "healthchecks-app-port-0-8000"
namespace: "healthchecks"
spec:
type: "NodePort"
ports:
- port: 8000
protocol: "TCP"
targetPort: 8000
name: "port-healthchecks-8000"
selector:
app: "healthchecks"
---
Pour installer, exécuter, à partir du master kubernetes :
kubectl apply -f manifest.yml
Connexion à l’ihm “healthchecks”
L’applicatif est démarrée, le service reseau est effectif, ouvrir votre navigateur, puis indiquer l’url d’accès au service ex : https://monurlhealthchecks. Il s’agit de la première connexion, vous ne pourrez pas vous y connecter.
Il faut d’abord créer un “superuser”.
Pour exécuter cette opération, démarrer un shell dans le container “healthcheck” sur votre cluster kubernetes, puis exécuter la commande :
./manage.py createsuperuser
# Vous devrez entrer votre adresse email, un mot de passe et sa confirmation
# Pour abandonner CTRL+C
Retourner sur votre navigateur web et connectez-vous à l’application avec ce compte et son mot de passe.
Alertes
Si n’avez encore visité le site , je vous invite a regarder la partie Notifications, pour chaque cas désiré, vous devrez agir sur la configuration du container (non abordé ici).
Conclusion
Cet outil est génial et facilite grandement la vie de l’administrateur système…
+++