Streams for Apache Kafka

¿Qué es Streams for Apache Kafka?

Distribución self-managed de Apache Kafka diseñada para crear una experiencia superior de instalación, configuración y gestión en Red Hat OpenShift.

Basada en el proyecto open source Strimzi (CNCF Incubation project), proporciona:

  • Container images para Apache Kafka

  • Operators para gestionar clusters, topics y usuarios

  • HTTP Bridge para Apache Kafka

  • Consola UI (StreamsHub)

Apache Kafka — Fundamentos

Apache Kafka es un sistema distribuido de streaming de datos basado en mecanismo publish-subscribe.

Características principales:

  • Escalabilidad horizontal

  • Tolerancia a fallos

  • Datos inmutables (append-only log)

  • Open source (Apache License 2.0)

Casos de uso:

  • Recomendaciones en tiempo real

  • Aplicaciones IoT

  • Data gathering para IA

  • Change Data Capture (CDC)

Operadores Strimzi

Diagram

El Cluster Operator observa el CR Kafka y reconcilia el estado deseado. Los Topic y User Operators corren como contenedores dentro del Entity Operator.

Despliegue KRaft (sin Zookeeper)

A partir de Streams for Apache Kafka 3.x, el metadata se almacena dentro de Kafka usando KRaft, eliminando la dependencia de Zookeeper.

apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
  name: cdc-cluster
  namespace: kafka-cdc
spec:
  kafka:
    version: "4.0.0"
    replicas: 3
    listeners:
      - name: plain
        port: 9092
        type: internal
        tls: false
      - name: tls
        port: 9093
        type: internal
        tls: true
    config:
      offsets.topic.replication.factor: 3
      transaction.state.log.replication.factor: 3
      transaction.state.log.min.isr: 2
      default.replication.factor: 3
      min.insync.replicas: 2
    storage:
      type: persistent-claim
      size: 10Gi
      deleteClaim: false
    metricsConfig:
      type: jmxPrometheusExporter
      valueFrom:
        configMapKeyRef:
          name: kafka-metrics-config
          key: kafka-metrics-config.yml
  entityOperator:
    topicOperator: {}
    userOperator: {}
  kafkaExporter:
    topicRegex: ".*"
    groupRegex: ".*"

Cluster KRaft: 3 nodos

How it Works

KRaft Consensus (sin Zookeeper)

A partir de Kafka 3.x, el metadata del cluster se gestiona internamente usando el protocolo KRaft (Kafka Raft):

  1. Cada broker tiene un rol: controller (gestión de metadata) o broker (almacenamiento y serving de datos), o ambos en clusters pequeños (combined mode).

  2. Los controllers forman un quorum usando Raft. Un controller es elegido como active controller — es el único que escribe metadata.

  3. Cuando un topic se crea o una partición se reasigna, el active controller escribe el cambio en un log interno (__cluster_metadata), que se replica a los otros controllers.

  4. Los brokers obtienen el metadata suscribiéndose al log del controller — no hay polling, es push-based.

  5. Si el active controller cae, los controllers restantes eligen un nuevo líder via Raft en milisegundos, eliminando el delay de minutos que ocurría con Zookeeper.

Ciclo de vida de un mensaje

  1. Un producer envía un batch de registros al broker leader de la partición destino.

  2. El leader escribe el batch en su log local (append-only en disco, sequential I/O).

  3. Los followers (réplicas) fetch el batch del leader y lo escriben en sus propios logs.

  4. Cuando min.insync.replicas réplicas (incluyendo el leader) confirman el write, el leader envía un ACK al producer.

  5. El offset del batch se asigna secuencialmente — es inmutable y monotónicamente creciente.

  6. Un consumer con un consumer group asignado hace poll() al leader de cada partición asignada, recibiendo batches desde su último offset committed.

Strimzi Reconciliation Loop

El Cluster Operator de Strimzi opera como un Kubernetes controller clásico:

  1. Observa los cambios en los CRs Kafka, KafkaConnect, KafkaTopic y KafkaUser.

  2. Calcula la diferencia entre el estado deseado (CR) y el estado actual (StatefulSets, ConfigMaps, Secrets).

  3. Aplica los cambios de forma rolling — nunca detiene todos los brokers simultáneamente.

  4. Los Topic y User Operators corren como sidecars en el Entity Operator pod y reconcilian sus respectivos CRs contra el API de Kafka directamente (no Kubernetes resources).

