Docker容器的kafka在VM虚拟机挂起重新运行之后连接异常解决

Docker容器的kafka在VM虚拟机挂起重新运行之后连接异常解决

在虚拟机安装Docker形式的kafka可参考:

https://blog.csdn.net/weixin_42949219/article/details/146045338?spm=1011.2415.3001.5331

当时可以连接,但是在虚拟机挂起重新运行之后连接异常:我估计应该是IP动态变化导致的,所以需要修改对应配置。

以下是我的解决方案:

docker-compose.yml文件

bash 复制代码
version: '3.8'

services:
  zookeeper:
    image: wurstmeister/zookeeper
    container_name: zookeeper
    ports:
      - "2181:2181"
    networks:
      - kafka-net
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_LISTEN_ADDRESS: 0.0.0.0  # 关键:强制监听所有接口
    volumes:
      - ./zookeeper/data:/data           # 数据持久化
    healthcheck:
      test: ["CMD-SHELL", "echo stat | nc 127.0.0.1 2181 | grep Mode"]
      interval: 10s
      timeout: 5s
      retries: 3

  kafka1:
    image: wurstmeister/kafka
    container_name: kafka1
    ports:
      - "19092:9092"
    networks:
      - kafka-net
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181  # 使用服务名称访问
      KAFKA_LISTENERS: INSIDE://0.0.0.0:9093,OUTSIDE://0.0.0.0:9092
      KAFKA_ADVERTISED_LISTENERS: INSIDE://kafka1:9093,OUTSIDE://${HOST_IP}:19092  # 动态IP
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
      KAFKA_AUTO_CREATE_TOPICS_ENABLE: "false"
    volumes:
      - ./kafka1/data:/opt/kafka/data  # 数据持久化
    depends_on:
      zookeeper:
        condition: service_healthy  # 等待ZooKeeper就绪

  kafka2:
    image: wurstmeister/kafka
    container_name: kafka2
    ports:
      - "19093:9092"
    networks:
      - kafka-net
    environment:
      KAFKA_BROKER_ID: 2
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_LISTENERS: INSIDE://0.0.0.0:9093,OUTSIDE://0.0.0.0:9092
      KAFKA_ADVERTISED_LISTENERS: INSIDE://kafka2:9093,OUTSIDE://${HOST_IP}:19093
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
      KAFKA_AUTO_CREATE_TOPICS_ENABLE: "false"
    volumes:
      - ./kafka2/data:/opt/kafka/data
    depends_on:
      zookeeper:
        condition: service_healthy

  kafka3:
    image: wurstmeister/kafka
    container_name: kafka3
    ports:
      - "19094:9092"
    networks:
      - kafka-net
    environment:
      KAFKA_BROKER_ID: 3
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_LISTENERS: INSIDE://0.0.0.0:9093,OUTSIDE://0.0.0.0:9092
      KAFKA_ADVERTISED_LISTENERS: INSIDE://kafka3:9093,OUTSIDE://${HOST_IP}:19094
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
      KAFKA_AUTO_CREATE_TOPICS_ENABLE: "false"
    volumes:
      - ./kafka3/data:/opt/kafka/data
    depends_on:
      zookeeper:
        condition: service_healthy

networks:
  kafka-net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16  # 固定子网防止IP变化

操作步骤

清理旧环境

bash 复制代码
docker-compose down -v  # 清除旧数据和网络
rm -rf zookeeper/data kafka*/data  # 删除残留数据(首次可跳过)

设置宿主机IP变量

bash 复制代码
export HOST_IP=$(hostname -I | awk '{print $1}')  # 自动获取本机IP

启动服务

bash 复制代码
docker-compose up -d

验证服务状态

检查ZooKeeper日志

bash 复制代码
docker logs zookeeper | grep "binding to port"

检查Kafka节点日志

bash 复制代码
docker logs kafka1 | grep "Registered broker 1"

测试跨容器通信

bash 复制代码
# 安装网络工具
apt update && apt install -y telnet

docker exec -it kafka1 telnet zookeeper 2181

创建测试Topic

bash 复制代码
docker exec kafka1 kafka-topics.sh --create \
  --bootstrap-server localhost:9092 \
  --topic test-topic \
  --partitions 3 \
  --replication-factor 2

关键配置说明

网络稳定性优化

显式指定子网 (172.20.0.0/16) 防止虚拟机恢复时IP变化

使用 condition: service_healthy 确保依赖启动顺序

ZooKeeper 可靠性

ZOOKEEPER_LISTEN_ADDRESS: 0.0.0.0 强制监听所有接口

健康检查通过 nc 命令验证服务状态

Kafka 动态IP配置

${HOST_IP} 环境变量动态注入宿主机IP

每个Broker的 OUTSIDE 端口递增映射 (19092-19094)

数据持久化

ZooKeeper数据目录: ./zookeeper/data

Kafka数据目录: ./kafka{1-3}/data

常见问题处理

持续出现 ZooKeeper 连接超时
bash 复制代码
检查容器IP是否在同一个子网
docker network inspect kafka-net | grep IPv4Address

临时关闭SELinux/AppArmor
sudo setenforce 0  # CentOS/RHEL
sudo systemctl stop apparmor  # Ubuntu
Topic创建失败
bash 复制代码
检查副本数是否小于等于Broker数量
docker exec kafka1 kafka-topics.sh --describe --topic test-topic --bootstrap-server localhost:9092
外部客户端无法连接
bash 复制代码
 验证宿主机防火墙规则
sudo iptables -L -n | grep 1909
telnet ${HOST_IP} 19092

该配置通过动态IP绑定、网络子网固定和数据持久化,可有效应对虚拟机挂起恢复后的网络变化问题。

相关推荐
冬奇Lab12 小时前
一天一个开源项目(第41篇):Workout.cool - 现代化开源健身教练平台,训练计划与进度追踪
docker·开源·资讯
天朝八阿哥19 小时前
使用Docker+vscode搭建离线的go开发调试环境
后端·docker·visual studio code
初次攀爬者2 天前
Kafka的Rebalance基础介绍
后端·kafka
阿虎儿2 天前
Docker安装(非sudo用户可用)
docker
初次攀爬者3 天前
Kafka + KRaft模式架构基础介绍
后端·kafka
初次攀爬者3 天前
Kafka + ZooKeeper架构基础介绍
后端·zookeeper·kafka
初次攀爬者3 天前
Kafka 基础介绍
spring boot·kafka·消息队列
fetasty3 天前
rustfs加picgo图床搭建
docker
蝎子莱莱爱打怪4 天前
GitLab CI/CD + Docker Registry + K8s 部署完整实战指南
后端·docker·kubernetes
小p5 天前
docker学习7:docker 容器的通信方式
docker