Configuración de la supervisión y las redes de un clúster de Kafka en Azure Kubernetes Service (AKS)

En este artículo se muestra cómo configurar la supervisión y las redes de un clúster de Kafka en Azure Kubernetes Service (AKS).

Supervisión con Azure Managed Prometheus y Grafana

Strimzi implementa la supervisión mediante la exposición de métricas de JMX a través del exportador JMX de Prometheus, que transforma los datos de rendimiento internos de Kafka en un formato que Prometheus puede recopilar y analizar. Esta canalización de supervisión permite la visibilidad en tiempo real de:

  • Métricas de rendimiento y estado del broker.
  • Rendimiento del productor y del consumidor.
  • Distribución del liderazgo en particiones.
  • Retraso de replicación y posibles riesgos de pérdida de datos.
  • Patrones de uso de recursos.

Azure Managed Prometheus proporciona un back-end de supervisión totalmente administrado y escalable sin la sobrecarga operativa de administrar sus propias instancias de Prometheus. Cuando se empareja con Azure Managed Grafana, obtiene acceso a funcionalidades de visualización completas con paneles pregenerados diseñados específicamente para la supervisión de Kafka.

Creación de PodMonitor

PodMonitors son recursos personalizados de Kubernetes que indican a Prometheus de qué pods recopilar métricas y cómo recopilarlas. Para la supervisión de Kafka, debe definir PodMonitors que tienen como destino varios componentes de Strimzi.

Antes de continuar, asegúrese de que el clúster de Kafka se implementó con la configuración de JMX Exporter. Sin esta configuración, las métricas no estarán disponibles para la recopilación.

  • Cree los recursos de PodMonitor mediante el kubectl apply comando .

    Nota:

    Al usar Azure Managed Prometheus:

    • PodMonitor apiVersion debe ser azmonitoring.coreos.com/v1 en lugar del estándar monitoring.coreos.com/v1.
    • En los siguientes ejemplos del selector de espacios de nombres, se asume que las cargas de trabajo de Kafka se implementan en el espacio de nombres kafka. Modifique en consecuencia si usa un espacio de nombres diferente.
    kubectl apply -f - <<EOF
    ---
    apiVersion: azmonitoring.coreos.com/v1
    kind: PodMonitor
    metadata:
      name: azmon-cluster-operator-metrics
      labels:
        app: strimzi
    spec:
      selector:
        matchLabels:
          strimzi.io/kind: cluster-operator
      namespaceSelector:
        matchNames:
          - kafka
      podMetricsEndpoints:
      - path: /metrics
        port: http
    ---
    apiVersion: azmonitoring.coreos.com/v1
    kind: PodMonitor
    metadata:
      name: azmon-entity-operator-metrics
      labels:
        app: strimzi
    spec:
      selector:
        matchLabels:
          app.kubernetes.io/name: entity-operator
      namespaceSelector:
        matchNames:
          - kafka
      podMetricsEndpoints:
      - path: /metrics
        port: healthcheck
    ---
    apiVersion: azmonitoring.coreos.com/v1
    kind: PodMonitor
    metadata:
      name: azmon-bridge-metrics
      labels:
        app: strimzi
    spec:
      selector:
        matchLabels:
          strimzi.io/kind: KafkaBridge
      namespaceSelector:
        matchNames:
          - kafka
      podMetricsEndpoints:
      - path: /metrics
        port: rest-api
    ---
    apiVersion: azmonitoring.coreos.com/v1
    kind: PodMonitor
    metadata:
      name: azmon-kafka-resources-metrics
      labels:
        app: strimzi
    spec:
      selector:
        matchExpressions:
          - key: "strimzi.io/kind"
            operator: In
            values: ["Kafka", "KafkaConnect", "KafkaMirrorMaker", "KafkaMirrorMaker2"]
      namespaceSelector:
        matchNames:
          - kafka
      podMetricsEndpoints:
      - path: /metrics
        port: tcp-prometheus
        relabelings:
        - separator: ;
          regex: __meta_kubernetes_pod_label_(strimzi_io_.+)
          replacement: $1
          action: labelmap
        - sourceLabels: [__meta_kubernetes_namespace]
          separator: ;
          regex: (.*)
          targetLabel: namespace
          replacement: $1
          action: replace
        - sourceLabels: [__meta_kubernetes_pod_name]
          separator: ;
          regex: (.*)
          targetLabel: kubernetes_pod_name
          replacement: $1
          action: replace
        - sourceLabels: [__meta_kubernetes_pod_node_name]
          separator: ;
          regex: (.*)
          targetLabel: node_name
          replacement: $1
          action: replace
        - sourceLabels: [__meta_kubernetes_pod_host_ip]
          separator: ;
          regex: (.*)
          targetLabel: node_ip
          replacement: $1
          action: replace
    EOF
    

