Kafka Docker Compose 外部连接

6

我希望将9093端口暴露到docker容器外部。当我将kafka-0端口设置为9093并将KAFKA_ADVERTISED_LISTENERS设置如下时,无法连接到localhost:9093,如下面的docker-compose文件所示。

version: '3'

services:
  kafka-0:
    image: confluentinc/cp-kafka:5.2.1
    container_name: kafka-0
    hostname: kafka-0
    ports:
      - "9093:9092"
    environment:
      - KAFKA_BROKER_ID=1
      - KAFKA_ZOOKEEPER_CONNECT=wise-nlp-zookeeper:2181
      - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
      - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka-0:29094,PLAINTEXT_HOST://localhost:9093
      - KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1
    depends_on:
      - zookeeper

  zookeeper:
    image: confluentinc/cp-zookeeper:5.3.1
    container_name: zookeeper
    ports:
      - "2182:2181"
    environment:
      - ZOOKEEPER_CLIENT_PORT=2181

然而,当我更改为

ports:
 - "9092:9092"

并且

- KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka-0:29094,PLAINTEXT_HOST://localhost:9092

我能够连接到kafka代理localhost:9092。

如何将外部端口更改为9093,以便应用程序连接?我想设置多个代理。


你的29094端口来自哪里? - Vincent
1个回答

19

为什么目前不工作?

广告的侦听器(如KAFKA_ADVERTISED_LISTENERS中定义的)是代理返回给客户端的主机和端口,用于在后续连接中使用。

如果要让外部客户端使用9093,则KAFKA_ADVERTISED_LISTENERS = ... PLAINTEXT_HOST:// localhost:9093是正确的。但是,您没有配置KAFKA_LISTENERS,如果在代理启动时检查代理日志,将默认为KAFKA_ADVERTISED_LISTENERS设置的值:

kafka-0      |  listeners = PLAINTEXT://0.0.0.0:29094,PLAINTEXT_HOST://0.0.0.0:9093

因此,在这种状态下,代理正在9093端口上监听,但是使用Docker Compose指令,您将外部连接重定向到容器中的9092端口:

    ports: 
      - "9093:9092"

➜ docker ps
CONTAINER ID        IMAGE                             … PORTS                                        NAMES
8b934ef4145c        confluentinc/cp-kafka:5.4.10.0.0.0:9093->9092/tcp                       kafka-0

因此,您的外部连接将转到容器中的端口9092 - 但代理程序不会在此端口上侦听。您可以使用nc进行验证:

-- Port 9093 is open on the host machine
➜ nc -vz localhost 9093
Connection to localhost port 9093 [tcp/*] succeeded!

-- Port 9092 is _not_ open on the Kafka container
➜ docker exec -it kafka-0 nc -vz localhost 9092
localhost [127.0.0.1] 9092 (?) : Connection refused

❌ 你会发现客户端连接失败

➜ kafkacat -b localhost:9093 -L
% ERROR: Failed to acquire metadata: Local: Broker transport failure

如何解决这个问题?

您可以选择:

  1. 更改监听器的端口,使其与Docker端口重定向所针对的端口一致。这种方法虽然可行,但我个人认为会更加令人困惑。
  2. 更改Docker端口重定向,使其针对监听器所在的端口。这是我会使用的选项,因为它更清晰明了(例如,始终使用端口9093,而不是混合使用90929093)。

选项1:更改监听器的端口,使其与Docker端口重定向所针对的端口一致

version: '3'

services:
  kafka-0:
    image: confluentinc/cp-kafka:5.4.1
    container_name: kafka-0
    ports:
      - "9093:9092"
    environment:
      - KAFKA_BROKER_ID=1
      - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
      - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
      - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka-0:29094,PLAINTEXT_HOST://localhost:9093
      - KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:29094,PLAINTEXT_HOST://0.0.0.0:9092
      - KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1
    depends_on:
      - zookeeper

  zookeeper:
    image: confluentinc/cp-zookeeper:5.4.1
    container_name: zookeeper
    ports:
      - "2182:2181"
    environment:
      - ZOOKEEPER_CLIENT_PORT=2181

✅测试:

 kafkacat -b localhost:9093 -L
Metadata for all topics (from broker 1: localhost:9093/1):
 1 brokers:
  broker 1 at localhost:9093 (controller)

选项二:更改Docker端口重定向,使其定位于侦听器所在的端口

version: '3'

services:
  kafka-0:
    image: confluentinc/cp-kafka:5.4.1
    container_name: kafka-0
    ports:
      - "9093:9093"
    environment:
      - KAFKA_BROKER_ID=1
      - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
      - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
      - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka-0:29094,PLAINTEXT_HOST://localhost:9093
      # If you don't specify KAFKA_LISTENERS it will default to the ports used in
      # KAFKA_ADVERTISED_LISTENERS, but IMO it's better to be explicit about these settings
      - KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:29094,PLAINTEXT_HOST://0.0.0.0:9093
      - KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1
    depends_on:
      - zookeeper

  zookeeper:
    image: confluentinc/cp-zookeeper:5.4.1
    container_name: zookeeper
    ports:
      - "2182:2181"
    environment:
      - ZOOKEEPER_CLIENT_PORT=2181

✅测试

➜ kafkacat -b localhost:9093 -L
Metadata for all topics (from broker 1: localhost:9093/1):
 1 brokers:
  broker 1 at localhost:9093 (controller)

在Docker网络中连接Kafka

以上示例是关于如何从Docker主机连接到Kafka的。如果您想要从Docker网络内(例如另一个容器)连接到它,您需要将kafka-0:29094作为broker主机和IP。如果您尝试使用localhost:9093,则客户端容器将会将localhost解析为其自己的容器,从而导致失败。

多个broker

点击此处查看带有多个Kafka brokers的Docker Compose示例。

参考资料

https://rmoff.net/2018/08/02/kafka-listeners-explained/


但是同样的问题,端口29094从哪里来?在我看来,这是容器中使用的端口。 - Vincent
@Vincent 29094只是用于其中一个监听器端口的任意数字。 - Robin Moffatt
kafka-0的端口映射是“9093: 9093”,因此在容器中,端口应该是9093。对吧? - Vincent
@Vincent,随意开一个新问题来讨论这个 :) - Robin Moffatt

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