Dans le cas où les volumes persistants de Kubernetes sont stockés par une interface de stockage pour conteneur (CSI), la supervision native de Kubernetes ne couvre pas leurs taux de remplissage et donc ne donne pas la visibilité permettant d’adapter leur dimensionnement. Dans cet article, nous allons voir comment utiliser Zabbix pour superviser les nœuds d’un cluster Kubernetes et notamment ses volumes persistants.

Pour cela, nous allons commencer par déployer des agents Zabbix sur les nœuds du cluster Kubernetes, ce qui permettra d’inspecter les points de montage des volumes persistants, et de déployer un proxy pour amasser les données des agents. Nous verrons ensuite comment correctement configurer Zabbix, et nous terminerons par l’automatisation de la configuration de Zabbix par Ansible.

Déploiement d’un proxy Zabbix et des agents sur les nœuds Kubernetes

Pour déployer Zabbix sur Kubernetes, nous allons utiliser Helm, qui va installer les composants nécessaires au proxy Zabbix et aux agents sur les nœuds. Pour que l’agent Zabbix soit déployé sur chacun des nœuds, un DaemonSet doit être utilisé.

Cloner le dépôt Helm de Zabbix :

$ git clone https://git.zabbix.com/scm/zt/kubernetes-helm.git

Il faut ensuite modifier les valeurs qui sont passées à Helm du fichier values.yaml. Plus spécifiquement, il faudra a minima modifier le nom du proxy Zabbix en modifiant la variable d’environnement ZBX_HOSTNAME, le nom du serveur Zabbix avec ZBX_SERVER_HOST, et mettre la variable hostNetwork à false pour cloisonner l’environnement réseau des agents Zabbix et ne pas les rendre accessible en dehors du réseau Kubernetes. Pour que l’agent Zabbix puisse accéder à tous les points de montage des nœuds, modifier le contexte de sécurité pour permettre à l’agent de tourner en tant que l’utilisateur root.

D’autres modifications peuvent être nécessaires, comme l’ajout de tolérances pour spécifier les nœuds sur lesquels le proxy et les agents seront déployés, spécifier l’image utilisée ou ajouter des requêtes ou limites Kubernetes.

Une fois les valeurs configurées, installer le proxy Zabbix et les agents :

$ oc new-project monitoring-kube-node
$ helm install zabbix . --dependency-update -f values.yaml -n monitoring-kube-nodes

Vérifier le bon déploiement :

$ oc get pods
NAME                                         READY   STATUS    RESTARTS   AGE
zabbix-agent-nbzdm                           1/1     Running   0          20h
zabbix-agent-tb8wg                           1/1     Running   0          20h
zabbix-kube-state-metrics-6644c6cc78-bjtm2   1/1     Running   0          20h
zabbix-proxy-8697d45854-zc6j6                1/1     Running   0          20h

Le nombre d’agent dépend des tolérances du DaemonSet et de la configuration du cluster.

Configuration du modèle Zabbix

Zabbix prévoit des modèles permettant de superviser des clusters Kubernetes et d’en découvrir automatiquement les ressources via le mécanisme de Découverte de Zabbix. Les nœuds Kubernetes sont donc automatiquement ajoutés ou retirés comme hôte Zabbix, et des modèles leurs seront attribués automatiquement.

Sur Zabbix, importer le modèle Kubernetes nodes by HTTP (adapter la version à la version Zabbix choisie) en allant dans Data collectionTemplates et appuyer sur le bouton Import.

Import du modèle *Kubernetes nodes by HTTP*

