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绑定、网络子网固定和数据持久化,可有效应对虚拟机挂起恢复后的网络变化问题。

相关推荐
mingyuewu2 小时前
MAC安装docker 后提示com.docker.vmnetd”将对您的电脑造成伤害
macos·docker·容器
小小寂寞的城2 小时前
Ubuntu里安装Jenkins
ubuntu·ci/cd·docker·jenkins
半间烟雨3 小时前
⼆、Kafka客户端消息流转流程
分布式·kafka
Architect_Lee5 小时前
阿里云服务器安装docker以及mysql数据库
阿里云·docker·云计算
geek_super5 小时前
Docker学习--容器的root文件系统(rootfs)命令--docker cp 命令
docker
专注代码七年5 小时前
Docker运维篇
运维·docker·容器
一杯敬朝阳 一杯敬月光6 小时前
WIN11 企业版 部署Dify+Docker
运维·docker·容器
Leo Han6 小时前
k8s常用命令(持续更新中)
docker·容器·kubernetes
KubeSphere 云原生6 小时前
云原生周刊:Kubernetes v1.33 要来了
云原生·容器·kubernetes
FLGB9 小时前
Kafka延迟队列实现分级重试
分布式·kafka