无法从logstash docker容器连接到kafka docker容器

3
我正在尝试从一个Logstash Docker容器连接到一个Kafka Docker容器,但我总是收到以下信息:
 Connection to node 0 (localhost/127.0.0.1:9092) could not be established. Broker may not be available.

我的docker-compose.yml文件是:
version: '3.2'

services:
  elasticsearch:
    build:
      context: elasticsearch/
      args:
        ELK_VERSION: $ELK_VERSION
    volumes:
      - type: bind
        source: ./elasticsearch/config/elasticsearch.yml
        target: /usr/share/elasticsearch/config/elasticsearch.yml
        read_only: true
      - type: volume
        source: elasticsearch
        target: /usr/share/elasticsearch/data
    ports:
      - "9200:9200"
      - "9300:9300"
    environment:
      ES_JAVA_OPTS: "-Xmx256m -Xms256m"
      ELASTIC_PASSWORD: changeme
    networks:
      - elk
    depends_on:
      - kafka

  logstash:
    build:
      context: logstash/
      args:
        ELK_VERSION: $ELK_VERSION
    volumes:
      - type: bind
        source: ./logstash/config/logstash.yml
        target: /usr/share/logstash/config/logstash.yml
        read_only: true
      - type: bind
        source: ./logstash/pipeline
        target: /usr/share/logstash/pipeline
        read_only: true
    ports:
      - "5000:5000"
      - "9600:9600"
    links:
      - kafka
    environment:
      LS_JAVA_OPTS: "-Xmx256m -Xms256m"
    networks:
      - elk
    depends_on:
      - elasticsearch

  kibana:
    build:
      context: kibana/
      args:
        ELK_VERSION: $ELK_VERSION
    volumes:
      - type: bind
        source: ./kibana/config/kibana.yml
        target: /usr/share/kibana/config/kibana.yml
        read_only: true
    ports:
      - "5601:5601"
    networks:
      - elk
    depends_on:
      - elasticsearch

  zookeeper:
    image: strimzi/kafka:0.11.3-kafka-2.1.0
    container_name: zookeeper
    command: [
      "sh", "-c",
      "bin/zookeeper-server-start.sh config/zookeeper.properties"
    ]
    ports:
      - "2181:2181"
    networks:
      - elk
    environment:
      LOG_DIR: /tmp/logs

  kafka:
    image: strimzi/kafka:0.11.3-kafka-2.1.0
    command: [
      "sh", "-c",
      "bin/kafka-server-start.sh config/server.properties --override listeners=$${KAFKA_LISTENERS} --override advertised.listeners=$${KAFKA_ADVERTISED_LISTENERS} --override zookeeper.connect=$${KAFKA_ZOOKEEPER_CONNECT}"
    ]
    depends_on:
      - zookeeper
    ports:
      - "9092:9092"
    networks:
      - elk
    environment:
      LOG_DIR: "/tmp/logs"
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181

networks:
  elk:
    driver: bridge

volumes:
  elasticsearch:

我的logstash.conf文件如下:
input {
    kafka{
        bootstrap_servers => "kafka:9092"
        topics => ["logs"]
    }
}

## Add your filters / logstash plugins configuration here

output {
    elasticsearch {
        hosts => "elasticsearch:9200"
        user => "elastic"
        password => "changeme"
    }
}

我的所有容器都正常运行,我可以将消息发送到容器外的Kafka主题中。

3个回答

6

你需要根据客户端可以解析的主机名来定义监听器。如果监听器是localhost,那么客户端(logstash)将尝试从其自己的容器中将其解析为localhost,因此会出现错误。

我在这里详细介绍了这个问题,但本质上您需要做到以下几点:

KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092, PLAINTEXT://kafka:29092
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092, PLAINTEXT://kafka:29092

随后,Docker网络中的任何容器都可以使用 kafka:29092 来访问它,因此logstash配置如下:

bootstrap_servers => "kafka:29092"

任何在主机上的客户端仍然使用localhost:9092
您可以通过Docker Compose看到它的实际效果,链接如下:https://github.com/confluentinc/demo-scene/blob/master/build-a-streaming-pipeline/docker-compose.yml#L40

1
我一直在尝试解决这个问题,但是问题不断出现,最终发现在Kafka中使用“-”作为容器名称会破坏某些东西。我移除了“-”(随后也从主机名中移除了“-”),现在一切正常运行。 - felipe

0

您可以使用主机的IP地址作为Kafka广告侦听器,这样您的Docker服务以及运行在Docker网络之外的服务都可以访问它。

KAFKA_ADVERTISED_LISTENERS:PLAINTEXT://$HOST_IP:9092
KAFKA_LISTENERS: PLAINTEXT://$HOST_IP:9092

参考文章:https://rmoff.net/2018/08/02/kafka-listeners-explained/


0
Kafka 的广告列表应该像这样定义:
KAFKA_ADVERTISED_LISTENERS:PLAINTEXT://kafka:9092   
KAFKA_LISTENERS: PLAINTEXT://kafka:9092

通过这种方式设置Kafka的广告侦听器可以防止我拥有的未经Docker化的应用程序通过localhost向Kafka生产消息。难道没有办法从Docker内部和外部都访问它吗? - geoandri
在这种情况下,将Kafka替换为它所部署的主机机器的fqdn。 - Soumen Mukherjee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接