Pour choisir le modèle automatiquement assigné aux nœuds Kubernetes, se rendre dans le prototype de l’hôte de la règle de Découverte en allant dans Data collectionTemplates, puis à la ligne Get nodes: Node discovery, sélectionner Host prototypes et appuyer sur {#NAME}. Il est ici possible de choisir un modèle permettant de superviser les systèmes de fichiers montés, permettant ainsi de superviser les volumes persistants.

Par ailleurs, le modèle part de l’hypothèse que l’agent Zabbix est installé sur les nœuds Kubernetes, et que cette agent est accessible depuis le proxy Zabbix via l’adresse réseau du nœud. Si la valeur de hostNetwork est false, les agents ne seront pas disponibles par les adresses réseau des nœuds du cluster. Il faut donc par conséquent retirer l’interface Zabbix configurée pour les noeuds automatiquement découvert par le modèle, et créer des hôtes Zabbix utilisant l’adresse réseau des pods contenant les agents Zabbix.

Zabbix s’appuie sur l’API Kubernetes pour superviser le cluster. Récupérer le token configuré par Helm qui sera utilisé par le modèle Kubernetes nodes by HTTP:

$ oc get secret zabbix-service-account -n monitoring-kube-nodes -o jsonpath={.data.token} | base64 -d

Ajout des hôtes Zabbix par Ansible

Une fois le proxy, les agents et modèle Zabbix correctement déployés et configurés, il ne reste plus qu’à ajouter les hôtes pour que la supervision se mette en place. Utiliser une solution comme Ansible permet de s’assurer de la cohérence et de la reproducibilité de la configuration des hôtes Zabbix.

Nous allons d’abord ajouter l’hôte utilisant le modèle Kubernetes nodes by HTTP en utilisant le module community.zabbix.zabbix_host. Les macro permettent de configurer le token ainsi que l’adresse de l’API Kubernetes.

tasks:
- name: "Create zabbix host node HTTP"
  community.zabbix.zabbix_host:
    host_name: "okd-host-nodes"
    state: present
    monitored_by: proxy
    proxy: "{{ proxy_name }}"
    host_groups:
        - "OKD clusters"
    link_templates:
        - Kubernetes nodes by HTTP
    macros:
        - macro: "{$KUBE.API.TOKEN}"
          value: "{{ api_token }}"
        - macro: "{$KUBE.API.URL}"
          value: "{{ host }}" # URL de l'API Kubernetes
  delegate_to: "{{ zabbix_server }}"

Pour ajouter les pods contenant les agents Zabbix sans passer par le hostNetwork, il faut d’abord en obtenir la liste, en s’appuyant sur le module kubernetes.core.k8s_info. Les pods des agents Zabbix en cours d’exécution sont sélectionnés par leurs labels, et placés dans la liste zabbix_agent_list:

tasks:
  - name: "Get zabbix-agent node"
    kubernetes.core.k8s_info:
      kind: Pod
      host: "{{ host }}" # URL de l'API Kubernetes
      api_key: "{{ api_token }}"
      namespace: "{{ namespace }}"
      label_selectors:
          - name = zabbix-agent
          - app = zabbix
      field_selectors:
          - status.phase=Running
    register: zabbix_agent_list

Une boucle est ensuite faite sur zabbix_agent_list pour ajouter les hôtes Zabbix, en utilisant l’adresse réseau du pod, et le nom du nœud sur lequel il s’exécute.

tasks:
  - name: Create zabbix node_agents
    community.zabbix.zabbix_host:
      host_name: "{{ item.spec.nodeName }}-agent"
      state: present
      monitored_by: proxy
      proxy: "{{ proxy_name }}"
      host_groups:
          - "OKD clusters"
      link_templates:
          - Template Openshift
          - Template Openshift FS
      interfaces:
          - type: 1
          main: 1
          useip: 1
          ip: "{{ item.status.podIP }}"
          port: 10050
    delegate_to: "{{ zabbix_server }}"
    loop: "{{ zabbix_agent_list.resources }}"

La directive link_templates permet d’assigner des modèles Zabbix aux hôtes Zabbix créés. Ces modèles sont ici utilisés pour superviser les nœuds Openshift, et notamment les taux d’occupation des points de montage, et donc des volumes persistants. Le graph ci-dessous montre le pourcentage d’espace disponible sur un volume persistent Kubernetes.

Espace disponible sur un volume persistent Kubernetes

Conclusion

Dans cet article, nous avons vu comment déployer Zabbix sur Kubernetes, comment configurer les modèles, et comment automatiser la configuration des hôtes Zabbix par des modules Ansible. Cela permet de superviser les ressources de stockage disponibles pour les nœuds Kubernetes, et de s’assurer que les pods utilisant des volumes persistants disposent d’assez d’espace de stockage pour leurs données.

Bien que cet article se concentre sur Kubernetes, les principes et les étapes décrites peuvent être adaptés à d’autres plateformes de conteneurisation, telles que OKD ou OpenShift.