Date de la publication : 13 octobre 2025

Lecture : 16 min

Kubernetes : gérer les données du cluster côté frontend

Découvrez dans ce guide tout ce que vous devez savoir sur la solution intégrée de GitLab pour surveiller l'état de vos clusters Kubernetes.

Un accès aux informations relatives au cluster en temps réel est essentiel pour vérifier le succès des déploiements logiciels et lancer les processus de dépannage. Dans cet article, vous découvrirez l'intégration Kubernetes améliorée de GitLab et notamment comment exploiter l'API Watch pour obtenir des informations en temps réel sur l'état des déploiements et les fonctionnalités de dépannage optimisées.

Quelles sont les ressources Kubernetes de GitLab ?

GitLab propose un tableau de bord dédié à Kubernetes afin de mieux visualiser l'état des clusters connectés grâce à une interface intuitive. Intégré à la page Détails de l'environnement, il permet d'afficher les ressources pertinentes de l'environnement.

Trois types de ressources Kubernetes sont actuellement disponibles :

Nous fournissons des informations générales telles que le nom, le statut, l'espace de nommage, l'âge, etc., pour ces ressources. Les données sont présentées de manière similaire à ce que la commande kubectl afficherait lorsqu'elle est exécutée depuis le cluster Kubernetes. Il est possible de cliquer sur n'importe quelle ressource pour obtenir plus de détails. Le panneau latéral affiche la liste des labels, des annotations, le statut détaillé et les informations de spécification présentées sous forme de blocs de code YAML en lecture seule, et diffuse en temps réel les événements Kubernetes filtrés pour cette ressource spécifique. En ce qui concerne les pods, les utilisateurs peuvent accéder à une vue dédiée des logs et sélectionner un conteneur afin de diffuser ses logs en temps réel et d'obtenir des informations cruciales pour le débogage.

Les informations fournies aident à visualiser l'état du cluster, à repérer d'éventuels problèmes et à déboguer immédiatement les déploiements problématiques. Les utilisateurs peuvent également agir immédiatement (supprimer les pods en échec, déclencher la réconciliation Flux ou suspendre/reprendre la synchronisation), le tout depuis la même interface sans avoir besoin de basculer vers des outils en ligne de commande.

Communication frontend-cluster : la solution GitLab

Nous avons développé une gamme d'outils et de solutions pour garantir une connexion et une gestion fluides des clusters Kubernetes dans GitLab. L'agent GitLab pour Kubernetes est l'un des principaux composants de ce système et offre une connexion bidirectionnelle sécurisée entre une instance GitLab et un cluster Kubernetes. Cet outil puissant est composé de deux composants clés : agentk et KAS (GitLab Agent Server for Kubernetes).

Graphique du flux Kubernetes

agentk est un composant léger côté cluster qui établit une connexion à une instance KAS et attend les requêtes à traiter. Il sert de proxy pour les requêtes KAS vers l'API Kubernetes. Il peut également envoyer activement des informations sur les événements du cluster à KAS.

Alors qu'agentk communique activement avec le cluster, KAS est un composant côté serveur GitLab qui :

  • Accepte les requêtes d'agentk

  • Authentifie les requêtes d'agentk en interrogeant le backend GitLab

  • Récupère la configuration de l'agent depuis un dépôt Git correspondant en utilisant Gitaly

  • Interroge les dépôts de manifestes pour la prise en charge de GitOps

Nous avons implémenté la fonctionnalité relative aux droits d'accès de l'agent pour fournir un accès du frontend GitLab au cluster de manière sécurisée et fiable. Pour activer cette fonctionnalité, l'utilisateur doit mettre à jour le fichier de configuration de l'agent en ajoutant la section user_access avec les paramètres projects, groups et access_as afin de préciser les projets qui peuvent accéder aux informations du cluster via l'agent et la manière dont il doit s'authentifier.

