Docker环境下Kafka SSL配置失败,SSL握手失败求助
我看了你在Docker中配置Kafka SSL的整个流程,明文连接正常但SSL握手失败,结合你的配置和错误日志,帮你梳理几个关键的遗漏点:
1. 客户端信任库文件名不匹配
你生成的客户端信任库是client.truststore.jks(脚本Step2里的命令),但客户端配置文件/opt/kafka/client-ssl.properties里写的是:
ssl.truststore.location=/tmp/ssl/1/kafka.client.truststore.jks
这里文件名多了前缀kafka.,Kafka客户端找不到正确的信任库文件,直接导致SSL握手失败。把路径改成/tmp/ssl/1/client.truststore.jks就能解决这个明显的路径错误。
2. Docker容器SSL端口未暴露与Advertised Listeners配置缺失
你的docker-compose.yml里只映射了明文的9092端口,也没有配置SSL端口的Advertised Listeners:
- 首先要在Kafka服务的
ports里加上SSL端口映射:- "9093:9093" - 然后在
environment中替换原有的KAFKA_ADVERTISED_HOST_NAME和KAFKA_ADVERTISED_PORT,改成完整的Advertised Listeners:- KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9092,SSL://127.0.0.1:9093
Kafka需要把SSL端口的地址告知客户端,否则客户端连接9093时会出现握手异常。
3. 确认Kafka服务端SSL配置的路径与密码
你把证书放在了本地/tmp/ssl/1/,通过挂载映射到容器的/tmp/ssl/,所以容器内的证书路径应该是/tmp/ssl/1/server.keystore.jks和/tmp/ssl/1/server.truststore.jks,要确保server.properties里的配置完全匹配:
listeners=PLAINTEXT://:9092,SSL://:9093 ssl.keystore.location=/tmp/ssl/1/server.keystore.jks ssl.keystore.password=test1234 # 要和你生成证书时设置的密码一致 ssl.truststore.location=/tmp/ssl/1/server.truststore.jks ssl.truststore.password=test1234 ssl.enabled.protocols=TLSv1.2,TLSv1.1,TLSv1 ssl.client.auth=required # 根据你的需求调整,可选required/requested/none
如果密码不匹配或者路径错误,服务端无法加载证书,自然会握手失败。
4. 证书Common Name(CN)的匹配验证
生成服务端证书时(Step1的keytool -genkey命令),你设置的Common Name(CN)必须是localhost,因为客户端连接的是localhost:9093,Kafka默认会验证证书CN和连接的主机名是否一致。如果生成证书时CN不是localhost,可以临时添加参数跳过验证(生产环境不建议):
在server.properties里加上:
ssl.endpoint.identification.algorithm=
5. 容器内证书文件的权限问题
进入Kafka容器,检查证书文件的权限:
docker exec -it <kafka-container-id> ls -l /tmp/ssl/1/
如果Kafka用户(通常是kafka)没有读取证书文件的权限,会导致加载失败。可以在本地给证书文件添加可读权限:
chmod +r /tmp/ssl/1/*.jks
修正后的关键配置示例
调整后的docker-compose.yml片段
services: kafka: image: wurstmeister/kafka ports: - "9092:9092" - "9093:9093" # 添加SSL端口映射 environment: - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9092,SSL://127.0.0.1:9093 - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 # 可以直接在environment里设置SSL参数,不用单独修改server.properties - KAFKA_LISTENERS=PLAINTEXT://:9092,SSL://:9093 - KAFKA_SSL_KEYSTORE_LOCATION=/tmp/ssl/1/server.keystore.jks - KAFKA_SSL_KEYSTORE_PASSWORD=test1234 - KAFKA_SSL_TRUSTSTORE_LOCATION=/tmp/ssl/1/server.truststore.jks - KAFKA_SSL_TRUSTSTORE_PASSWORD=test1234 volumes: - "/tmp/ssl/:/tmp/ssl/" depends_on: - zookeeper
修正后的客户端配置client-ssl.properties
security.protocol=SSL ssl.truststore.location=/tmp/ssl/1/client.truststore.jks ssl.truststore.password=test1234
先从文件名错误和端口配置这两个最明显的问题入手排查,应该能解决SSL握手失败的问题。
内容的提问来源于stack exchange,提问作者jvmsneue