Carga de paneles de Grafana para la supervisión de Kafka

Strimzi proporciona paneles de Grafana listos para usar en el repositorio strimzi/strimzi-kafka-operator de GitHub diseñado específicamente para supervisar clústeres de Kafka. Estos paneles visualizan las métricas expuestas por el exportador de JMX Prometheus que configuró anteriormente.

Implemente la supervisión de Kafka con Grafana mediante los pasos siguientes:

  1. Seleccione los paneles del repositorio de GitHub en función de sus necesidades de supervisión específicas.
  2. Descargue los archivos del panel JSON del repositorio.
  3. Importe los paneles en la instancia de Azure Managed Grafana a través de la interfaz de usuario de Grafana.

Configuración del exportador de Kafka para habilitar las métricas mejoradas de Prometheus

Aunque el Exportador de JMX Prometheus proporciona métricas internas de Kafka, el Exportador de Kafka lo complementa al centrarse en la supervisión del retraso de los consumidores y en los conocimientos a nivel de tema. Este exportador:

  • Realiza un seguimiento de los offsets del grupo de consumidores y calcula las métricas de retardo.
  • Supervisa el estado del tema, incluyendo las particiones con replicación insuficiente.
  • Proporciona métricas para los tamaños y recuentos de mensajes del tema.

Estas métricas adicionales pueden ser críticas para los entornos de producción en los que el monitoreo del rendimiento de los consumidores y el cumplimiento de los acuerdos de nivel de servicio de procesamiento de datos son esenciales.

Hay disponible un gráfico de Helm para implementar el exportador de Kafka junto con la canalización de supervisión existente.

  1. Cree un espacio de nombres para implementar el exportador de Kafka usando el comando kubectl create namespace. También puede usar un espacio de nombres existente si lo prefiere.

    kubectl create namespace azmon-kafka-exporter  
    
  2. Agregue y actualice el repositorio de Helm prometheus-community usando los comandos helm repo add y helm repo update.

    helm repo add prometheus-community https://prometheus-community.github.io/helm-charts  
    helm repo update  
    
  3. Cree un values.yaml archivo para invalidar configuraciones específicas para el gráfico de Helm. El punto de conexión bootstrap de Kafka debe actualizarse antes de ejecutar el script.

    cat <<EOF > values.yaml  
    kafkaServer:  
      - <kafka-bootstrap-fqdn-or-privateip>:9092 #additional kafka clusters can be added to the list  
    prometheus:  
      serviceMonitor:  
        namespace: azmon-kafka-exporter #ensure namespace is the same as in step 1  
        enabled: true  
        apiVersion: azmonitoring.coreos.com/v1  
    EOF  
    
  4. Instale el operador de clúster strimzi mediante el helm install comando .

    helm install azmon-kafka-exporter prometheus-community/prometheus-kafka-exporter \
    --version 2.11.0 \
    --namespace azmon-kafka-exporter \
    --values values.yaml
    
  5. Suba el Kafka Exporter Dashboard a Grafana.

Nota:

Este panel de Grafana usa el complemento AngularJS que quedará en desuso en futuras versiones de Grafana. Para más información, consulte Obsolescencia del soporte de Angular. Las métricas del exportador de Kafka seguirán estando disponibles, pero es posible que tenga que crear sus propios paneles una vez que quede en desuso.

