docker安装【zookeeper】&【kafka】&【provectuslabs/kafka-ui】记录

  • (选做)新环境没有jdk,安装jdk-17.0.10备用
mkdir -p /export/{data,apps,logs,conf,downloads}

cd /export/downloads

curl -OLk  https://download.oracle.com/java/17/archive/jdk-17.0.10_linux-x64_bin.tar.gz

tar zxf jdk-17.0.10_linux-x64_bin.tar.gz

mv /export/downloads/jdk-17.0.10 /export/apps/

ln -s /export/apps/jdk-17.0.10 /export/apps/jdk

cat >> /etc/profile << EOF
export JAVA_HOME=/export/apps/jdk
export CLASSPATH=.:$JAVA_HOME/lib/
export PATH=.:\$JAVA_HOME/bin:\$PATH
EOF

source /etc/profile

1.安装zookeeper:3.9.2-jre-17

  • 注意修改端口映射
docker pull zookeeper:3.9.2-jre-17

sudo docker run -d --name zk --privileged -p 2181:2181 -p 2888:2888 -p 3888:3888 zookeeper:3.9.2-jre-17

2.安装kafka:3.7.0

  • 注意修改zk地址及端口
docker pull bitnami/kafka:3.7.0

docker run -d -t -p 9092:9092 --restart=always \
-e KAFKA_BROKER_ID=0 \
-e ALLOW_PLAINTEXT_LISTENER=yes \
-e KAFKA_CFG_ZOOKEEPER_CONNECT=192.168.1.30:2181 \
-e KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://192.168.1.30:9092 \
-e TZ="Asia/Shanghai" --name kafka-0 --privileged=true bitnami/kafka:3.7.0
  • 安装kafka:3.7.0参数说明
#参数说明
#docker run -d -t -p 9092:9092 --restart=always \
#-p 自己的内网 宿主机端口:容器端口

#-e KAFKA_BROKER_ID=0 \
#集群的broker的ID,该ID是集群的唯一标识,可以理解为节点ID。

#-e ALLOW_PLAINTEXT_LISTENER=yes \
#允许使用PLAINTEXT侦听器

#-e KAFKA_CFG_ZOOKEEPER_CONNECT=192.168.1.30:2181 \
#zookeeper的连接地址

#-e KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://1192.168.1.30:9092 \
#kafka发布到zookeeper供客户端使用的服务地址。

#-e TZ="Asia/Shanghai" --name kafka-0 --privileged=true bitnami/kafka:3.7.0
#TZ:指定时区,这里指定亚洲上海时区,也就是东八区

#--name 给容器取个名字

#--privileged:使用该参数,container内的root拥有真正的root权限。否则,container内的root只是外部的一个普通用户权限。
  • kfk常用命令
#创建topic:kafka-topics.sh --create --bootstrap-server 192.168.1.30:9092 --replication-factor 1 --partitions 3 --topic test
#查看topic列表:kafka-topics.sh --list --bootstrap-server 192.168.1.30:9092
#单个查询topic描述:kafka-topics.sh --topic test --bootstrap-server 192.168.1.30:9092 --describe --exclude-internal
#生产消息:kafka-console-producer.sh --bootstrap-server 192.168.1.30:9092 --topic test
#消费消息:kafka-console-consumer.sh --bootstrap-server 192.168.1.30:9092 --topic test --from-beginning
#删除某条消息:kafka-delete-records.sh --bootstrap-server 192.168.1.30:9092 --offset-json-file /tmp/delete-strategy.json
#{
#  "partitions": [
#    {"topic": "test", "partition": 1, "offset": 1}
#  ],                      
#	"version":1                          
#}
#删除某主题下topic消息(超时时间设置短一些):kafka-configs.sh --zookeeper 192.168.1.30:2181 --entity-type topics --entity-name test --alter --add-config retention.ms=100
#删除topic:kafka-topics --bootstrap-server 192.168.1.30:9092 --topic test --delete
#查看消息内容:kafka-console-consumer.sh --bootstrap-server 192.168.1.30:9200 --topic test --from-beginning

3.安装provectuslabs/kafka-ui

  • 命令行方便,但是更多开发调试的时候仅限于查看,还是要有个ui工具,决定使用kfk-ui
  • kfk-ui官方地址:https://github.com/provectus/kafka-ui
  • 初次启动使用docker compose配置,注意配置端口映射和kafka集群服务器地址及端口
cat > kfkui-docker-compose.yml << EOF
version: '3.4'
services:
  kafka-ui:
    container_name: kafka-ui
    image: provectuslabs/kafka-ui:latest
    ports:
      - 9093:8080

    extra_hosts:
      - "kafka1-nonesecure:192.168.1.30"
    environment:
      KAFKA_CLUSTERS_0_NAME: kafka-cluster-0
      KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka1-nonesecure:9092
