一条指令,解决外网无法访问云服务器Kafka容器问题

前言

在上一篇跟着官方文档使用docker,在云服务器上搭建了一个单节点的Kafka集群,在云服务器上连接成功,当我在笔记本上使用Spark尝试连接的时候,无法消费到数据。

从上图可以看出,我在consumer config中明明将bootstrap.servers设置成了弹性公网IP,而且在笔记本上Telnet连接Kafka网络也是通的。

但是当我启动Spark程序之后,程序应该输出从kakfa中消费的数据,但是程序却卡住了。

从日志最后一行可以看到,这里居然连接的是localhost,这肯定是消费不到数据的。但是我明明在程序中使用的是弹性公网IP,怎么到这里就成了localhost了…

问题分析

遇到这种问题,首先排查Kafka服务端的问题,于是我就去容器中查看Kafka的配置,看那个配置选项使用了localhost,然后再进行反推这个问题。

通过docker exec指令进入到kafka容器,然后就开始从各个目录翻找server.properties,在/etc/kafk/docker目录找到了配置文件。

grep localhost一共找到了两个参数,去官网找了一下配置说明,发现第2个配置是导致此问题出现的”元凶“。

advertised.listeners

首先看advertised.listeners选项说明。

然后买一赠一,与listeners一起学习效果更佳。

listenersadvertised.listeners的大概意思就是,listeners是Kafka服务器用于监听客户端连接的地址,包括外部客户端和其他Kafka服务器之间的连接,用于客户端与kafka之间的数据交互的地址。

而advertised.listeners是Kafka向客户端广播的地址。如果Kafka服务器处于内部网络中,而客户端处于外部网络中,则advertised.listeners中的地址需要配置为外部可访问的地址。

这样客户端在连接时,先在zookeeper或者KRaft中查找advertised.listeners广播的地址,然后再去匹配listeners中配置的地址连接Kafka读取数据。

listeners的常见的写法如下:

PLAINTEXT://:9092
PLAINTEXT://0.0.0.0:9092
PLAINTEXT://ip:9092

前两种写法感觉没什么区别,都是监听所有的地址,包括弹性公网IP,第三种写