Conectividad de cliente al clúster de Kafka

Strimzi ofrece opciones flexibles para exponer el clúster de Kafka a los clientes a través de agentes de escucha. Cada listener define cómo los clientes se conectan a los brokers de Kafka mediante protocolos específicos, métodos de autenticación y patrones de exposición de red.

Una configuración de escuchador define:

  • El puerto en el que Kafka acepta conexiones.
  • El protocolo de seguridad (Plain, TLS, SASL).
  • Cómo se expone el punto de conexión (tipo de servicio de Kubernetes).

Kafka usa un proceso de conexión en dos fases que influye en cómo debe configurar las redes. Al configurar agentes de escucha para la implementación de Strimzi Kafka en AKS, es importante comprender el siguiente proceso:

  • Fase 1: el cliente se conecta al servicio de arranque, que luego se conecta a cualquiera de los brokers para recuperar los metadatos. Los metadatos contienen información sobre los temas, sus particiones y los agentes que los hospedan.
  • Fase 2: el cliente establece una nueva conexión directamente a un agente individual mediante la dirección anunciada obtenida de los metadatos.

Esto significa que la arquitectura de red debe tener en cuenta tanto el servicio de arranque como la conectividad de corredor individual.

Para obtener más información, consulte la documentación de Strimzi sobre la configuración del acceso de cliente.

Opción 1: Acceso interno al clúster (ClusterIP)

En el caso de las aplicaciones que se ejecutan en el mismo clúster de Kubernetes que el clúster de Kafka, exponga Kafka a través de ClusterIP:

listeners:
  - name: internal
    port: 9092
    type: internal
    tls: true

Esto crea un ClusterIP para el servicio bootstrap y los brokers accesibles solo dentro de la red de Kubernetes.

Opción 2: Acceso externo a través de Load Balancer público

En el caso de los clientes externos, el loadbalancer tipo de agente de escucha crea una configuración de Azure Load Balancer con direcciones IP públicas:

listeners:
  - name: external
    port: 9094
    type: loadbalancer
    tls: false

Al usar esta configuración:

  • Se crea un servicio de LoadBalancer de Kubernetes para cada broker y el servicio de arranque.
  • Azure aprovisiona direcciones IP públicas para cada servicio.

Si desea usar nombres DNS personalizados, debe configurar el advertisedHost para cada broker y el alternativeNames para el servicio de arranque. Esto es necesario para garantizar que Kafka anuncia correctamente el nombre de host personalizado para cada broker hacia un cliente. También agrega la información al certificado correspondiente de broker o de arranque para que se pueda usar para la comprobación del nombre del host TLS.

listeners:
  - name: external
    port: 9094
    type: loadbalancer
    tls: true
    configuration: 
      bootstrap:
        alternativeNames: 
        - kafka-bootstrap.example.com
      brokers:
        - broker: 0
          advertisedHost: kafka-broker-0.example.com

Opción 3: Acceso externo a través de Private Load Balancer

Si desea acceder al clúster de Kafka fuera del clúster de AKS, pero dentro de una red virtual de Azure, puede exponer el servicio de arranque y los agentes a través de un equilibrador de carga interno con direcciones IP privadas:

listeners:
  - name: private-lb
    port: 9094
    type: loadbalancer
    tls: true
    configuration: 
      bootstrap:
        annotations:
          service.beta.kubernetes.io/azure-load-balancer-internal: "true"
      brokers:
        - broker: 0
          annotations:
            service.beta.kubernetes.io/azure-load-balancer-internal: "true"
        - broker: 1
          annotations:
            service.beta.kubernetes.io/azure-load-balancer-internal: "true"
        - broker: 2
          annotations:
            service.beta.kubernetes.io/azure-load-balancer-internal: "true"

Importante

Al agregar nuevos intermediarios a su clúster, debe actualizar la configuración del escuchador con las anotaciones correspondientes para cada nuevo intermediario. De lo contrario, esos intermediarios se expondrán con direcciones IP públicas.