EOF

docker compose -f kfkui-docker-compose.yml up -d
  • ui效果
    在这里插入图片描述
&lt;think&gt;我们正在解决用户的问题:在执行docker run启动apache/kafka:3.7.1容器时,提示`chmod: /opt/kafka/logs: Operation not permitted`。 根据错误信息,这通常是由于容器内部进程试图修改挂载的宿主目录权限,但宿主目录的权限设置不允许容器内的操作导致的。 用户提到他们按照官网的docker手册使用自定义配置文件运行kafka容器,命令如下: docker run --volume path/to/property/folder:/mnt/shared/config -p 9092:9092 apache/kafka:latest 在挂载宿主目录到容器内时,如果宿主机目录的权限与容器内进程运行用户(kafka镜像中默认使用用户`kafka`,UID 1000)不匹配,就可能导致此问题。 解决方案通常有两种: 1. 调整宿主机挂载目录的权限,使得容器内用户(UID 1000)有写权限。 2. 在运行容器时,通过指定用户(使用`--user`参数)来覆盖容器内的默认用户,使其与宿主机目录的拥有者匹配。 但是,由于错误发生在`chmod /opt/kafka/logs`,这个目录是容器内部的目录,并不是挂载的宿主机目录。那么为什么会出现这个错误呢? 实际上,用户可能不仅挂载了配置文件目录,还挂载了日志目录(或者数据目录)?因为官网示例只挂载了配置文件目录,而日志目录默认在容器内部。 然而,查看apache/kafka官方镜像的Dockerfile(以3.7.1为例): https://github.com/apache/kafka/blob/3.7/docker/Dockerfile 在Dockerfile中,我们可以看到: RUN mkdir -p $KAFKA_LOG_DIRS &amp;&amp; chown -R $KAFKA_USER:$KAFKA_GROUP $KAFKA_LOG_DIRS 在容器启动时,启动脚本(docker-entrypoint.sh)可能会再次尝试修改日志目录权限,以确保用户kafka有权限写入。 如果用户将宿主机目录挂载到容器内的日志目录(比如`/opt/kafka/logs`),那么容器启动时尝试执行chmod就会作用在宿主机的目录上,而如果宿主机目录的权限不允许容器内用户修改,就会失败。 因此,我们需要检查用户是否挂载了日志目录?用户提供的命令中并没有挂载日志目录,所以可能是用户使用了自定义的启动命令或者环境变量导致?或者用户使用了其他挂载? 用户只挂载了配置文件目录,那么日志目录应该还在容器内部,按理说不会有权限问题。所以,可能是用户没有使用默认的启动命令?或者使用了其他环境变量? 另外,用户提到的是kafka3.7.0,但问题使用的是3.7.1,不过问题应该相同。 我们注意到,在用户提供的kafka-ui的引用中,并没有直接解决这个问题的信息,但我们可以根据经验给出解决方案。 解决方案步骤: 1. 确保没有挂载宿主机目录到容器的日志目录(除非必要)。如果确实需要挂载日志目录到宿主机,那么需要预先在宿主机上创建该目录,并设置正确的权限(让UID 1000的用户有写权限)。 2. 如果必须挂载日志目录,可以在宿主机上执行: mkdir -p /path/to/logs chown -R 1000:1000 /path/to/logs 3. 如果宿主机目录已经存在,并且你不想改变宿主机目录的所有者,可以在运行容器时使用`--user`参数指定一个具有该目录权限的用户UID(比如宿主目录的拥有者UID): docker run --user $(id -u):$(id -g) ... 但是注意,使用`--user`参数可能会带来其他问题,因为容器内的用户kafka(UID1000)被覆盖了,而容器内的一些目录可能还是属于UID1000,这可能导致其他权限问题。 4. 另一种方法是,在Dockerfile中或启动脚本中调整,但用户可能不方便修改镜像。 5. 另外,检查是否SELinux或AppArmor等安全模块阻止了操作。如果是,可以尝试临时禁用SELinux(`setenforce 0`)或添加适当的规则。 由于用户的问题描述中并没有提到挂载日志目录,所以可能是容器内部默认的日志目录权限问题?这不太可能,因为镜像构建时已经设置了权限。 因此,我们更倾向于用户可能挂载了某个目录(比如数据目录或日志目录)而没有正确设置权限。 用户需要检查他们的docker run命令,看是否挂载了除了配置文件目录以外的目录,特别是挂载到了容器内的`/opt/kafka/logs`。 如果用户确实需要挂载日志目录,那么按照步骤2设置宿主机目录权限即可。 如果用户没有挂载,那么可能是其他原因?比如容器运行在只读文件系统上?或者用户使用了`--read-only`参数?或者宿主机目录的挂载选项(如noexec, nosuid, nodev)?这需要进一步排查。 不过,最常见的还是挂载目录的权限问题。 因此,我们建议用户: - 如果挂载了日志目录(或数据目录),请确保宿主机上该目录对UID 1000可写(或者使用`--user`指定有权限的用户)。 - 如果没有挂载日志目录,请尝试不挂载任何目录运行,看是否正常?如果正常,再逐个添加挂载目录排查。 另外,注意:在kraft模式下(Kafka 3.3.1+)可能还需要挂载数据目录,同样需要设置权限。 所以,具体解决步骤建议如下: 1. 首先,确认问题是否由挂载引起:尝试运行一个不挂载任何卷的容器,看是否出现同样错误。 docker run -it --rm --name kafka-test apache/kafka:3.7.1 如果这样运行没有错误,则说明问题出在挂载上。 2. 如果用户需要挂载配置文件目录(如官网示例),那么需要确保挂载的宿主机目录中的配置文件存在,并且目录权限设置正确(对UID 1000可读)。但注意,挂载配置文件目录通常不需要写权限(除非kafka会修改配置文件?一般不会),所以可能不是配置文件目录的问题。 3. 如果用户还挂载了其他目录(比如日志目录`/opt/kafka/logs`,或者数据目录),那么需要设置这些目录的权限。 4. 如果用户没有挂载日志目录,但错误发生在`/opt/kafka/logs`,那么可能是容器启动脚本试图修改该目录权限失败。可以尝试在运行容器时覆盖启动命令,在启动前手动修改权限?但这样可能会破坏镜像的初衷。 由于用户使用的是自定义配置文件,我们假设用户只挂载了配置文件目录(如官网示例),那么日志目录并没有挂载,为什么会出现权限问题呢? 一个可能的原因是:用户挂载的配置文件目录中包含了`log.dirs`配置项,指向了另一个目录,而这个目录在容器内不存在,或者存在但没有权限?但错误提示的是`/opt/kafka/logs`,这是默认的日志目录。 另一种可能是:用户挂载的配置文件目录覆盖了容器内的某个重要文件?比如,容器内默认的日志目录配置就是`/opt/kafka/logs`,这个目录在镜像构建时已经创建并设置了权限(用户kafka)。如果用户没有挂载这个目录,那么它应该可写。 因此,我们可能需要用户提供完整的docker run命令,以便进一步分析。 但是,由于用户没有提供完整命令,我们只能给出一般性建议。 综合以上,我们给出一个具体的解决方案示例: 情况一:用户只挂载了配置文件目录(如官网示例),没有挂载日志目录。 那么,请确保配置文件目录在宿主机上存在,并且其中的配置文件对于容器内用户(UID1000)是可读的。但是,容器内的日志目录(/opt/kafka/logs)并没有挂载,所以应该是可写的。此时出现权限问题,可能是由于宿主机的SELinux设置?或者该目录在容器启动过程中被意外修改了权限?可以尝试在运行容器时添加`--privileged`(不推荐)或者使用`--security-opt`调整。 情况二:用户还挂载了日志目录(比如将宿主机的目录挂载到/opt/kafka/logs)。 那么,请确保宿主机上该目录的权限设置正确,例如: mkdir -p /path/on/host/logs chown -R 1000:1000 /path/on/host/logs 然后运行容器时挂载该目录: -v /path/on/host/logs:/opt/kafka/logs 情况三:用户使用了自定义的日志目录(通过配置文件指定),并且挂载了该自定义目录。 同样,需要确保宿主机上的自定义日志目录的权限为1000:1000。 另外,用户提到使用的是kraft模式(无zookeeper),那么可能还需要挂载数据目录(存储元数据),同样需要设置权限。 在kraft模式下,数据目录由`log.dirs`配置项指定(默认还是`/opt/kafka/logs`),所以如果用户使用默认配置,那么日志目录同时也是数据目录。 因此,我们建议用户: 1. 如果使用挂载,请确保挂载的所有目录(配置文件目录、日志目录、数据目录)在宿主机上预先创建,并设置正确的权限(chown 1000:1000)。 2. 如果用户不需要持久化数据,可以不挂载日志目录,让数据保存在容器内部(但容器删除后数据会丢失)。 总结命令步骤: 假设用户需要挂载配置文件目录(/mnt/shared/config)和日志目录(同时也是数据目录,/opt/kafka/logs)到宿主机: # 在宿主机上创建目录并设置权限 sudo mkdir -p /path/to/property/folder sudo mkdir -p /path/to/kafka/logs sudo chown -R 1000:1000 /path/to/kafka/logs # 注意:配置文件目录只需要可读,但为了避免其他问题,也可以设置1000:1000 # 注意:配置文件目录需要放入配置文件,比如server.properties等,这些文件需要可读,所以权限设置为644,所有者设为1000或root都可以,但目录至少要有执行权限(进入目录)和读权限。 # 运行容器 docker run -d \ --name kafka \ -p 9092:9092 \ -v /path/to/property/folder:/mnt/shared/config \ -v /path/to/kafka/logs:/opt/kafka/logs \ apache/kafka:3.7.1 注意:如果用户使用自定义配置文件,可能需要通过环境变量指定配置文件的位置,或者通过命令参数。具体参考kafka官方文档。 另外,在kraft模式下,还需要配置节点ID和角色等。但权限问题通过以上步骤应该可以解决。 如果问题仍然存在,请检查SELinux状态,并考虑暂时禁用SELinux(生产环境不推荐)或设置适当的SELinux策略。 针对SELinux,可以尝试在运行容器时添加Z选项重新标记卷: -v /path/to/kafka/logs:/opt/kafka/logs:Z 或者,在宿主机上更改目录的安全上下文: chcon -Rt svirt_sandbox_file_t /path/to/kafka/logs 但注意,这些操作需要根据宿主机的具体安全策略调整。 由于用户的问题描述有限,我们给出以上多种可能性和解决方案。希望用户根据实际情况选择。 最后,我们生成相关问题。 &lt;/think&gt; ### 解决 Docker 启动 Kafka 容器时 `chmod: /opt/kafka/logs: Operation not permitted` 错误 此错误通常由 **挂载目录的权限冲突** 引起。当容器内进程(默认以 `kafka` 用户,UID 1000 运行)尝试修改挂载的宿主机目录权限时,若宿主机目录权限不足或安全策略限制(如 SELinux),会导致操作失败。以下是完整解决方案: --- ### 解决方法 #### 1. **调整宿主机目录权限**(推荐) 在宿主机上创建挂载目录并赋予 `1000:1000` 权限(对应容器内 `kafka` 用户): ```bash # 创建日志目录并授权 sudo mkdir -p /path/on/host/logs sudo chown -R 1000:1000 /path/on/host/logs # 运行容器时挂载目录 docker run -d \ -v /path/on/host/logs:/opt/kafka/logs \ # 挂载日志目录 -v /path/to/config:/mnt/shared/config \ # 挂载配置文件目录 -p 9092:9092 \ apache/kafka:3.7.1 ``` #### 2. **添加 `--privileged` 参数**(临时方案) 允许容器获得宿主机 root 权限: ```bash docker run -d \ --privileged \ # 授予特权模式 -v /path/to/logs:/opt/kafka/logs \ -v /path/to/config:/mnt/shared/config \ -p 9092:9092 \ apache/kafka:3.7.1 ``` &gt; **注意**:此方式降低安全性,仅建议测试环境使用[^1]。 #### 3. **禁用 SELinux 安全策略**(如启用) 临时禁用: ```bash sudo setenforce 0 # 临时关闭 SELinux ``` 永久禁用(编辑 `/etc/selinux/config` 设置 `SELINUX=disabled`)。 --- ### 根本原因分析 1. **权限冲突** Kafka 容器默认以 UID 1000 用户运行,若挂载的宿主机目录不属于 `1000:1000` 或权限不足(如 `root:root`),会导致 `chmod` 失败。 2. **安全策略限制** SELinux/AppArmor 可能阻止容器进程修改挂载目录[^1]。 3. **Kraft 模式要求** Kafka 3.3.1+ 默认使用 Kraft 模式(无 ZooKeeper),日志目录需显式挂载并确保写入权限。 --- ### 完整操作示例 ```bash # 宿主机准备目录 sudo mkdir -p /data/kafka/{logs,config} sudo chown -R 1000:1000 /data/kafka/logs # 启动容器 docker run -d \ --name kafka \ -v /data/kafka/config:/mnt/shared/config \ # 自定义配置文件 -v /data/kafka/logs:/opt/kafka/logs \ # 挂载日志目录 -p 9092:9092 \ apache/kafka:3.7.1 ``` --- ### 验证是否解决 进入容器检查日志目录权限: ```bash docker exec -it kafka bash ls -ld /opt/kafka/logs # 应显示 &quot;kafka kafka&quot; ``` ---
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值