Ce que vous devez savoir sur la journalisation des clusters dans Kubernetes


  • FrançaisFrançais


  • La journalisation des serveurs et des applications est une fonctionnalité importante pour les développeurs, les opérateurs et les équipes de sécurité pour comprendre l’état d’une application en cours d’exécution dans leur environnement de production.

    La journalisation permet aux opérateurs de déterminer si les applications et les composants requis fonctionnent correctement et de détecter si quelque chose d’inhabituel se produit afin qu’ils puissent réagir à la situation.

    Pour les développeurs, la journalisation donne une visibilité pour dépanner le code pendant et après le développement. Dans un environnement de production, le développeur s’appuie généralement sur une fonction de journalisation sans outils de débogage. Couplé à la journalisation des systèmes, les développeurs peuvent travailler main dans la main avec les opérateurs pour résoudre efficacement les problèmes.

    Le bénéficiaire le plus important des installations de journalisation est l’équipe de sécurité, en particulier dans un environnement cloud natif. La possibilité de collecter des informations à partir des applications et des journaux système permet à l’équipe de sécurité d’analyser les données de l’authentification, de l’accès des applications aux activités malveillantes où elles peuvent y répondre si nécessaire.

    Kubernetes est la principale plate-forme de conteneurs où de plus en plus d’applications sont déployées en production. Je pense que comprendre l’architecture de journalisation de Kubernetes est une entreprise très importante que chaque équipe de développement, d’exploitation et de sécurité doit prendre au sérieux.

    Dans cet article, je discute du fonctionnement des différents modèles de journalisation des conteneurs dans Kubernetes.

    Journalisation du système et journalisation des applications

    Avant d’approfondir l’architecture de journalisation Kubernetes, j’aimerais explorer les différentes approches de journalisation et comment les deux fonctionnalités sont des caractéristiques essentielles de la journalisation Kubernetes.

    Il existe deux types de composants système : ceux qui s’exécutent dans un conteneur et ceux qui ne le font pas. Par exemple:

    • Le planificateur Kubernetes et kube-proxy courir dans un conteneur.
    • Les kubelet et le runtime de conteneur ne s’exécutent pas dans des conteneurs.

    Semblables aux journaux de conteneur, les journaux de conteneur système sont stockés dans le /var/log répertoire, et vous devez les faire pivoter régulièrement.

    Ici, je considère la journalisation des conteneurs. Tout d’abord, je regarde la journalisation au niveau du cluster et pourquoi elle est importante pour les opérateurs de cluster. Les journaux de cluster fournissent des informations sur les performances du cluster. Des informations telles que la raison pour laquelle les pods ont été expulsés ou le nœud meurt. La journalisation des clusters peut également capturer des informations telles que l’accès aux clusters et aux applications et la façon dont l’application utilise les ressources de calcul. Dans l’ensemble, une fonction de journalisation de cluster fournit aux opérateurs de cluster des informations utiles pour le fonctionnement et la sécurité du cluster.

    L’autre moyen de capturer les journaux de conteneurs consiste à utiliser la fonction de journalisation native de l’application. La conception d’applications modernes a très probablement un mécanisme de journalisation qui aide les développeurs à résoudre les problèmes de performances des applications via une sortie standard (stdout) et les flux d’erreurs (stderr).

    Pour disposer d’une fonction de journalisation efficace, la mise en œuvre de Kubernetes nécessite à la fois des composants de journalisation des applications et du système.

    3 types de journalisation des conteneurs Kubernetes

    Il existe trois méthodes principales de journalisation au niveau du cluster que vous voyez dans la plupart des implémentations Kubernetes de nos jours.

    1. Agent de journalisation au niveau du nœud
    2. Application de conteneur side-car pour la journalisation
    3. Exposition des journaux d’application directement au backend de journalisation

    Agent de journalisation au niveau du nœud

    J’aimerais considérer l’agent de journalisation au niveau du nœud. Vous les implémentez généralement en utilisant un DaemonSet comme stratégie de déploiement pour déployer un pod (qui agit comme un agent de journalisation) dans tous les nœuds Kubernetes. Cet agent de journalisation est ensuite configuré pour lire les journaux de tous les nœuds Kubernetes. Vous configurez généralement l’agent pour lire les nœuds /var/logs capture de répertoire stdout/stderr flux et l’envoyer au stockage principal de journalisation.

    La figure ci-dessous montre la journalisation au niveau du nœud exécutée en tant qu’agent dans tous les nœuds.

    Pour configurer la journalisation au niveau du nœud à l’aide de la fluentd approche à titre d’exemple, vous devez procéder comme suit :

    1. Tout d’abord, vous devez créer un ServiceAccount appelé fluentdd. Ce compte de service est utilisé par les pods Fluentd pour accéder à l’API Kubernetes, et vous devez les créer dans l’espace de noms de journalisation avec le libellé app: fluentd.

      #fluentd-SA.yaml
      apiVersion
      : v1
      kind
      : ServiceAccount
      metadata
      :
        name
      : fluentd
        namespace
      : logging
        labels
      :
          app
      : fluentd

      Vous pouvez voir l’exemple complet dans ce dépôt.

    2. Vous devez ensuite créer un ConfigMap fluentd-configmap. Cela fournit un fichier de configuration au fluentd daemonset avec toutes les propriétés requises.

      #fluentd-daemonset.yaml
      apiVersion
      : extensions/v1beta1
      kind
      : DaemonSet
      metadata
      :
        name
      : fluentd
        namespace
      : logging
        labels
      :
          app
      : fluentd
          kubernetes.io/cluster-service
      : "true"
      spec
      :
        selector
      :
          matchLabels
      :
            app
      : fluentd
            kubernetes.io/cluster-service
      : "true"
        template
      :
          metadata
      :
            labels
      :
              app
      : fluentd
              kubernetes.io/cluster-service
      : "true"
          spec
      :
            serviceAccount
      : fluentd
            containers
      :
            - name
      : fluentd
              image
      : fluent/fluentd-kubernetes-daemonset:v1.7.3-debian-elasticsearch7-1.0
              env
      :
                - name
      : FLUENT_ELASTICSEARCH_HOST
                  value
      : "elasticsearch.logging.svc.cluster.local"
                - name
      : FLUENT_ELASTICSEARCH_PORT
                  value
      : "9200"
                - name
      : FLUENT_ELASTICSEARCH_SCHEME
                  value
      : "http"
                - name
      : FLUENT_ELASTICSEARCH_USER
                  value
      : "elastic"
                - name
      : FLUENT_ELASTICSEARCH_PASSWORD
                  valueFrom
      :
                    secretKeyRef
      :
                      name
      : efk-pw-elastic
                      key
      : password
                - name
      : FLUENT_ELASTICSEARCH_SED_DISABLE
                  value
      : "true"
              resources
      :
                limits
      :
                  memory
      : 512Mi
                requests
      :
                  cpu
      : 100m
                  memory
      : 200Mi
              volumeMounts
      :
              - name
      : varlog
                mountPath
      : /var/log
              - name
      : varlibdockercontainers
                mountPath
      : /var/lib/docker/containers
                readOnly
      : true
              - name
      : fluentconfig
                mountPath
      : /fluentd/etc/fluent.conf
                subPath
      : fluent.conf
            terminationGracePeriodSeconds
      : 30
            volumes
      :
            - name
      : varlog
              hostPath
      :
                path
      : /var/log
            - name
      : varlibdockercontainers
              hostPath
      :
                path
      : /var/lib/docker/containers
            - name
      : fluentconfig
              configMap
      :
                name
      : fluentdconf

      Vous pouvez voir l’exemple complet dans ce dépôt.

    Maintenant, je regarde le code sur la façon de déployer un fluentd daemonset en tant qu’agent de journalisation.

    #fluentd-daemonset.yaml
    apiVersion
    : extensions/v1beta1
    kind
    : DaemonSet
    metadata
    :
      name
    : fluentd
      namespace
    : logging
      labels
    :
        app
    : fluentd
        kubernetes.io/cluster-service
    : "true"
    spec
    :
      selector
    :
        matchLabels
    :
          app
    : fluentd
          kubernetes.io/cluster-service
    : "true"
      template
    :
        metadata
    :
          labels
    :
            app
    : fluentd
            kubernetes.io/cluster-service
    : "true"
        spec
    :
          serviceAccount
    : fluentd
          containers
    :
          - name
    : fluentd
            image
    : fluent/fluentd-kubernetes-daemonset:v1.7.3-debian-elasticsearch7-1.0
            env
    :
              - name
    : FLUENT_ELASTICSEARCH_HOST
                value
    : "elasticsearch.logging.svc.cluster.local"
              - name
    : FLUENT_ELASTICSEARCH_PORT
                value
    : "9200"
              - name
    : FLUENT_ELASTICSEARCH_SCHEME
                value
    : "http"
              - name
    : FLUENT_ELASTICSEARCH_USER
                value
    : "elastic"
              - name
    : FLUENT_ELASTICSEARCH_PASSWORD
                valueFrom
    :
                  secretKeyRef
    :
                    name
    : efk-pw-elastic
                    key
    : password
              - name
    : FLUENT_ELASTICSEARCH_SED_DISABLE
                value
    : "true"
            resources
    :
              limits
    :
                memory
    : 512Mi
              requests
    :
                cpu
    : 100m
                memory
    : 200Mi
            volumeMounts
    :
            - name
    : varlog
              mountPath
    : /var/log
            - name
    : varlibdockercontainers
              mountPath
    : /var/lib/docker/containers
              readOnly
    : true
            - name
    : fluentconfig
              mountPath
    : /fluentd/etc/fluent.conf
              subPath
    : fluent.conf
          terminationGracePeriodSeconds
    : 30
          volumes
    :
          - name
    : varlog
            hostPath
    :
              path
    : /var/log
          - name
    : varlibdockercontainers
            hostPath
    :
              path
    : /var/lib/docker/containers
          - name
    : fluentconfig
            configMap
    :
              name
    : fluentdconf

    Pour mettre ça ensemble :

    kubectl apply -f fluentd-SA.yaml
                  -f fluentd-configmap.yaml
                  -f fluentd-daemonset.yaml

    Application de conteneur side-car pour la journalisation

    L’autre approche consiste à utiliser un conteneur side-car dédié avec un agent de journalisation. La mise en œuvre la plus courante du conteneur side-car consiste à utiliser Courant en tant que collecteur de journaux. Dans le déploiement d’entreprise (où vous ne vous soucierez pas d’une petite surcharge de ressources de calcul), un conteneur side-car utilisant fluentd (ou similaire) offre une flexibilité par rapport à la journalisation au niveau du cluster. En effet, vous pouvez régler et configurer l’agent collecteur en fonction du type de journaux, de la fréquence et d’autres réglages possibles que vous devez capturer.

    La figure ci-dessous montre un conteneur side-car en tant qu’agent de journalisation.

    Par exemple, un pod exécute un seul conteneur et le conteneur écrit dans deux fichiers journaux différents en utilisant deux formats différents. Voici un fichier de configuration pour le pod :

    #log-sidecar.yaml
    apiVersion
    : v1
    kind
    : Pod
    metadata
    :
      name
    : counter
    spec
    :
      containers
    :
      - name
    : count
        image
    : busybox
        args
    :
       - /bin/sh
        - -c
        - >
         i=0;
          while true;
          do
            echo "$i: $(date)" >> /var/log/1.log;
            echo "$(date) INFO $i" >> /var/log/2.log;
            i=$((i+1));
            sleep 1;
          done

        volumeMounts
    :
        - name
    : varlog
          mountPath
    : /var/log
      - name
    : count-log
        image
    : busybox
        args
    : [/bin/sh, -c, 'tail -n+1 -f /var/log/1.log']
        volumeMounts
    :
        - name
    : varlog
          mountPath
    : /var/log
      volumes
    :
      - name
    : varlog
        emptyDir
    : {}

    Pour mettre tout cela ensemble, vous pouvez exécuter ce pod :

    $ kubectl apply -f log-sidecar.yaml

    Pour vérifier si le conteneur side-car fonctionne comme un agent de journalisation, vous pouvez effectuer :

    $ kubectl logs counter count-log

    Le résultat attendu devrait ressembler à ceci :

    $ kubectl logs counter count-log-1

    Thu 04 Nov 2021 09:23:21 NZDT
    Thu 04 Nov 2021 09:23:22 NZDT
    Thu 04 Nov 2021 09:23:23 NZDT
    Thu 04 Nov 2021 09:23:24 NZDT

    Exposition des journaux d’application directement au backend de journalisation

    La troisième approche, qui (à mon avis) est la solution de journalisation la plus flexible pour les journaux de conteneurs et d’applications Kubernetes, consiste à envoyer les journaux directement vers la solution principale de journalisation. Bien que ce modèle ne repose pas sur la capacité native de Kubernetes, il offre la flexibilité dont la plupart des entreprises ont besoin, comme :

    1. Étendez une plus grande variété de prise en charge des protocoles réseau et des formats de sortie.
    2. Permet la capacité d’équilibrage de charge et améliore les performances.
    3. Configurable pour accepter des exigences de journalisation complexes via l’agrégation en amont

    Étant donné que cette troisième approche repose sur une fonctionnalité non Kubernetes en poussant les journaux directement à partir de chaque application, elle est en dehors de la portée de Kubernetes.

    Conclusion

    La fonction de journalisation Kubernetes est un composant très important pour un déploiement d’entreprise d’un cluster Kubernetes. J’ai discuté de trois modèles possibles qui sont disponibles pour une utilisation. Vous devez trouver un modèle adapté à vos besoins.

    Comme indiqué, la journalisation au niveau du nœud utilisant daemonset est le modèle de déploiement le plus simple à utiliser, mais il présente également certaines limitations qui peuvent ne pas répondre aux besoins de votre organisation. D’autre part, le modèle side-car offre une flexibilité et une personnalisation qui vous permettent de personnaliser le type de journaux à capturer, ce qui vous donne une surcharge de ressources de calcul. Enfin, l’exposition des journaux d’application directement à la fonction de journal principal est une autre approche attrayante qui permet une personnalisation plus poussée.

    Le choix t’appartient. Il vous suffit de trouver l’approche qui correspond aux besoins de votre organisation.

    Source

    La Rédaction

    L'équipe rédactionnnelle du site

    Pour contacter personnellement le taulier :

    Laisser un commentaire

    Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

    Copy code