Как обеспечить доступ к Kafka извне Kubernetes-кластера?

«Как обеспечить доступ к Kafka извне Kubernetes-кластера?» — вопрос из категории Брокеры сообщений, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Предоставление доступа к Kafka из внешних сетей — это компромисс между удобством и безопасностью. Я никогда не открываю брокеры напрямую в интернет без аутентификации и шифрования.

Основной подход: настройка advertised.listeners. Конфигурация брокера должна явно указывать, как к нему могут подключиться внешние клиенты.

# В конфигурации Kafka broker (server.properties)
listeners=INTERNAL://0.0.0.0:9092,EXTERNAL://0.0.0.0:9094
advertised.listeners=INTERNAL://kafka-broker.kafka.svc.cluster.local:9092,EXTERNAL://kafka.company.com:9094
listener.security.protocol.map=INTERNAL:PLAINTEXT,EXTERNAL:SASL_SSL
inter.broker.listener.name=INTERNAL

Способы вынести слушатель EXTERNAL наружу из Kubernetes:

  1. Kubernetes Service типа LoadBalancer или NodePort:

    apiVersion: v1
    kind: Service
    metadata:
      name: kafka-external
    spec:
      type: LoadBalancer # Или NodePort
      ports:
      - name: external
        port: 9094
        targetPort: 9094
      selector:
        app: kafka

    После создания Service нужно взять его внешний IP (EXTERNAL-IP) или домен, предоставленный облачным провайдером, и прописать его в advertised.listeners (например, EXTERNAL://<EXTERNAL-IP>:9094).

  2. Использование Ingress Controller с TCP/UDP проксированием (например, NGINX Ingress): Это позволяет использовать доменные имена и централизованное управление TLS.

Обязательные меры безопасности, которые я применяю:

  • TLS/SSL: Для шифрования трафика на внешнем листенере.
  • SASL аутентификация: Например, SASL/SCRAM или SASL/OAUTHBEARER.
  • Авторизация (ACL): Настройка прав доступа к топикам.
  • Сетевые политики Kubernetes (NetworkPolicy): Ограничение доступа к портам брокера только от определенных источников.

Альтернативный (и часто более безопасный) паттерн: вместо прямого доступа клиентов к Kafka я разворачиваю REST Proxy для Kafka (например, Confluent REST Proxy) и выношу его через Ingress с аутентификацией. Клиенты работают через HTTP/HTTPS API, что проще для безопасности и совместимости.