Docker/Docker-Compose 安装 Kafka

该博客详细介绍了如何使用Docker和Docker-Compose在本地环境中部署Zookeeper和Kafka集群,并配置了Kafka-Manager进行管理。步骤包括下载镜像、启动容器、设置环境变量以及测试Kafka的基本操作,如创建Topic、发送和消费消息。

安装环境

安装 Zookeeper

1.下载镜像

docker pull zookeeper:3.7

2.启动

docker run -d --name zookeeper -p 2181:2181 -e TZ="Asia/Shanghai" -v /opt/zookeeper/data:/data --restart always zookeeper:3.7

安装 Kafka

1.下载镜像

docker pull wurstmeister/kafka

2.启动

docker run -d --name kafka -p 9092:9092 -e KAFKA_BROKER_ID=0 -e KAFKA_ZOOKEEPER_CONNECT=Zookeeper-IP:2181 -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://IP:9092 -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 -e TZ="Asia/Shanghai" wurstmeister/kafka

启动环境变量参数说明

变量描述
KAFKA_BROKER_IDkafka集群中每个kafka都有一个BROKER_ID来区分自己
KAFKA_ADVERTISED_LISTENERSkafka的地址和端口,用于向zookeeper注册
KAFKA_ZOOKEEPER_CONNECTzookeeper地址
KAFKA_LISTENERSkafka监听端口
TZ容器时区

安装 Manager

1.下载镜像

docker pull sheepkiller/kafka-manager

2.启动

docker run -d --name kfk-manager --restart always -p 9000:9000 -e ZK_HOSTS=<这里换成你的zookeeper地址和端口> sheepkiller/kafka-manager

Docker-Compose 安装 Kafka

新建目录

mkdir kafka

新建 docker-compose.yml

version: '3.5'
services:
  zookeeper:
    image: wurstmeister/zookeeper   ## 镜像
    container_name: zookeeper
    ports:
      - "2181:2181"                 ## 对外暴露的端口号
  kafka:
    image: wurstmeister/kafka       ## 镜像
    container_name: kafka
    volumes: 
        - /etc/localtime:/etc/localtime ## 挂载位置(kafka镜像和宿主机器之间时间保持一直)
    ports:
      - "9092:9092"
    environment:
      KAFKA_ADVERTISED_HOST_NAME: 127.0.0.1         ## 修改:宿主机IP
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181       ## 卡夫卡运行是基于zookeeper的
      KAFKA_ADVERTISED_PORT: 9092
      KAFKA_LOG_RETENTION_HOURS: 120
      KAFKA_MESSAGE_MAX_BYTES: 10000000
      KAFKA_REPLICA_FETCH_MAX_BYTES: 10000000
      KAFKA_GROUP_MAX_SESSION_TIMEOUT_MS: 60000
      KAFKA_NUM_PARTITIONS: 3
      KAFKA_DELETE_RETENTION_MS: 1000
  kafka-manager:
    image: sheepkiller/kafka-manager                ## 镜像:开源的web管理kafka集群的界面
    container_name: kafka-manager
    environment:
        ZK_HOSTS: 127.0.0.1                         ## 修改:宿主机IP
    ports:  
      - "9009:9000"                                 ## 暴露端口 9000这个端口冲突太多

启动

docker-compose up -d --build

测试

1.通过容器名称进入到 kafka 容器中

docker exec -it kafka /bin/bash

2.创建一个名称为 mingyue 的 topic

kafka-topics.sh --create --topic mingyue \
--zookeeper zookeeper:2181 --replication-factor 1 \
--partitions 1

输出日志:

Created topic mingyue.

3.查看刚刚创建的 topic 信息

kafka-topics.sh --zookeeper zookeeper:2181 --describe --topic mingyue

输出日志:

Topic: mingyue	TopicId: jn6EBXBFStqH4s1zTERmnQ	PartitionCount: 1	ReplicationFactor: 1	Configs: 
Topic: mingyue	Partition: 0	Leader: 1001	Replicas: 1001	Isr: 1001

