【问题标题】:docker-compose zookeeper kafka - ERROR cnxn.saslServer is null: cnxn object did not initialize its saslServer properlydocker-compose zookeeper kafka - 错误 cnxn.saslServer 为空:cnxn 对象未正确初始化其 saslServer
【发布时间】:2026-02-16 21:05:01
【问题描述】:

我正在尝试使用 docker-compose 来启动 zk/kafka。

docker-compose.yml

version: '2'
services:
  zookeeper-1:
    image: confluentinc/cp-zookeeper:6.1.4
    environment:
      ZOOKEEPER_SERVER_ID: 1
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
      ZOOKEEPER_INIT_LIMIT: 10
      ZOOKEEPER_SYNC_LIMIT: 5
      ZOOKEEPER_DATADIR_AUTOCREATE: "false"
      ZOOKEEPER_MAX_CLIENT_CNXNS: 60
      ZOOKEEPER_AUTOPURGE_SNAP_RETAIN_COUNT: 12
      ZOOKEEPER_AUTOPURGE_PURGE_INTERVAL: 168
      ZOOKEEPER_ADMIN_ENABLE_SERVER: "false"
      ZOOKEEPER_SERVER_1: zookeeper-1:12881:13881
      ZOOKEEPER_AUTH_PROVIDER_1: org.apache.zookeeper.server.auth.SASLAuthenticationProvider
      ZOOKEEPER_REQUIRE_CLIENT_AUTH_SCHEME: sasl
      ZOOKEEPER_JAAS_LOGIN_RENEW: 3600000
      ZOOKEEPER_SECURE_CLIENT_PORT: 12181
      ZOOKEEPER_AUTH_PROVIDER_X509: org.apache.zookeeper.server.auth.X509AuthenticationProvider
      ZOOKEEPER_SERVER_CNXN_FACTORY: org.apache.zookeeper.server.NettyServerCnxnFactory
      ZOOKEEPER_SSL_PROTOCOL: TLSv1.2      
      ZOOKEEPER_SSL_TRUSTSTORE_LOCATION: /etc/kafka/secrets/truststore.jks
      ZOOKEEPER_SSL_TRUSTSTORE_PASSWORD: password
      ZOOKEEPER_SSL_KEYSTORE_LOCATION: /etc/kafka/secrets/zookeeper.server1.keystore.jks
      ZOOKEEPER_SSL_KEYSTORE_PASSWORD: password
      ZOOKEEPER_SSL_CLIENT_AUTH: none

      KAFKA_OPTS: "-Djava.security.auth.login.config=/etc/kafka/secrets/zookeeper_jaas.conf"
    ports:
      - 12181:12181
    volumes:
      - /var/ssl:/etc/kafka/secrets

  kafka-1:
    image: confluentinc/cp-kafka:latest
    depends_on:
      - zookeeper-1
    ports:
      - 29092:9092
    volumes:
      - /var/ssl:/etc/kafka/secrets
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ADVERTISED_LISTENERS: SASL_SSL://kafka-1:9092
      KAFKA_NUM_PARTITIONS: 4
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 2
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 2
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 2
      KAFKA_AUTO_CREATE_TOPICS_ENABLE: "false"
      KAFKA_ZOOKEEPER_CONNECT: zookeeper-1:12181
      KAFKA_ZOOKEEPER_CLIENT_CNXN_SOCKET: org.apache.zookeeper.ClientCnxnSocketNetty
      KAFKA_ZOOKEEPER_SSL_CLIENT_ENABLE: "true"
      KAFKA_ZOOKEEPER_SSL_PROTOCOL: TLSv1.2
      KAFKA_ZOOKEEPER_SSL_TRUSTSTORE_LOCATION: /etc/kafka/secrets/truststore.jks
      KAFKA_ZOOKEEPER_SSL_TRUSTSTORE_PASSWORD: password
      KAFKA_ZOOKEEPER_SET_ACL: "false"
      KAFKA_SECURITY_INTER_BROKER_PROTOCOL: SASL_SSL
      KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL: PLAIN
      KAFKA_SASL_ENABLED_MECHANISMS: PLAIN
      KAFKA_SSL_CLIENT_AUTH: none
      KAFKA_SSL_KEYSTORE_FILENAME: kafka.server1.keystore.jks
      KAFKA_SSL_KEYSTORE_CREDENTIALS: keystore_credentials
      KAFKA_SSL_KEY_CREDENTIALS: keystore_credentials
      KAFKA_SSL_TRUSTSTORE_FILENAME: truststore.jks
      KAFKA_SSL_TRUSTSTORE_CREDENTIALS: keystore_credentials
      KAFKA_SSL_ENABLED_PROTOCOLS: TLSv1.2
      
      KAFKA_OPTS: "-Djava.security.auth.login.config=/etc/kafka/secrets/kafka_server_jaas.conf"