<think>好的,我现在需要解决用户的问题:在Ubuntu虚拟机里的Docker启动一个Kafka容器,让主机能访问。首先,我需要回忆一下Docker容器网络配置的相关知识,以及Kafka的网络设置要点。 首先,用户的环境是Ubuntu虚拟机,主机(比如Windows或Mac)需要访问虚拟机内Docker运行的Kafka容器。关键在于确保Kafka的监听地址和端口能够被主机正确访问。 首先,Docker容器默认使用桥接网络(bridge),但可能需要映射端口到主机。Kafka依赖ZooKeeper,所以通常需要同时启动ZooKeeper容器Kafka容器。需要注意Kafka的配置中,`advertised.listeners`必须设置为外部可访问的地址,否则客户端可能无法连接。 步骤可能包括: 1. 拉取Kafka和ZooKeeper镜像,比如使用Confluent的官方镜像或者wurstmeister的镜像(常用的是wurstmeister/kafka)。 2. 启动ZooKeeper容器,映射2181端口。 3. 启动Kafka容器,需要设置环境变量,特别是`KAFKA_ADVERTISED_LISTENERS`,这里应该指向虚拟机的IP地址(因为主机需要通过虚拟机IP访问),而不是容器内部的IP或localhost。同时,需要映射Kafka的9092端口到虚拟机的某个端口(比如9092),这样主机可以通过虚拟机IP:9092访问。 4. 检查网络配置,确保虚拟机的防火墙允许9092端口的入站连接。 5. 测试连接,使用主机上的Kafka客户端工具(如kafka-console-producer.sh)连接虚拟机IP:9092,验证是否能发送消息。 需要注意的点: - `advertised.listeners`必须设置为虚拟机的IP地址,而不是容器IP或`localhost`,否则Kafka会告诉客户端连接到容器内部地址,导致主机无法访问。 - 如果虚拟机使用NAT网络(比如VirtualBox默认的NAT),需要在虚拟机的网络设置中添加端口转发规则,将主机的某个端口(如9092)转发到虚拟机的9092端口。如果是桥接网络,虚拟机有独立的IP,主机可以直接访问该IP的9092端口。 - 确保ZooKeeper的连接地址正确,Kafka容器需要能够访问ZooKeeper容器,可能使用容器名作为主机名(在Docker同一网络下)。 可能的Docker命令示例(使用wurstmeister镜像): 启动ZooKeeper: ```bash docker run -d --name zookeeper -p 2181:2181 zookeeper:3.8 ``` 启动Kafka,注意替换`<虚拟机IP>`为Ubuntu虚拟机的实际IP(如192.168.1.100): ```bash docker run -d --name kafka \ -p 9092:9092 \ -e KAFKA_BROKER_ID=0 \ -e KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 \ -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://<虚拟机IP>:9092 \ -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 \ --link zookeeper \ wurstmeister/kafka:2.13-2.8.1 ``` 如果虚拟机使用NAT,可能需要在VirtualBox中设置端口转发:主机端口9092 → 虚拟机IP:9092。这样主机可以通过localhost:9092访问,或者如果虚拟机有独立IP,则直接使用该IP。 验证方法:在主机上使用telnet或kafka客户端工具连接虚拟机IP:9092,确认端口是否开放。如果连接失败,检查防火墙(ufw在Ubuntu上是否允许9092端口)、Docker端口映射是否正确、`advertised.listeners`是否设置正确。 总结步骤:安装Docker,拉取镜像,启动ZooKeeper和Kafka容器(正确配置环境变量),配置网络(端口映射或虚拟机端口转发),测试连接。 </think>要在Ubuntu虚拟机的Docker中启动Kafka容器并让主机访问,需重点配置Kafka的监听地址和Docker端口映射。以下是具体步骤: ### 步骤说明 1. **安装Docker**(若未安装) 确保Ubuntu虚拟机已安装Docker,可通过`sudo apt-get install docker.io`安装,或使用官方脚本安装。 2. **启动ZooKeeper容器** Kafka依赖ZooKeeper管理元数据,需先启动ZooKeeper容器: ```bash docker run -d --name zookeeper -p 2181:2181 zookeeper:3.8 ``` 3. **启动Kafka容器并配置网络** 使用`wurstmeister/kafka`镜像(常用且配置灵活),关键是设置`KAFKA_ADVERTISED_LISTENERS`为虚拟机的IP(主机能访问的IP),确保客户端连接时使用该地址。命令示例: ```bash docker run -d --name kafka \ -p 9092:9092 \ # 映射容器9092端口到虚拟机9092端口 -e KAFKA_BROKER_ID=0 \ # broker唯一ID -e KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 \ # ZooKeeper连接地址(容器名) -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://<虚拟机IP>:9092 \ # 主机访问的地址(替换为虚拟机实际IP,如192.168.1.100) -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 \ # 容器内部监听所有接口 --link zookeeper \ # 连接ZooKeeper容器(可选,若使用自定义网络则更推荐) wurstmeister/kafka:2.13-2.8.1 ``` 4. **配置虚拟机网络** - 若虚拟机使用**桥接模式**(虚拟机与主机同网段),主机可直接通过虚拟机IP:9092访问。 - 若使用**NAT模式**(如VirtualBox默认),需在虚拟机软件(如VirtualBox)中添加端口转发规则:主机端口(如9092)→ 虚拟机IP:9092。 5. **验证访问** 在主机上使用Kafka客户端工具(如`kafka-console-producer.sh`)连接测试: ```bash ./kafka-console-producer.sh --bootstrap-server <虚拟机IP>:9092 --topic test ``` ### 注意事项 - **`advertised.listeners`必须正确**:若设置为容器IP或`localhost`,主机会无法连接(客户端会被导向容器内部地址)。 - **防火墙放行端口**:Ubuntu需确保`ufw`放行9092端口(`sudo ufw allow 9092`)。 - **ZooKeeper连接性**:Kafka容器需能访问ZooKeeper容器(通过容器名或自定义网络)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值