Kafka Bridge (HTTP REST)

El Kafka Bridge permite producir y consumir mensajes via HTTP REST — ideal para demos y testing sin cliente Kafka nativo:

apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaBridge
metadata:
  name: cdc-bridge
  namespace: kafka-cdc
spec:
  replicas: 1
  bootstrapServers: cdc-cluster-kafka-bootstrap:9092
  http:
    port: 8080

Ejemplo — producir un mensaje:

curl -X POST https://kafka-bridge-kafka-cdc.apps.<domain>/topics/cdc.public.customers \
  -H "Content-Type: application/vnd.kafka.json.v2+json" \
  -d '{"records":[{"value":{"first_name":"Test","last_name":"User","email":"test@demo.io"}}]}'

Seguridad: Autenticación y Encriptación

El cluster Kafka expone dos listeners: plain (9092, sin TLS) y tls (9093, con TLS). Los clientes de producción deben usar el listener TLS con autenticación SCRAM-SHA-512.

KafkaUser con SCRAM-SHA-512

Strimzi gestiona las credenciales automáticamente al crear un recurso KafkaUser. El operador genera un Secret con la contraseña:

apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaUser
metadata:
  name: cdc-user
  namespace: kafka-cdc
  labels:
    strimzi.io/cluster: cdc-cluster
spec:
  authentication:
    type: scram-sha-512
  authorization:
    type: simple
    acls:
      - resource:
          type: topic
          name: cdc
          patternType: prefix
        operations: [Read, Write, Describe]
      - resource:
          type: topic
          name: dlq
          patternType: prefix
        operations: [Read, Write, Describe]
      - resource:
          type: group
          name: cdc-connect-cluster
          patternType: literal
        operations: [Read]
      - resource:
          type: group
          name: camel-cdc-consumer
          patternType: literal
        operations: [Read]

Las ACLs restringen el acceso: solo los topics con prefijo cdc y dlq, y los consumer groups específicos del pipeline.

Configuración de cliente — KafkaConnect

KafkaConnect se configura para usar el listener TLS (9093) con SCRAM-SHA-512:

spec:
  bootstrapServers: cdc-cluster-kafka-bootstrap:9093
  authentication:
    type: scram-sha-512
    username: cdc-user
    passwordSecret:
      secretName: cdc-user
      password: password
  tls:
    trustedCertificates:
      - secretName: cdc-cluster-cluster-ca-cert
        certificate: ca.crt

Strimzi genera automáticamente el secret cdc-cluster-cluster-ca-cert con el certificado CA del cluster.

Configuración de cliente — Apache Camel

Camel usa propiedades SASL/SSL en los parámetros del componente kafka:

parameters:
  brokers: cdc-cluster-kafka-bootstrap.kafka-cdc.svc:9093
  securityProtocol: SASL_SSL
  saslMechanism: SCRAM-SHA-512
  saslJaasConfig: "org.apache.kafka.common.security.scram.ScramLoginModule required username=\"${env:KAFKA_USER}\" password=\"${env:KAFKA_PASSWORD}\";"
  sslTruststoreLocation: /etc/kafka-certs/ca.crt
  sslTruststoreType: PEM

Las credenciales se inyectan como variables de entorno desde el Secret generado por Strimzi.

Ecosistema Streams for Apache Kafka

Componente Rol en el ecosistema

Kafka Core

Brokers, topics, particiones, replicación

Kafka Connect

Framework de connectors (source/sink)

Kafka Bridge

REST proxy HTTP para producir/consumir

Apicurio Registry

Schema Registry (Avro, JSON Schema, Protobuf)

Debezium

CDC connectors para PostgreSQL, MySQL, MongoDB, etc.

Streams Console

UI web para monitorear clusters, topics y consumer groups

Kafka Exporter

Exporta métricas de lag de consumer groups a Prometheus

Mirror Maker 2

Replicación cross-cluster

Kroxylicious

Kafka Proxy — encryption at rest, schema validation

Documentación Oficial