<think>我们使用wurstmeister/kafka镜像部署Kafka,并需要配置SASL/SCRAM认证(使用SCRAM-SHA-512机制)和SASL_PLAINTEXT安全协议。
主要步骤:
1. 创建Kafka所需的ZooKeeper和Kafka容器,并配置环境变量以启用SASL认证。
2. 在Kafka容器内配置JAAS文件(用于定义登录模块和用户凭证)。
3. 配置Kafka的server.properties文件,设置SASL相关参数。
4. 创建SCRAM凭证(用户和密码)并存储在ZooKeeper中。
5. 设置环境变量,确保Kafka启动时加载JAAS配置。
注意:由于我们使用docker run,我们需要通过环境变量和卷挂载的方式传递配置。
具体步骤:
步骤1:配置ZooKeeper容器
我们首先启动一个ZooKeeper容器(使用wurstmeister/zookeeper镜像)。
步骤2:配置Kafka容器
在启动Kafka容器时,我们需要设置多个环境变量来配置SASL,并且需要提供一个JAAS配置文件。
我们需要为Kafka broker配置一个JAAS文件,例如kafka_server_jaas.conf,内容如下:
```
KafkaServer {
org.apache.kafka.common.security.scram.ScramLoginModule required
username="admin"
password="admin"
user_admin="admin";
};
```
这个文件定义了一个名为admin的用户,密码为admin,并且该用户也是broker之间通信的用户(这里为了简单,broker间通信也使用同一个用户,生产环境建议区分)。
步骤3:配置Kafka的server.properties
我们可以通过环境变量来覆盖server.properties的配置。需要设置以下关键配置:
- KAFKA_LISTENERS: SASL_PLAINTEXT://0.0.0.0:9092
- KAFKA_ADVERTISED_LISTENERS: SASL_PLAINTEXT://<宿主机的IP>:9092
- KAFKA_SECURITY_INTER_BROKER_PROTOCOL: SASL_PLAINTEXT
- KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL: SCRAM-SHA-512
- KAFKA_SASL_ENABLED_MECHANISMS: SCRAM-SHA-512
- KAFKA_AUTHORIZER_CLASS_NAME: kafka.security.authorizer.AclAuthorizer(如果需要ACL)
- KAFKA_SUPER_USERS: User:admin
- KAFKA_OPTS: 用于传递JAAS配置的位置,例如:-Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf
另外,我们还需要设置环境变量来创建SCRAM用户(admin)?但是,在wurstmeister/kafka镜像中,我们可以通过脚本在启动时创建用户。然而,该镜像并没有直接提供这样的脚本,所以我们需要在容器启动后执行命令来创建用户。
因此,我们可以这样操作:
- 启动Kafka容器,挂载JAAS配置文件到容器内的某个路径(例如:/etc/kafka/kafka_server_jaas.conf)
- 设置KAFKA_OPTS环境变量指向该JAAS文件
- 通过环境变量设置server.properties的配置(如上所述)
- 在Kafka启动后,进入容器执行kafka-configs命令创建SCRAM用户(或者通过启动脚本在后台执行)
但是,由于docker run是单次执行,我们需要编写一个启动脚本在容器内执行,包括启动Kafka和创建用户(注意:需要等待ZooKeeper和Kafka启动完成)。
考虑到复杂性,我们可以分两步:
第一步:启动Kafka容器,但不启动Kafka服务,只保持运行(例如使用tail -f /dev/null),然后进入容器执行命令。
第二步:在容器内先启动ZooKeeper和Kafka,然后执行创建用户的命令。
然而,wurstmeister/kafka镜像的入口脚本已经会启动Kafka,所以我们不能直接覆盖。因此,我们可以采用在容器启动后执行命令的方式。
另一种方法:使用docker exec在容器启动后执行创建用户的命令。
但是,为了自动化,我们可以编写一个自定义的启动脚本,替换原来的启动脚本。这里我们选择在容器启动后通过docker exec执行命令。
具体步骤:
1. 启动ZooKeeper容器:
docker run -d --name zookeeper -p 2181:2181 -t wurstmeister/zookeeper
2. 准备一个JAAS文件(kafka_server_jaas.conf),内容如上。
3. 启动Kafka容器,挂载JAAS文件,并设置环境变量:
docker run -d --name kafka \
-p 9092:9092 \
-e KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 \
-e KAFKA_LISTENERS=SASL_PLAINTEXT://0.0.0.0:9092 \
-e KAFKA_ADVERTISED_LISTENERS=SASL_PLAINTEXT://<host_ip>:9092 \
-e KAFKA_SECURITY_INTER_BROKER_PROTOCOL=SASL_PLAINTEXT \
-e KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL=SCRAM-SHA-512 \
-e KAFKA_SASL_ENABLED_MECHANISMS=SCRAM-SHA-512 \
-e KAFKA_OPTS="-Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf" \
-e KAFKA_AUTHORIZER_CLASS_NAME=kafka.security.authorizer.AclAuthorizer \
-e KAFKA_ALLOW_EVERYONE_IF_NO_ACL_FOUND=false \
-e KAFKA_SUPER_USERS=User:admin \
-v /path/to/kafka_server_jaas.conf:/etc/kafka/kafka_server_jaas.conf \
--link zookeeper \
wurstmeister/kafka
注意:<host_ip>需要替换为宿主机的IP地址。
4. 创建SCRAM用户(admin):
由于在JAAS文件中我们已经定义了admin用户,但是Kafka的SCRAM用户需要存储在ZooKeeper中,所以我们还需要在Kafka容器中执行命令来创建用户。
进入Kafka容器:
docker exec -it kafka bash
在容器内执行:
# 进入Kafka安装目录(通常为/opt/kafka)
cd /opt/kafka/bin
# 创建SCRAM用户(admin),密码为admin(与JAAS文件中的密码一致)
./kafka-configs.sh --zookeeper zookeeper:2181 --alter --add-config 'SCRAM-SHA-512=[password=admin]' --entity-type users --entity-name admin
注意:这里我们使用SCRAM-SHA-512,与之前配置的机制一致。
5. 验证:我们可以使用kafka-console-producer和kafka-console-consumer进行验证,但需要配置客户端的JAAS文件。
但是,上述步骤中,我们在JAAS文件中已经定义了admin用户,并且创建了SCRAM凭证,这样Kafka broker就可以用这个用户进行认证了。
然而,我们还需要注意:在JAAS文件中,我们配置了KafkaServer部分的用户,这个用户用于broker之间的通信(如果只有一个broker,则不需要)。同时,我们创建的用户admin是作为客户端连接时使用的用户(以及超级用户)。
另外,我们配置了超级用户(super.users)为admin,这样admin用户就有所有权限。
但是,我们还没有设置ACL,所以需要为每个topic设置访问控制。不过,根据配置`allow.everyone.if.no.acl.found=false`,如果没有设置ACL,则不允许访问。因此,我们需要为每个topic设置ACL,或者为客户端用户授权。
由于问题只要求设置用户名密码,所以我们先完成认证部分。
总结docker run命令:
假设JAAS文件在宿主机的/tmp/kafka_server_jaas.conf,宿主机IP为192.168.1.100,则:
启动ZooKeeper:
docker run -d --name zookeeper -p 2181:2181 wurstmeister/zookeeper
启动Kafka:
docker run -d --name kafka \
-p 9092:9092 \
-e KAFKA_ZOOKEEPER_CONNECT=192.168.1.100:2181 \
-e KAFKA_LISTENERS=SASL_PLAINTEXT://0.0.0.0:9092 \
-e KAFKA_ADVERTISED_LISTENERS=SASL_PLAINTEXT://192.168.1.100:9092 \
-e KAFKA_SECURITY_INTER_BROKER_PROTOCOL=SASL_PLAINTEXT \
-e KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL=SCRAM-SHA-512 \
-e KAFKA_SASL_ENABLED_MECHANISMS=SCRAM-SHA-512 \
-e KAFKA_OPTS="-Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf" \
-e KAFKA_AUTHORIZER_CLASS_NAME=kafka.security.auth.SimpleAclAuthorizer \
-e KAFKA_ALLOW_EVERYONE_IF_NO_ACL_FOUND=false \
-e KAFKA_SUPER_USERS=User:admin \
-v /tmp/kafka_server_jaas.conf:/etc/kafka/kafka_server_jaas.conf \
--link zookeeper \
wurstmeister/kafka
注意:在较新的Kafka版本中,AclAuthorizer的类名已经改为`kafka.security.authorizer.AclAuthorizer`,但wurstmeister/kafka镜像可能使用的是较旧的版本(旧版本使用`kafka.security.auth.SimpleAclAuthorizer`)。请根据镜像中的Kafka版本确定。
然后,执行创建用户的命令:
docker exec kafka /opt/kafka/bin/kafka-configs.sh --zookeeper 192.168.1.100:2181 --alter --add-config 'SCRAM-SHA-512=[password=admin]' --entity-type users --entity-name admin
这样,Kafka broker就可以使用SCRAM-SHA-512认证了。
客户端连接时,需要配置:
security.protocol=SASL_PLAINTEXT
sasl.mechanism=SCRAM-SHA-512
以及JAAS配置(包含用户名和密码)
注意:wurstmeister/kafka镜像的Kafka版本可能影响配置的类名和可用性,请根据实际版本调整。
由于wurstmeister/kafka镜像的Kafka版本可能较旧,可能不支持SCRAM-SHA-512,所以请确保使用的镜像版本支持。
如果遇到问题,可以查看Kafka容器的日志:docker logs kafka
另外,如果Kafka启动失败,可能是因为环境变量配置错误,可以进入容器检查/etc/kafka/server.properties文件,看配置是否生效。
由于在docker run中配置较多,建议使用docker-compose来管理。
但是,用户要求使用docker run,所以我们提供上述命令。
注意:在启动Kafka容器时,我们使用了--link zookeeper,这要求ZooKeeper容器已经启动并且名为zookeeper。如果ZooKeeper不在同一台机器或者不同网络,需要调整连接字符串。
最后,我们提供完整的步骤和命令。
</think>
### 在 Docker 中为 wurstmeister/kafka 配置 SASL/SCRAM 认证
以下是使用 `docker run` 部署 Kafka 并启用 SCRAM-SHA-512 认证的完整步骤:
---
#### **1. 创建 JAAS 配置文件**
创建 `kafka_server_jaas.conf` 文件,内容如下:
```properties
KafkaServer {
org.apache.kafka.common.security.scram.ScramLoginModule required
username="admin"
password="admin"
user_admin="admin";
};
```
---
#### **2. 启动 ZooKeeper 容器**
```bash
docker run -d --name zookeeper \
-p 2181:2181 \
-t wurstmeister/zookeeper
```
---
#### **3. 启动 Kafka 容器(关键配置)**
```bash
docker run -d --name kafka \
-p 9092:9092 \
-e KAFKA_ZOOKEEPER_CONNECT=<宿主机IP>:2181 \
-e KAFKA_LISTENERS=SASL_PLAINTEXT://0.0.0.0:9092 \
-e KAFKA_ADVERTISED_LISTENERS=SASL_PLAINTEXT://<宿主机IP>:9092 \
-e KAFKA_SECURITY_INTER_BROKER_PROTOCOL=SASL_PLAINTEXT \
-e KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL=SCRAM-SHA-512 \
-e KAFKA_SASL_ENABLED_MECHANISMS=SCRAM-SHA-512 \
-e KAFKA_OPTS="-Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf" \
-e KAFKA_AUTHORIZER_CLASS_NAME=kafka.security.authorizer.AclAuthorizer \
-e KAFKA_ALLOW_EVERYONE_IF_NO_ACL_FOUND=false \
-e KAFKA_SUPER_USERS=User:admin \
-v $(pwd)/kafka_server_jaas.conf:/etc/kafka/kafka_server_jaas.conf \
--link zookeeper \
wurstmeister/kafka
```
**参数说明**:
- `<宿主机IP>`:替换为实际宿主机 IP(可通过 `hostname -I` 获取)
- `KAFKA_SASL_ENABLED_MECHANISMS=SCRAM-SHA-512`:启用 SCRAM-SHA-512 认证
- `KAFKA_OPTS`:加载 JAAS 配置文件
- `KAFKA_SUPER_USERS=User:admin`:设置管理员用户
---
#### **4. 创建 SCRAM 用户凭证**
在 Kafka 容器内执行(替换 `your-password` 为实际密码):
```bash
docker exec kafka /opt/kafka/bin/kafka-configs.sh \
--zookeeper <宿主机IP>:2181 \
--alter \
--add-config 'SCRAM-SHA-512=[password=your-password]' \
--entity-type users \
--entity-name admin
```
---
#### **5. 验证配置**
使用控制台生产者测试连接:
```bash
docker exec -it kafka /opt/kafka/bin/kafka-console-producer.sh \
--broker-list localhost:9092 \
--topic test \
--producer.config /opt/kafka/config/producer.properties
```
在 `producer.properties` 中添加:
```properties
security.protocol=SASL_PLAINTEXT
sasl.mechanism=SCRAM-SHA-512
sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required username="admin" password="your-password";
```
---
### 关键配置解释
| **配置项** | **值** | **作用** |
|------------|--------|----------|
| `sasl.enabled.mechanisms` | `SCRAM-SHA-512` | 启用 SCRAM-SHA-512 认证 |
| `security.inter.broker.protocol` | `SASL_PLAINTEXT` | Broker 间通信协议 |
| `sasl.mechanism.inter.broker.protocol` | `SCRAM-SHA-512` | Broker 间认证机制 |
| `allow.everyone.if.no.acl.found` | `false` | 强制 ACL 验证 |
| `super.users` | `User:admin` | 管理员权限用户 |
[^1]
---
### 相关问题
1. 如何为 Kafka 生产者/消费者配置 SCRAM 认证?
2. 使用 Docker Compose 部署 SASL 认证的 Kafka 集群的最佳实践是什么?
3. SCRAM-SHA-256 和 SCRAM-SHA-512 在安全性上有何区别?
4. 如何通过 Kafka ACL 控制主题访问权限?