Докер / Кафка соединяют два разных контейнера - PullRequest
1 голос
/ 13 июня 2019

Я использую docker-kafka проекта wurstmeister для запуска kafka / zookeeper в контейнере.Я создаю контейнеры, используя localhost в качестве переменной KAFKA_ADVERTISED_HOST_NAME: localhost.

Я написал приложение на Java, которое использует flink для подключения и использования одной из тем этого контейнера Kafka.Если я экспортирую работающую банку и запускаю ее со своего компьютера, она работает абсолютно нормально.Когда я создаю следующий образ для запуска jar из другого контейнера-докера, я получаю исключение (примерно через 30 секунд после выполнения) Exception in thread "main" org.apache.flink.runtime.client.JobExecutionException: org.apache.kafka.common.errors.TimeoutException: Timeout expired while fetching topic metadata, которое, по моему мнению, связано с тем, что моя программа Java не может связаться с сервером Kafka, работающим вдругой контейнер.

Вот докер-файл моего Java-приложения:

# Dockerfile

FROM anapsix/alpine-java

MAINTAINER myself myself

COPY myApp.jar /home/myApp.jar

CMD ["java","-jar","/home/myApp.jar"]

А вот докер-compose.yml для докера wurstmeister kafka:

version: "3.5"

networks:
  myNetwork:
    name: myNetwork
    driver: bridge

services:
  zookeeper:
    image: wurstmeister/zookeeper
    ports:
      - "2181:2181"
    networks:
      - myNetwork
  kafka:
    build: .
    ports:
      - "9092:9092"
    environment:
      KAFKA_ADVERTISED_HOST_NAME: localhost
      KAFKA_ADVERTISED_PORT: "9092"
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true"
      ALLOW_PLAINTEXT_LISTENER: "yes"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - myNetwork
  auth_analytics:
      build: 
        context: .
        dockerfile: auth_dockerfile
      depends_on:
        - kafka
      networks:
        - myNetwork

Я пробовал несколько версийвыше.Изначально я не настраивал какую-либо сеть, которая, как мне казалось, могла быть проблемой, однако вышеприведенное, что создает сеть, не имеет никакого значения.Я попробовал "localhost: 9092" в качестве сервера начальной загрузки в моем приложении Java и "myNetwork: 9092", когда я читал онлайн.

Я также прочитал FAQ от wurstmeister о подключении, но я не вижу ничего плохого в моей настройке.

Я также попытался запустить образ приложения Java безиспользуя docker-compose (я запустил docker-compose, чтобы запустить zookeeper / kafka, а затем я выполнил сборку docker, запустил docker для образа моего приложения Java. Это не имело никакого значения.)

Я застрял,Что я делаю не так?

Ответы [ 2 ]

2 голосов
/ 13 июня 2019

Вам необходимо правильно установить KAFKA_ADVERTISED_LISTENERS.На данный момент это localhost, что означает, что брокеру сообщается о любом подключении клиента, что брокер подключен к localhost, и когда клиент пытается подключиться к нему, произойдет сбой (если брокер Kafka фактически не доступен наlocalhost, чего не будет в контейнере Docker, просто запускающем ваше приложение).

Решение состоит в том, чтобы определить слушателей так, чтобы к ним можно было обращаться из любого брокера и клиента, которым это необходимо.Мой предпочтительный подход - это , где у вас есть один для внутриконтейнерной связи и один для связи с хоста:

  KAFKA_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092
  KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
  KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
  KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092

Ваши клиенты в сети Docker используют kafka:29092подключиться;клиенты на хост-компьютере подключаются к localhost: 9092 (и убедитесь, что 9092 через Docker выставлен на хост-компьютер).

Чтобы узнать больше об этом, см. https://rmoff.net/2018/08/02/kafka-listeners-explained/

Кстати, я бы настоятельно рекомендовал исправить это должным образом;переопределение файла /etc/hosts - это хак, который не решает актуальную проблему IMO.

1 голос
/ 13 июня 2019

KAFKA_ADVERTISED_HOST_NAME: localhost

- это то, что ваш клиент получит в качестве строки подключения к Kafka.Это означает, что контейнер с вашим приложением будет пытаться связаться с Kafka на localhost, где localhost - это стек локальной сети для контейнера с вашим приложением.

Чтобы решить эту проблему, вы должны использовать kafka host в качестве KAFKA_ADVERTISED_HOST_NAME и серверов начальной загрузки -это позволит вашему контейнеру подключаться к kafka внутри докеров, но нарушит конфигурацию, когда вы попытаетесь подключиться к Kafka, запустив на своем компьютере java -jar ...

Чтобы исправить эту проблему, сделайте запись в файле hosts наваш компьютер с отображением кафки -> localhost.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...