Le frontend peut ensuite se connecter au cluster en envoyant une requête au contrôleur Rails, qui doit définir un cookie gitlab_kas. Ce cookie est ensuite ajouté à la requête envoyée à KAS avec l'ID de l'agent et le token Cross-Site Request Forgery (CSRF). À la réception de la requête, KAS vérifie l'autorisation de l'utilisateur et la transmet à agentk, qui effectue une requête réelle à l'API Kubernetes. Ensuite, la réponse remonte et passe par agentk et KAS avant de finalement arriver au client GitLab.

Aperçu du fonctionnement de Kubernetes overview

Pour intégrer cette logique dans le frontend GitLab et l'utiliser dans l'application Vue, nous avons développé une bibliothèque JavaScript (@gitlab/cluster-client) générée à partir de la spécification OpenAPI Kubernetes au moyen du générateur typescript-fetch. Elle fournit toutes les API Kubernetes qui peuvent être utilisées dans un navigateur web, ainsi que notre classe WebSocketWatchManager qui gère l'API Watch Aggregator et fournit des mises à jour efficaces en temps réel.

Présentation de l'API Watch

Les mises à jour en temps réel représentent le défi le plus important du tableau de bord Kubernetes. Dans Kubernetes, le concept de commandes watch est une extension des requêtes GET qui permet d'afficher le contenu du corps sous forme de flux lisible. Une fois connecté au flux, l'API Kubernetes transmet les mises à jour de l'état du cluster de manière similaire à la commande kubectl get <resource> --watch. Le mécanisme de surveillance permet au client de récupérer l'état actuel de la ressource (ou de la liste de ressources) puis de s'abonner aux changements ultérieurs afin de ne rien manquer. Chaque événement contient un type de modification (ajout, modification ou suppression) et l'objet concerné.

Au sein de la classe WatchApi de la bibliothèque @gitlab/cluster-client, nous avons développé une approche systématique pour interagir avec l'API Kubernetes, qui consiste à récupérer un flux continu de données, à le traiter ligne par ligne et à gérer les événements en fonction de leurs types. Explorons les principaux composants et fonctionnalités de cette approche :

  1. Extension de l'API Kubernetes : au sein de la classe WatchApi, nous étendons les fonctionnalités de base de l'API Kubernetes pour récupérer un flux continu de données avec un chemin et des paramètres de requête spécifiés. Cette extension permet une gestion efficace des grands ensembles de données, car le flux est traité ligne par ligne.

  2. Décodage et catégorisation des événements : à la réception du flux, chaque ligne, qui représente généralement un objet JSON, est décodée. Ce processus extrait les informations pertinentes et catégorise les événements en fonction de leurs types.

  3. Gestion interne des données : la classe WatchApi maintient un tableau de données interne pour indiquer l'état actuel des données diffusées. Elle le met à jour en conséquence à mesure que de nouvelles données arrivent ou que des modifications se produisent.

  4. Enregistrement d'écouteurs d'événements : la classe WatchApi implémente des méthodes pour enregistrer des écouteurs d'événements, tels que onData, onError, onTimeout, et onTerminate. Ces méthodes permettent aux équipes de développement de personnaliser la réponse de leur application aux événements tels que les mises à jour de données, les erreurs et les délais d'attente dépassés.

Le code gère également des scénarios tels que les types de contenu non valides, les délais d'attente dépassés et les erreurs du serveur, pour lesquels il émet des événements correspondants afin que les clients puissent les traiter de manière appropriée. Cette approche simple et axée sur les événements de la classe WatchApi permet aux équipes de développement de créer en toute efficacité des applications réactives en temps réel.

Aperçu du flux Kubernetes overview

Évolution vers l'agrégation WebSocket

Nous nous sommes basés sur l'API Watch et avons introduit le WebSocketWatchManager pour répondre aux limitations des flux lisibles : le sous-protocole WebSocket gitlab-agent-watch-api agrège plusieurs commandes watch de ressources au sein d'une seule connexion persistante.