Si desea usar nombres DNS personalizados, debe configurar el advertisedHost para cada broker y el alternativeNames para el servicio de arranque. Esto es necesario para asegurarse de que Kafka anuncie correctamente el nombre de host personalizado que respalda cada agente hacia un cliente. También agrega la información al certificado de agente o de arranque correspondiente para que pueda utilizarse en la verificación del nombre de host de TLS.

  listeners:
    - name: private-lb
      port: 9094
      type: loadbalancer
      tls: true
      configuration: 
        bootstrap:
          alternativeNames: 
          - kafka-bootstrap.example.com
          annotations:
            service.beta.kubernetes.io/azure-load-balancer-internal: "true"
        brokers:
          - broker: 0
            advertisedHost: kafka-broker-0.example.com
            annotations:
              service.beta.kubernetes.io/azure-load-balancer-internal: "true"

Para tener redes internas más seguras o acceder a través de redes virtuales de Azure que no tienen emparejamiento, puede exponer el clúster de Kafka a través de Azure Private Link Services.

listeners:
  - name: private-link
    port: 9094
    type: loadbalancer
    tls: true
    configuration:
      bootstrap:
        alternativeNames: 
        - kafka-bootstrap.<privatedomain-pe>.com
        annotations:
          service.beta.kubernetes.io/azure-load-balancer-internal: "true"
          service.beta.kubernetes.io/azure-pls-create: "true"
          service.beta.kubernetes.io/azure-pls-name: "pls-kafka-bootstrap" 
      brokers:
        - broker: 0
          advertisedHost: kafka-broker-0.<privatedomain-pe>.com
          annotations:
            service.beta.kubernetes.io/azure-load-balancer-internal: "true"
            service.beta.kubernetes.io/azure-pls-create: "true"
            service.beta.kubernetes.io/azure-pls-name: "pls-kafka-broker-0"
        - broker: 1
          advertisedHost: kafka-broker-1.<privatedomain-pe>.com   
          annotations:
            service.beta.kubernetes.io/azure-load-balancer-internal: "true"
            service.beta.kubernetes.io/azure-pls-create: "true"
            service.beta.kubernetes.io/azure-pls-name: "pls-kafka-broker-1"
        - broker: 2
          advertisedHost: kafka-broker-2.<privatedomain-pe>.com
          annotations:
            service.beta.kubernetes.io/azure-load-balancer-internal: "true"
            service.beta.kubernetes.io/azure-pls-create: "true"
            service.beta.kubernetes.io/azure-pls-name: "pls-kafka-broker-2"

Esta configuración:

  • Crea servicios de equilibrador de carga internos con direcciones IP privadas para todos los componentes.
  • Establece un servicio de enlace privado para el servicio de arranque y los intermediarios individuales, respectivamente. Esto habilita la conexión a través de puntos de conexión privados de otras redes virtuales.
  • Configura el alternativeNames. Esto es necesario para asegurarse de que Strimzi agrega los nombres de servicio de arranque alternativos al certificado TLS para que se puedan usar para la comprobación del nombre de host TLS.
  • Configura el advertisedHost. Esto es necesario para asegurarse de que Kafka anuncia la entrada DNS privada del punto de conexión privado configurado para cada agente. advertisedHost también se agrega al certificado de intermediario para que pueda usarse en la verificación del nombre de host TLS.

Importante

Al agregar nuevos intermediarios a su clúster, debe actualizar la configuración del escuchador con las anotaciones correspondientes para cada nuevo intermediario. De lo contrario, esos intermediarios se expondrán con direcciones IP públicas.

Puede cambiar el service.beta.kubernetes.io/azure-pls-name: a cualquier nombre que prefiera.

Después de implementar esta configuración, siga los pasos para crear un punto de conexión privado en el servicio Private Link de Azure Load Balancer.

Colaboradores

Microsoft mantiene este artículo. Originalmente lo escribieron los siguientes colaboradores:

  • Sergio Navar | Ingeniero superior de clientes
  • Erin Schaffer | Desarrollador de contenido 2