SSL/TLS

#!/usr/bin/env bash

export DIR=/var/ssl
export PASSWORD=password
export DNS=localhost

echo subjectAltName=DNS:$DNS,DNS:zookeeper-1,DNS:kafka-1 > openssl.cnf

openssl req -x509 -new -sha256 -newkey rsa:2048 -keyout CA.key -days 7300 -out CA.crt -subj "/CN=$DNS" -passout pass:$PASSWORD
keytool -keystore truststore.jks -alias CA -importcert -file CA.crt -storepass $PASSWORD -noprompt

openssl req -new -sha256 -newkey rsa:2048 -keyout zookeeper.server${instance}.key -subj "/CN=$DNS" -out zookeeper.server${instance}.csr -passout pass:$PASSWORD
openssl x509 -req -extfile openssl.cnf -in zookeeper.server${instance}.csr -CA CA.crt -CAkey CA.key -CAcreateserial -out zookeeper.server${instance}.crt -days 7300 -sha256 -passin pass:$PASSWORD
openssl pkcs12 -export -in zookeeper.server${instance}.crt -inkey zookeeper.server${instance}.key -out zookeeper.server${instance}.p12 -name zookeeper.server${instance} -CAfile CA.crt -caname CA -passin pass:$PASSWORD -passout pass:$PASSWORD
keytool -importkeystore -deststorepass $PASSWORD -destkeypass $PASSWORD -destkeystore zookeeper.server${instance}.keystore.jks -srckeystore zookeeper.server${instance}.p12 -srcstoretype pkcs12 -srcstorepass $PASSWORD -alias zookeeper.server${instance}
keytool -keystore zookeeper.server${instance}.keystore.jks -alias CA -importcert -file CA.crt -storepass $PASSWORD -noprompt

openssl req -new -sha256 -newkey rsa:2048 -keyout kafka.server${instance}.key -subj "/CN=$DNS" -out kafka.server${instance}.csr -passout pass:$PASSWORD
openssl x509 -req -extfile openssl.cnf -in kafka.server${instance}.csr -CA CA.crt -CAkey CA.key -CAcreateserial -out kafka.server${instance}.crt -days 7300 -sha256 -passin pass:$PASSWORD
openssl pkcs12 -export -in kafka.server${instance}.crt -inkey kafka.server${instance}.key -out kafka.server${instance}.p12 -name kafka.server${instance} -CAfile CA.crt -caname CA -passin pass:$PASSWORD -passout pass:$PASSWORD
keytool -importkeystore -deststorepass $PASSWORD -destkeypass $PASSWORD -destkeystore kafka.server${instance}.keystore.jks -srckeystore kafka.server${instance}.p12 -srcstoretype pkcs12 -srcstorepass $PASSWORD -alias kafka.server${instance}
keytool -keystore kafka.server${instance}.keystore.jks -alias CA -importcert -file CA.crt -storepass $PASSWORD -noprompt

echo -n password > /var/ssl/keystore_credentials

kafka_server_jaas.conf

KafkaServer {
    org.apache.kafka.common.security.plain.PlainLoginModule required
    username="kafka_broker_admin"
    password="password"
    user_kafka_broker_admin="password"
    user_zookeeper="password"
};

Client {
    org.apache.kafka.common.security.plain.PlainLoginModule required
    username="zookeeper"
    password="password";
};

zookeeper_jaas.conf

Server {
    org.apache.zookeeper.server.auth.DigestLoginModule required
    user_zookeeper="password";
};

命令

docker-compose up -d

错误