Cette approche apporte plusieurs améliorations :

  • Plusieurs commandes watch via une connexion unique : au lieu d'ouvrir des flux HTTP séparés pour chaque ressource Kubernetes, elles partagent toutes une seule connexion WebSocket. Les problèmes de connexion côté client et serveur sont ainsi considérablement réduits, un aspect particulièrement important lors de la surveillance de nombreuses ressources dans différents espaces de nommage.

  • Gestion dynamique des commandes watch : le protocole prend en charge le démarrage et l'arrêt de commandes watch individuelles à la demande via des messages watch et unwatch. La fonctionnalité unwatch n'est pas encore implémentée dans le client JavaScript, mais une fois ajoutée, elle arrêtera les commandes watch inutiles lorsque les utilisateurs quittent les vues de ressources.

  • Connexions plus fiables : les connexions WebSocket maintiennent des sessions stables et durables sans les interruptions imprévisibles que nous avons rencontrées avec le streaming basé sur HTTP de l'API Watch. Ces connexions de streaming s'interrompaient parfois de manière inattendue, nécessitaient une logique de reconnexion et risquaient potentiellement de manquer des événements pendant la fenêtre de reconnexion.

Lors de l'établissement d'une connexion, le client doit d'abord demander un token d'authentification, car les connexions WebSocket ne peuvent pas envoyer d'en-têtes personnalisés (comme les tokens CSRF ou les cookies) après la communication initiale. Ce token, obtenu via une requête HTTP standard avec des en-têtes d'authentification complets, est ensuite intégré dans l'en-tête du sous-protocole WebSocket lors de l'établissement de la connexion. Une fois connecté au point de terminaison /watch, le client démarre des commandes watch individuelles en envoyant des messages avec des paramètres de ressource, et le serveur renvoie en continu les événements watch à mesure que les ressources Kubernetes changent.

Le système revient à l'implémentation WatchApi d'origine lorsque les connexions WebSocket échouent pour une raison quelconque, que ce soit en raison de limitations d'infrastructure réseau, d'échecs de connexion ou de problèmes d'authentification. Cette double approche offre les avantages de performance WebSocket lorsque ceux-ci sont disponibles et maintient une fonctionnalité complète grâce à la méthode de streaming de l'API Watch si nécessaire. Le basculement se fait automatiquement et garantit une fonctionnalité en temps réel et cohérente qui ne requiert aucune connaissance ni intervention de l'utilisateur.

Comment la vue d'ensemble Kubernetes est-elle intégrée au frontend GitLab ?

Nous avons actuellement deux intégrations Kubernetes dans le produit : la section Vue d'ensemble Kubernetes pour les Environnements et le tableau de bord Kubernetes complet comme vue séparée. Ce dernier représente le fruit de nos efforts en vue d'afficher toutes les ressources Kubernetes disponibles avec des fonctionnalités de filtrage et de tri, et une vue détaillée avec des informations complètes sur les métadonnées, les spécifications et le statut de la ressource. Ce projet est actuellement en pause, car nous sommes en train d'explorer comment afficher les ressources Kubernetes liées à un environnement de la façon la plus utile possible.

La vue d'ensemble Kubernetes sur la page Environnements représente une vue détaillée des ressources Kubernetes liées à un environnement spécifique. Pour accéder à la vue de l'état du cluster, l'utilisateur doit sélectionner un agent installé dans le cluster avec les droits d'accès appropriés, fournir un espace de nommage (facultatif) et sélectionner une ressource Flux associée.

La vue affiche une liste de pods et de services Kubernetes filtrés par l'espace de nommage avec leurs statuts et le statut de synchronisation Flux. Cliquer sur chaque ressource ouvre une vue détaillée avec plus d'informations pour faciliter la détection des problèmes et le débogage de haut niveau.

Aperçu de Kubernetes, liste des pods et services Kubernetes

Nous devons paramétrer un objet de configuration correct qui sera utilisé pour toutes les requêtes API. Dans la configuration, nous devons préciser l'URL fournie par le KAS, qui sert de proxy pour les API Kubernetes, l'ID de l'agent GitLab auquel se connecter et le token CSRF. Nous devons inclure les cookies pour que le kas_cookie soit récupéré et envoyé dans la requête.


