Lo que necesita saber sobre el registro de clústeres en Kubernetes

El registro de aplicaciones y servidores es una función importante para que los desarrolladores, operadores y equipos de seguridad comprendan el estado de una aplicación que se ejecuta en su entorno de producción.

El registro permite a los operadores determinar si las aplicaciones y los componentes necesarios funcionan correctamente y detectar si ocurre algo inusual para que puedan reaccionar ante la situación.

Para los desarrolladores, el registro proporciona visibilidad del código de solución de problemas durante y después del desarrollo. En un entorno de producción, el desarrollador suele depender de una función de registro sin herramientas de depuración. Junto con el registro de los sistemas, los desarrolladores pueden trabajar codo a codo con los operadores para solucionar problemas de manera efectiva.

El beneficiario más importante de las instalaciones de registro es el equipo de seguridad, especialmente en un entorno nativo de la nube. La capacidad de recopilar información de las aplicaciones y los registros del sistema permite que el equipo de seguridad analice los datos de la autenticación, el acceso a las aplicaciones y las actividades de malware a las que pueden responder si es necesario.

Kubernetes es la plataforma de contenedores líder en la que cada vez se implementan más aplicaciones en producción. Creo que comprender la arquitectura de registro de Kubernetes es un esfuerzo muy importante que todo equipo de desarrollo, operaciones y seguridad debe tomar en serio.

En este artículo explicaré cómo funcionan los diferentes modelos de registro de contenedores en Kubernetes.

