L’une des fonctionnalités les plus appréciées de Maintenant est l’auto-découverte : déployez le conteneur, et tous vos services apparaissent dans le dashboard sans configuration. Voici comment ça fonctionne.
Détection du runtime
Au démarrage, Maintenant exécute une séquence de détection :
- Vérifie la présence du fichier
/var/run/secrets/kubernetes.io/serviceaccount/token - Si trouvé → mode Kubernetes avec in-cluster config
- Sinon, tente de se connecter au socket Docker (
/var/run/docker.sock) - Si trouvé → mode Docker
- La variable
MAINTENANT_RUNTIMEpermet de forcer un mode spécifique
Cette détection prend moins de 100ms au démarrage.
Mode Docker
En mode Docker, Maintenant utilise le SDK Docker officiel pour Go. Il se connecte au socket Unix monté en lecture seule et effectue plusieurs opérations :
Listing initial
Un appel à ContainerList avec le filtre status=running récupère tous les conteneurs actifs. Pour chaque conteneur, Maintenant extrait les labels Docker, le projet Compose (via le label com.docker.compose.project), les ports exposés, et la configuration de health check.
Écoute des événements
Un goroutine dédié écoute les événements Docker en temps réel via Events. Chaque événement start, stop, die, health_status est capté et traité immédiatement. C’est ce qui permet au dashboard de se mettre à jour en temps réel via SSE.
Collecte de métriques
L’API Docker ContainerStats fournit les métriques CPU, mémoire, réseau et I/O disque par conteneur. Maintenant les collecte à intervalle régulier et les stocke dans SQLite.
Mode Kubernetes
En mode Kubernetes, Maintenant utilise le client-go officiel avec la configuration in-cluster (service account). Le RBAC nécessaire est minimal et en lecture seule :
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: maintenant-reader
rules:
- apiGroups: [""]
resources: ["pods", "services", "events"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments", "daemonsets", "statefulsets"]
verbs: ["get", "list", "watch"]
Maintenant ne crée, ne modifie et ne supprime jamais rien dans votre cluster. Observation uniquement.
Workloads
Contrairement au mode Docker qui raisonne en conteneurs, le mode Kubernetes raisonne en workloads : Deployments, DaemonSets, StatefulSets. Les pods sont regroupés sous leur workload parent, offrant une vue plus pertinente de l’état de vos services.
Le stockage : SQLite en WAL mode
Toutes les données collectées sont stockées dans SQLite en mode WAL (Write-Ahead Logging). Ce choix permet des lectures concurrentes sans bloquer les écritures — essentiel pour un outil qui collecte des métriques en continu tout en servant un dashboard temps réel.
L’empreinte mémoire reste minimale (~17 MB au repos) grâce à une gestion stricte des goroutines et au garbage collector de Go.
Conclusion
L’auto-découverte n’est pas de la magie. C’est l’utilisation intelligente des APIs existantes de Docker et Kubernetes, combinée à une architecture Go légère et des choix de stockage simples.
Le résultat : vous déployez un conteneur, et votre stack est monitorée. Sans configuration.