动物园管理员-1_1 | [2022-01-17 12:30:34,845] INFO 绑定到端口 0.0.0.0/0.0.0.0:2181 (org.apache.zookeeper.server.NettyServerCnxnFactory)
动物园管理员-1_1 | [2022-01-17 12:30:34,886] INFO 绑定到端口 2181 (org.apache.zookeeper.server.NettyServerCnxnFactory)
动物园管理员-1_1 | [2022-01-17 12:30:34,893] 信息 zookeeper.snapshotSizeFactor = 0.33 (org.apache.zookeeper.server.ZKDatabase)
动物园管理员-1_1 | [2022-01-17 12:30:34,894] 信息快照:0x0 到 /var/lib/zookeeper/data/version-2/snapshot.0 (org.apache.zookeeper.server.persistence.FileTxnSnapLog)
动物园管理员-1_1 | [2022-01-17 12:30:34,895] 信息快照:0x0 到 /var/lib/zookeeper/data/version-2/snapshot.0
(org.apache.zookeeper.server.persistence.FileTxnSnapLog) 动物园管理员-1_1 | [2022-01-17 12:30:34,901] 信息 PrepRequestProcessor (sid:0) 已启动,reconfigEnabled=false (org.apache.zookeeper.server.PrepRequestProcessor)
动物园管理员-1_1 | [2022-01-17 12:30:34,903] 信息 zookeeper.client.portUnification=false (org.apache.zookeeper.server.NettyServerCnxnFactory)
动物园管理员-1_1 | [2022-01-17 12:30:34,938] INFO 使用 org.apache.zookeeper.server.NettyServerCnxnFactory 作为服务器 连接工厂 (org.apache.zookeeper.server.ServerCnxnFactory)
动物园管理员-1_1 | [2022-01-17 12:30:34,938] INFO 绑定到端口 0.0.0.0/0.0.0.0:12181 (org.apache.zookeeper.server.NettyServerCnxnFactory)
动物园管理员-1_1 | [2022-01-17 12:30:34,940] INFO 绑定到端口 12181 (org.apache.zookeeper.server.NettyServerCnxnFactory)
动物园管理员-1_1 | [2022-01-17 12:30:34,941] 使用 checkIntervalMs=60000 maxPerMinute=10000 的信息 (org.apache.zookeeper.server.ContainerManager)
动物园管理员-1_1 | [2022-01-17 12:30:38,480] INFO 创建新的日志文件:log.1 (org.apache.zookeeper.server.persistence.FileTxnLog)
动物园管理员-1_1 | [2022-01-17 12:30:38,493] 错误 cnxn.saslServer 为空:cnxn 对象未正确初始化其 saslServer。 (org.apache.zookeeper.server.ZooKeeperServer)

我在配置什么或做错了什么?谢谢。

【问题讨论】:

  • 在 Docker 中运行 Kafka 不需要 SASL
  • 谢谢,我的主要目标是复制我的产品设置(不使用 Docker)。
  • 我不认为 JVMFLAGSSERVER_JVMFLAGS 对于 Zookeeper 传递 SASL 参数是正确的。你从哪里弄来的?见github.com/apache/kafka/blob/trunk/bin/…github.com/apache/kafka/blob/trunk/bin/kafka-run-class.sh#L242
  • 我有两个服务开始但一个堆栈跟踪,因为缺少kafka_server_jaas.conf。您可以通过编辑您的问题来分享它吗?
  • 感谢@OneCricketeer,为了安全起见,我已更新为KAFKA_OPTS。 @рüффп,我更新了请求的kafka_server_jaas.confzookeeper_jaas.conf

标签: apache-kafka docker-compose apache-zookeeper


【解决方案1】:

在明确了您的需求后,我发现了三个需要解决的问题:

  1. /etc/kafka/secrets/zookeeper.server1.keystore.jks 应该是 /etc/kafka/secrets/zookeeper.server.keystore.jks,因为 TLS/SSL 脚本会生成该名称。
  2. zookeeper 密钥库也是如此
  3. 启动时请求一个名为keystore_credentials 的额外文件。只需在里面使用password 创建它(你的 jks 密码)

我还有一个问题,但似乎更进一步你得到的错误:

io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: no cipher suites in common 

这似乎与您的 SSL 脚本更相关

【讨论】:

  • 谢谢,我已经这样做了。我在没有 TLS 和 SASL 的情况下运行没有问题。
  • 好的,那么你必须说出你放在 /var/ssl 目录中的内容(至少要告诉程序,不一定是你的秘密证书/信任库)
  • 好点,我已经更新了问题。
  • @jumping_monkey 我已经修改了我的答案,我似乎 SASL 正在工作,我遇到了另一个与 SSL 相关的错误。您能否检查您的密钥库名称,以及您身边的 keystore_credentials 是否正在解决您的问题?
  • 对于第 1 点和第 2 点,这不是问题,我在循环中使用 ${instance} 填充数字。对于第 3 点,是的,我在 /var/ssl 中有 keystore_credentials 文件。我更新了问题。相同的 SSL/TLS 脚本在没有 Docker 的情况下运行良好,并且在 Zk/Kafka 上运行良好。
最近更新 更多