createK8sAccessConfig({ kasTunnelUrl, gitlabAgentId }) {
  return {
    basePath: kasTunnelUrl,
    headers: {
      'GitLab-Agent-Id': gitlabAgentId,
      ...csrf.headers,
    },
    credentials: 'include',
  };
}

Cet objet de configuration sert de base pour toutes les interactions avec l'API Kubernetes via KAS, que ce soit en utilisant des appels API standard, le streaming de l'API Watch ou les connexions WebSocket. Chaque méthode de connexion s'appuie sur cette configuration de base avec ses exigences spécifiques.

Toutes les requêtes API sont implémentées sous forme de requêtes client GraphQL pour une meilleure efficacité, flexibilité et facilité de développement. La structure de requête permet aux clients de récupérer des données provenant de diverses sources en une seule requête. Grâce à des définitions de schéma claires, GraphQL minimise les erreurs et renforce l'efficacité des équipes de développement. L'implémentation WebSocket complète cette approche avec une gestion des mises à jour en temps réel via une connexion unique persistante, ce qui réduit le besoin de multiples connexions de streaming parallèles et maintient la même structure de requête GraphQL pour les mises à jour de données.

Lors du premier affichage de la vue d'ensemble Kubernetes, le frontend demande des listes statiques de pods, services et ressources Flux (HelmRelease ou Kustomization). La requête de récupération est nécessaire pour afficher correctement la vue vide. Si le frontend essayait de s'abonner au flux de l'API Watch et qu'une des listes de ressources était vide, il faudrait alors attendre les mises à jour indéfiniment, et le résultat réel, soit 0 ressource, ne serait jamais affiché. Dans le cas des pods et services, après la requête initiale, nous nous abonnons au flux même si une liste vide a été reçue afin de refléter tout changement d'état du cluster. En ce qui concerne la ressource Flux, la probabilité que l'utilisateur s'attende à ce qu'une ressource apparaisse après la requête initiale est faible. Nous utilisons la réponse vide ici en vue de fournir plus d'informations sur la fonctionnalité et sa configuration.

Aperçu de Kubernetes, synchronisation du statut du flux non disponible

Après avoir affiché le résultat initial, le frontend établit des connexions en temps réel pour surveiller les changements. L'implémentation tente d'abord la connexion WebSocket et se rabat sur le streaming de l'API Watch lorsqu'elle n'est pas disponible. Avec les connexions WebSocket, une seule connexion gère toutes les commandes watch de ressources, maintient des flux internes pour chaque ressource et les met à jour en fonction des événements entrants (ADDED, MODIFIED, DELETED). En mode de solution alternative API Watch, le frontend effectue des requêtes avec le paramètre de requête ?watch=true et crée des watchers séparés pour chaque type d'événement :


watcher.on(EVENT_DATA, (data) => {
  result = data.map(mapWorkloadItem);
  client.writeQuery({
    query,
    variables: { configuration, namespace },
    data: { [queryField]: result },
  });

  updateConnectionStatus(client, {
    configuration,
    namespace,
    resourceType: queryField,
    status: connectionStatus.connected,
  });
});

Les deux approches suivent le même modèle de traitement des données :

  • Transformer les données pour assurer une structure cohérente

  • Mettre à jour le cache Apollo pour déclencher les mises à jour de l'interface utilisateur

  • Exécuter une mutation pour mettre à jour l'indicateur d'état de connexion

Étant donné que les informations détaillées sont affichées pour chaque ressource, nous devons pouvoir consulter les champs statut, spécifications et métadonnées avec annotations et labels. L'API Kubernetes n'envoie pas toujours ces informations, ce qui pourrait mettre à mal l'interface utilisateur et générer des erreurs du client GraphQL. Il faut d'abord transformer les données reçues pour éviter ces problèmes, et ajouter __typename afin de mieux définir les types de données et simplifier les requêtes en réutilisant les fragments partagés.