Índice

    Registro del sistema y registro de la aplicación

    Antes de profundizar en la arquitectura de registro de Kubernetes, me gustaría explorar los diferentes enfoques de registro y cómo ambas características son características críticas del registro de Kubernetes.

    Hay dos tipos de componentes del sistema: los que se ejecutan en un contenedor y los que no. Por ejemplo:

    • El programador de Kubernetes e kube-proxy ejecutar en un contenedor.
    • El kubelet y el tiempo de ejecución del contenedor no se ejecuta en contenedores.

    Al igual que los registros de contenedores, los registros de contenedores del sistema se almacenan en /var/log directorios y debe rotarlos regularmente.

    Aquí considero el registro del contenedor. Primero, analizo el registro a nivel de clúster y por qué es importante para los operadores de clúster. Los registros del clúster proporcionan información sobre el rendimiento del clúster. Información como por qué los pods fueron desalojados o el nodo muere. El registro de clústeres también puede capturar información como el acceso a clústeres y aplicaciones y cómo la aplicación utiliza los recursos informáticos. En general, una función de registro de clúster proporciona a los operadores de clúster información útil para la seguridad y el funcionamiento del clúster.

    La otra forma de capturar registros de contenedores es a través de la función de registro nativa de la aplicación. Es muy probable que el diseño de aplicaciones modernas tenga un mecanismo de registro que ayude a los desarrolladores a solucionar problemas de rendimiento de aplicaciones a través de una salida estándar (stdout) y flujos de error (stderr).

    Para tener una función de registro efectiva, la implementación de Kubernetes requiere componentes de registro tanto de la aplicación como del sistema.

    3 tipos de registro de contenedores de Kubernetes

    Hay tres métodos importantes de registro a nivel de clúster que se ven en la mayoría de las implementaciones de Kubernetes en estos días.

    1. Agente de registro a nivel de nodo
    2. Solicitud de registro de contenedor de sidecar
    3. Exponga los registros de la aplicación directamente al backend de registro

    Agente de registro a nivel de nodo

    Me gustaría considerar el agente de registro a nivel de nodo. Por lo general, los implementa utilizando un DaemonSet como su estrategia de implementación para implementar un pod (que actúa como un agente de registro) en todos los nodos de Kubernetes. Luego, este agente de registro se configura para leer registros de todos los nodos de Kubernetes. Por lo general, configura el agente para leer los nodos /var/logs adquisición de directorio stdout/stderr transmitir y enviarlo a la tienda backend de grabación.

    La siguiente figura muestra el registro a nivel de nodo ejecutándose como agente en todos los nodos.

    Para configurar el registro a nivel de nodo mediante el fluentd enfoque como ejemplo, debe hacer lo siguiente:

    1. Primero, debe crear una cuenta de servicio llamada fluentdd. Esta cuenta de servicio es utilizada por Fluentd Pods para acceder a la API de Kubernetes y debe crearlos en el espacio de nombres de registro etiquetado app: fluentd.

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

      Puedes ver el ejemplo completo en este repositorio.

    2. Por lo tanto, es necesario crear un ConfigMap fluentd-configmap. Esto proporciona un archivo de configuración para el fluentd daemonset con todas las propiedades requeridas.

      #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
            Contenedores
      :
            - 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/Contenedores
                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/Contenedores
            - name
      : fluentconfig
              configMap
      :
                name
      : fluentdconf

      Puedes ver el ejemplo completo en este repositorio.

    Ahora, miro el código sobre cómo implementar un fluentd daemonset como agente de registro.

    #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
          Contenedores
    :
          - 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/Contenedores
              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/Contenedores
          - name
    : fluentconfig
            configMap
    :
              name
    : fluentdconf

    Para poner esto junto:

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

    Solicitud de registro de contenedor de sidecar

    El otro enfoque es utilizar un contenedor sidecar dedicado con un agente de registro. La implementación más común del contenedor sidecar es el uso Fluido como recolector de troncos. En la implementación empresarial (donde no se preocupará por una pequeña sobrecarga de recursos informáticos), se utiliza un contenedor sidecar fluentd (o similar) ofrece flexibilidad sobre el registro a nivel de clúster. Esto se debe a que puede ajustar y configurar el recopilador según el tipo de registros, la frecuencia y otros posibles ajustes que necesite adquirir.

    La siguiente figura muestra un contenedor sidecar como agente de registro.

    Por ejemplo, un pod ejecuta un solo contenedor y el contenedor escribe en dos archivos de registro diferentes usando dos formatos diferentes. Aquí hay un archivo de configuración para el pod:

    #log-sidecar.yaml
    apiVersion
    : v1
    kind
    : Pod
    metadata
    :
      name
    : counter
    spec
    :
      Contenedores
    :
      - 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
    : {}

    Para armar esto, puede ejecutar este pod:

    $ kubectl apply -f log-sidecar.yaml

    Para verificar si el contenedor de sidecar funciona como agente de registro, puede hacer lo siguiente:

    $ kubectl logs counter count-log

    El resultado esperado debería verse así:

    $ 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

    Exponga los registros de la aplicación directamente al backend de registro

    El tercer enfoque, que (en mi opinión) es la solución de registro más flexible para los registros de aplicaciones y contenedores de Kubernetes, es transferir los registros directamente a la solución de back-end de registro. Si bien este modelo no se basa en la capacidad nativa de Kubernetes, ofrece la flexibilidad que la mayoría de las empresas necesitan, como por ejemplo:

    1. Amplíe una variedad más amplia de soporte para protocolos de red y formatos de salida.
    2. Habilita las capacidades de equilibrio de carga y mejora el rendimiento.
    3. Configurable para aceptar requisitos de registro complejos a través de la agregación ascendente

    Dado que este tercer enfoque se basa en la funcionalidad que no es de Kubernetes al enviar registros directamente desde cada aplicación, está fuera del alcance de Kubernetes.

    Conclusión

    El registrador de Kubernetes es un componente muy importante para la implementación empresarial de un clúster de Kubernetes. He discutido tres modelos posibles que están disponibles para su uso. Necesitas encontrar un modelo que se adapte a tus necesidades.

    Como se muestra, el registro a nivel de nodo que utiliza daemonset Es el modelo de implementación más simple de usar, pero también tiene algunas limitaciones que pueden no satisfacer las necesidades de su organización. Por otro lado, el modelo sidecar ofrece flexibilidad y personalización que le permiten personalizar el tipo de registro que se capturará, lo que le brinda una sobrecarga de recursos informáticos. Finalmente, exponer los registros de la aplicación directamente a la función de registro de back-end es otro enfoque tentador que permite una mayor personalización.

    La decisión es tuya. Solo necesita encontrar el enfoque que se adapte a los requisitos de su organización.

    Artículos de interés

    Subir