4.打开生产者发送消息

kafka-console-producer.sh --topic=mingyue \
--broker-list kafka:9092

5.消费者接收消息

kafka-console-consumer.sh \
--bootstrap-server kafka:9092 \
--from-beginning --topic mingyue

输入日志:

# 生产者发送消息
bash-5.1# kafka-console-producer.sh --topic=mingyue \
> --broker-list kafka:9092
>hahah
>love
>mingyue

# 消费者接收消息
bash-5.1# kafka-console-consumer.sh \
> --bootstrap-server kafka:9092 \
> --from-beginning --topic mingyue
hahah
love
mingyue
<think>我们正在运行一个Kafka容器,使用了两个卷映射:一个是配置文件,另一个是数据目录。 报错信息没有直接给出,但根据经验,常见的错误可能包括: 1. 宿主机路径不存在:Docker要求宿主机路径必须存在(如果是文件,则文件必须存在;如果是目录,则目录必须存在或会被创建)。但注意:如果映射的是文件,而宿主机上不存在该文件,那么Docker会将其作为目录创建,导致错误。 2. 权限问题:容器内的进程(通常以非root用户运行)可能没有权限读写宿主机映射的目录或文件。 3. 配置文件错误:Kafka的配置文件可能有误,导致启动失败。 4. 端口冲突:宿主机上9092或9093端口已被占用。 5. 容器名称冲突:已经有一个名为kafka1的容器存在(根据引用[4]和引用[5]可知,容器名必须唯一)。 为了定位问题,我们需要查看具体的错误日志。但是,我们可以根据常见情况逐一排查。 步骤1:检查容器名称是否冲突 运行:`docker ps -a`,查看是否有名为kafka1的容器(无论是否运行)。如果有,需要先删除(`docker rm kafka1`)或使用不同的名称。 步骤2:检查宿主机路径是否存在 命令中映射了两个路径: - /usr/local/kafka_docker/conf/server.properties (文件) - /usr/local/kafka_docker/data (目录) 对于第一个映射(配置文件): - 必须确保宿主机上存在`/usr/local/kafka_docker/conf/server.properties`这个文件,并且是一个文件(不是目录)。 - 如果该路径不存在,Docker会尝试创建一个目录(因为-v映射时,如果宿主机路径不存在,会创建为目录),这样就会导致容器内映射错误(容器内需要的是文件,结果映射成了一个目录)。 对于第二个映射(数据目录): - 如果宿主机上不存在`/usr/local/kafka_docker/data`,Docker会自动创建该目录(作为目录创建),这通常不会导致问题,但要注意权限。 步骤3:检查权限 如果宿主机上的配置文件或数据目录的权限不足,容器内的进程(可能是非root用户)可能无法读取或写入。 对于配置文件: - 确保配置文件可读:`chmod a+r /usr/local/kafka_docker/conf/server.properties` 对于数据目录: - 通常需要写权限,可以设置宽松的权限:`chmod a+w /usr/local/kafka_docker/data` 或者更安全地设置属主(根据容器内运行Kafka的用户,通常Kafka镜像内运行的用户可能为kafka,UID可能为1000或1001,具体看镜像文档) - 或者,在宿主机上创建目录时指定权限:`sudo mkdir -p /usr/local/kafka_docker/data && sudo chown -R 1000:1000 /usr/local/kafka_docker/data` (假设容器内用户UID为1000) 步骤4:检查端口是否被占用 使用命令:`netstat -tuln | grep -E &#39;9092|9093&#39;` 查看端口是否被占用。 步骤5:查看容器日志 如果容器启动后立即退出,可以通过查看容器日志来获取错误信息: `docker logs kafka1` 常见错误场景: 场景1:配置文件映射错误(宿主机文件不存在,被创建为目录) - 错误现象:容器启动失败,日志中可能出现类似“java.io.IOException: Is a directory”或者“文件读取错误”等。 - 解决:确保宿主机上存在该配置文件,并且是一个文件。 场景2:数据目录权限不足 - 错误现象:日志中可能出现“Permission denied”字样,涉及数据目录。 - 解决:更改宿主机目录权限。 场景3Kafka配置问题 - 例如,Kafka配置中需要设置`listeners`和`advertised.listeners`,以正确绑定网络。 - 在配置文件中,你可能需要设置: listeners=PLAINTEXT://:9092 advertised.listeners=PLAINTEXT://<宿主机IP>:9092 注意:如果使用容器名称或主机名,确保网络配置正确。 由于你没有提供具体的错误信息,我给出一个通用的解决方案: 1. 确保宿主机配置文件存在(并且是文件): ```bash sudo mkdir -p /usr/local/kafka_docker/conf # 如果server.properties文件不存在,则需要创建一个(可以从Kafka官方获取默认配置) # 下载默认配置文件(假设使用curl) sudo curl -o /usr/local/kafka_docker/conf/server.properties https://raw.githubusercontent.com/apache/kafka/3.7.1/config/server.properties ``` 2. 修改配置文件以适配容器运行: 至少需要修改以下配置(根据你的环境调整): ```properties # 设置broker.id,每个broker必须唯一 broker.id=1 # 监听地址 listeners=PLAINTEXT://0.0.0.0:9092 # 如果你需要外部访问,设置advertised.listeners为宿主机的IP或域名(注意:容器内可能无法解析宿主机主机名,建议使用IP) advertised.listeners=PLAINTEXT://<宿主机IP>:9092 # 数据目录(容器内路径) log.dirs=/opt/kafka/data # Zookeeper连接(如果使用外部Zookeeper,需要设置) zookeeper.connect=localhost:2181 ``` 注意:如果使用Docker Compose,通常使用服务名(如zookeeper:2181),但这里我们是单独运行Kafka容器,所以需要指定Zookeeper地址。如果未配置Zookeeper,则需要同时启动Zookeeper3. 创建数据目录并设置权限: ```bash sudo mkdir -p /usr/local/kafka_docker/data sudo chmod -R a+w /usr/local/kafka_docker/data # 或者更精确地设置用户 # 或者,如果你知道容器内用户的UID(假设为1000): sudo chown -R 1000:1000 /usr/local/kafka_docker/data ``` 4. 确保没有容器名冲突和端口冲突。 5. 重新运行容器,并查看日志: ```bash docker run -d --name kafka1 -p 9092:9092 -p 9093:9093 -e KAFKA_CLUSTER_ID=hWhZ9DBPRligdOE8VEkeEA -v /usr/local/kafka_docker/conf/server.properties:/opt/kafka/config/server.properties -v /usr/local/kafka_docker/data:/opt/kafka/data --privileged=true apache/kafka:3.7.1 docker logs -f kafka1 ``` 如果问题仍然存在,请根据日志信息进一步排查。 注意:Kafka容器通常需要依赖Zookeeper(除非使用Kafka with KRaft模式)。在命令中我们没有看到指定Zookeeper的配置(环境变量或配置文件中的zookeeper.connect)。在Kafka 3.7.1中,默认是使用KRaft模式吗?或者还是需要Zookeeper? 查看apache/kafka镜像的文档:默认情况下,该镜像支持两种模式。如果设置了`KAFKA_CLUSTER_ID`,那么它将使用KRaft模式(不需要Zookeeper)。但如果是KRaft模式,还需要配置一些额外的参数。 如果你希望使用Zookeeper模式,则应该设置环境变量`KAFKA_ZOOKEEPER_CONNECT`,并且不要设置`KAFKA_CLUSTER_ID`(或者按照文档说明配置)。 因此,另一个可能的错误是配置模式错误。如果你打算使用Zookeeper模式,那么应该: - 移除`KAFKA_CLUSTER_ID`环境变量 - 在配置文件中设置`zookeeper.connect`,或者通过环境变量`KAFKA_ZOOKEEPER_CONNECT`设置 总结:问题可能有多方面原因,需要根据日志逐一排查。以上提供了常见的解决方向。 </think> ### Kafka 容器启动报错原因分析与解决方案 根据您的命令和 Kafka 容器常见问题,以下是可能的原因及解决方案: #### 🔍 常见报错原因 1. **权限问题**(最常见) - Kafka 容器默认以非 root 用户运行(如 UID 1000)[^1] - 宿主机映射目录权限不足导致写入失败 ```bash # 错误日志示例 java.io.IOException: Permission denied ``` 2. **配置文件映射错误** - `/usr/local/kafka_docker/conf/server.properties` 宿主机文件不存在 - 文件被误创建为目录(Docker 对不存在的文件会创建目录)[^2] 3. **数据目录冲突** - Kafka 要求数据目录为空,若宿主机目录已存在内容会导致冲突 4. **端口冲突** - 宿主机 9092/9093 端口被占用(如已有 Kafka 实例)[^4] 5. **容器名冲突** - 已有同名容器 `kafka1` 在运行[^4][^5] #### ✅ 解决方案步骤 1. **检查并修复权限**(关键步骤) ```bash # 创建目录并赋权(假设 Kafka UID=1000) sudo mkdir -p /usr/local/kafka_docker/{conf,data} sudo chown -R 1000:1000 /usr/local/kafka_docker/data sudo chmod -R 755 /usr/local/kafka_docker ``` 2. **验证配置文件存在性** ```bash # 确保配置文件是真实文件(非目录) ls -l /usr/local/kafka_docker/conf/server.properties # 若无配置文件,从镜像提取默认配置 docker run --rm apache/kafka:3.7.1 \ cat /opt/kafka/config/server.properties > /usr/local/kafka_docker/conf/server.properties ``` 3. **清理冲突资源** ```bash # 停止同名容器 docker stop kafka1 && docker rm kafka1 # 检查端口占用 sudo lsof -i :9092 ``` 4. **添加必要环境变量**(KRaft 模式要求) ```bash # 补全Kafka运行模式配置 -e KAFKA_NODE_ID=1 \ -e KAFKA_PROCESS_ROLES=controller,broker \ -e KAFKA_CONTROLLER_QUORUM_VOTERS=1@kafka1:9093 \ -e KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT \ -e KAFKA_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093 \ -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://<宿主机IP>:9092 \ ``` 5. **完整修正命令** ```bash docker run -d --name kafka1 \ -p 9092:9092 -p 9093:9093 \ -e KAFKA_CLUSTER_ID=hWhZ9DBPRligdOE8VEkeEA \ -e KAFKA_NODE_ID=1 \ -e KAFKA_PROCESS_ROLES=controller,broker \ -e KAFKA_CONTROLLER_QUORUM_VOTERS=1@kafka1:9093 \ -e KAFKA_LISTENER_SECURITY_PROTOCOL_MAP="CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT" \ -e KAFKA_LISTENERS="PLAINTEXT://:9092,CONTROLLER://:9093" \ -e KAFKA_ADVERTISED_LISTENERS="PLAINTEXT://<宿主机IP>:9092" \ -v /usr/local/kafka_docker/conf/server.properties:/opt/kafka/config/server.properties \ -v /usr/local/kafka_docker/data:/opt/kafka/data \ --privileged=true \ apache/kafka:3.7.1 ``` #### ⚠️ 关键注意事项 1. **网络配置**: - 替换 `<宿主机IP>` 为实际 IP(非 127.0.0.1) - KRaft 模式需要控制器端口 9093[^3] 2. **数据目录**: - 首次启动前确保 `/usr/local/kafka_docker/data` 为空目录 - 使用 `tree /usr/local/kafka_docker` 检查目录结构 3. **日志诊断**: ```bash docker logs -f kafka1 | grep -i error ``` > 💡 **经验提示**:使用 Docker Compose 管理 Kafka 集群可显著降低配置复杂度[^3],参考示例配置见引用[1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Strive_MY

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值