Après la stabilisation des données, nous mettons à jour le cache Apollo pour que le frontend puisse afficher de nouveau les vues afin de refléter les changements d'état du cluster. Il est intéressant de constater que nous pouvons visualiser exactement ce qui se passe dans le cluster : par exemple, lors de la suppression des pods, Kubernetes en crée de nouveaux avec un état en attente, puis il supprime les anciens pods. Ainsi, il est possible de voir deux fois plus de pods qu'escompté pendant un bref instant. Nous pouvons également vérifier comment les pods passent d'un état à un autre en temps réel. Pour ce faire, il nous suffit de combiner les événements ajoutés, supprimés et modifiés reçus des API Kubernetes et traités soit par le WebSocketWatchManager, soit par la classe WatchApi de la bibliothèque @gitlab/cluster-client.

Aperçu de Kubernetes, états des statuts de connexion

L'indicateur d'état de connexion est un élément important pour les deux types de connexion, bien que pour des raisons différentes. Même si les connexions WebSocket sont plus stables et durables, les utilisateurs doivent pouvoir savoir si la connexion est interrompue en raison de problèmes réseau ou d'authentifications expirées. Avec le streaming de l'API Watch, les connexions ont des limitations dues aux délais d'attente dépassés et sont davantage sujettes à la déconnexion. Pour obtenir une meilleure visibilité à ce sujet, nous avons introduit une requête k8sConnection avec la mutation reconnectToCluster. L'interface utilisateur affiche un badge avec une infobulle qui indique trois états de connexion :

  • Connexion en cours : défini lors de l'initiation de l'une ou l'autre connexion

  • Connecté : mis à jour lorsque les premières données arrivent via l'une ou l'autre connexion

  • Déconnecté : déclenché en cas d'échec de connexion WebSocket, d'expiration des flux API Watch, ou d'erreur de connexion

En cas de déconnexion, les utilisateurs peuvent cliquer pour se reconnecter sans actualiser le navigateur. En comptant sur l'utilisateur pour se reconnecter au flux, nous pouvons économiser des ressources et ne demander que les données nécessaires tout en garantissant que l'état précis du cluster est disponible pour l'utilisateur à tout moment.

Et maintenant ?

La fonctionnalité intégrée de Kubernetes pour surveiller le flux lisible nous a aidés à développer rapidement cette fonctionnalité et à fournir une solution d'interface utilisateur Kubernetes à nos clients, à obtenir des retours précoces et à ajuster le produit. Bien que l'approche initiale de l'API Watch présente des défis comme les délais d'attente dépassés de connexion et les besoins de reconnexion, elle nous a donné des informations précieuses sur les modèles d'utilisation réels. L'implémentation WebSocket a résolu bon nombre de ces défis initiaux et a offert des connexions plus stables ainsi qu'une meilleure efficacité des ressources grâce aux commandes watch multiplexées. Les deux approches API Watch et WebSocket continueront d'évoluer en fonction des besoins des utilisateurs.

Il existe des solutions qui pourraient améliorer davantage l'expérience utilisateur. Le protocole WebSocket prend déjà en charge les messages unwatch pour la gestion dynamique des commandes watch, même s'il n'est pas encore implémenté dans le client JavaScript. Une gestion des erreurs plus complète et la prise en charge de types de ressources Kubernetes supplémentaires pourraient également renforcer les fonctionnalités du tableau de bord.

Vous souhaitez contribuer à la fonctionnalité du tableau de bord Kubernetes, explorer les possibilités d'amélioration ou partager vos cas d'utilisation ? Partagez vos retours dans notre epic Tableau de bord Kubernetes.

Votre avis nous intéresse

Cet article de blog vous a plu ou vous avez des questions ou des commentaires ? Partagez vos réflexions en créant un sujet dans le forum de la communauté GitLab.
Share your feedback

Plus de 50 % des entreprises du classement Fortune 100 font confiance à GitLab

Commencez à livrer des logiciels de meilleurs qualité plus rapidement

Découvrez comment la plateforme DevSecOps intelligente

peut aider votre équipe.