# kafka_server **Repository Path**: Uping61/kafka_server ## Basic Information - **Project Name**: kafka_server - **Description**: kafka单机部署(无认证与加密认证),兼容使用localhost(linux, win/mac) - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-09-11 - **Last Updated**: 2026-02-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README **不能简单地把 `192.168.8.8` 改成 `localhost`**,否则**容器外的客户端(你的 Python 程序)会连不上 Kafka**。 这是 Kafka 的经典“** advertised listeners **”陷阱。 --- ### 🔍 为什么? - `KAFKA_ADVERTISED_LISTENERS` 是 **Kafka 返回给客户端的地址**,客户端后续会用它建立连接。 - 如果你写成 `localhost`,**容器外的程序解析到的就是容器内部的 localhost**,也就是 **自己**,而不是 Kafka 容器,于是连不上。 --- ### ✅ 正确做法:让外部和内部都能用 #### 场景 1:只在 **本机开发**(Windows/Mac 单机) 1. 把 `KAFKA_ADVERTISED_LISTENERS` 改成 **宿主机的 IP 或 hostname**,但**不能写 localhost**。 2. 用 **host network** 模式,让容器共享宿主机网络,这样 `localhost` 就真的指向宿主机。 **改法(host 网络模式)**: ```yaml version: '3' services: zookeeper: image: wurstmeister/zookeeper container_name: zookeeper network_mode: host # ← 关键 kafka: image: wurstmeister/kafka container_name: kafka01 network_mode: host # ← 关键 environment: KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092 KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092 KAFKA_ZOOKEEPER_CONNECT: localhost:2181 KAFKA_BROKER_ID: 1 KAFKA_CREATE_TOPICS: TestComposeTopic:2:1 ``` 此时: - 你在宿主机上用 `localhost:9092` 就能连。 - **无需再写死 192.168.8.8**。 - **缺点**:只能在 **Linux 宿主机** 用 host 模式;Windows/Mac 的 Docker Desktop 不支持 host 网络,会退回到虚拟机内部,仍需要宿主机 IP。 --- #### 场景 2:Windows/Mac 开发(Docker Desktop) Docker Desktop 里容器跑在轻量虚拟机里,**host 网络无效**。 **唯一办法**: - 用 **特殊 DNS 名 `host.docker.internal`**(Docker Desktop 内置,指向宿主机)。 - 把 advertised listener 写成这个地址: ```yaml environment: KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://host.docker.internal:9092 KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092 KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 ``` - 容器外的 Python 程序连 `host.docker.internal:9092` 即可。 - **注意**:**Linux 原生 Docker 不支持 `host.docker.internal`**,只在 Docker Desktop 有效。 --- ### ✅ 总结一句话 | 运行环境 | 推荐写法 | |------------------|--------------------------------------------------------------------------| | Linux 本机开发 | `network_mode: host` + `PLAINTEXT://localhost:9092` | | Windows/Mac 桌面 | 保持 bridge 模式 + `PLAINTEXT://host.docker.internal:9092` | | 生产/多机 | 用真实 IP 或 DNS,配合 `KAFKA_ADVERTISED_LISTENERS` 写外部可解析的地址 | --- 按你的场景,**如果是 Linux 宿主机**,直接加 `network_mode: host` 最干净; **如果是 Windows/Mac**,改成 `host.docker.internal:9092` 即可摆脱硬编码 IP。