Strimzi Kafka自定义证书配置故障:AKS内部网络连接失败
我尝试为Strimzi Kafka监听器配置自定义证书,在Azure Kubernetes Service(AKS)私有虚拟网络内暴露监听器,操作步骤如下:
- 用内部CA生成自定义证书及私钥,创建对应的Kubernetes Secret:
kubectl create secret generic kafka-tls --from-literal=listener.cer=$cert --from-literal=listener.key=$skey -n kafka
- Kafka监听器配置:
listeners: - name: external port: 9094 type: loadbalancer tls: true authentication: type: tls #Listener TLS config configuration: brokerCertChainAndKey: secretName: kafka-tls certificate: listener.cer key: listener.key bootstrap: loadBalancerIP: 10.67.249.253 annotations: service.beta.kubernetes.io/azure-load-balancer-internal: "true" brokers: - broker: 0 loadBalancerIP: 10.67.249.251 annotations: service.beta.kubernetes.io/azure-load-balancer-internal: "true" - broker: 1 loadBalancerIP: 10.67.249.252 annotations: service.beta.kubernetes.io/azure-load-balancer-internal: "true" - broker: 2 loadBalancerIP: 10.67.249.250 annotations: service.beta.kubernetes.io/azure-load-balancer-internal: "true" authorization: type: simple
- 证书SAN字段包含以下记录:
*.kafka-datalake-prod-kafka-brokers *.kafka-datalake-prod-kafka-brokers.kafka.svc kafka-datalake-prod-kafka-bootstrap kafka-datalake-prod-kafka-bootstrap.kafka.svc kafka-datalake-prod-kafka-external-bootstrap kafka-datalake-prod-kafka-external-bootstrap.kafka.svc kafka-datalake-prod-azure.custom.domain
CN=kafka-datalake-produkty-prod-azure.custom.domain
已在自定义DNS中创建A记录:
kafka-datalake-produkty-prod-azure.custom.domain指向10.67.249.253创建KafkaUser对象:
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaUser metadata: name: customuser namespace: kafka labels: strimzi.io/cluster: kafka-datalake-prod spec: authentication: type: tls authorization: type: simple acls: - resource: type: topic name: notify.somecustomapp.prod.topic_name patternType: literal operations: - Create - Describe - Write # host: "*"
- 从AKS集群获取证书文件用于客户端连接:
kubectl get secret kafka-datalake-prod-cluster-ca-cert -n kafka -o jsonpath='{.data.ca\.crt}' | base64 -d > broker.crt kubectl get secret customuser -n kafka -o jsonpath='{.data.user\.key}' | base64 -d > customuser.key kubectl get secret customuser -n kafka -o jsonpath='{.data.user\.crt}' | base64 -d > customuser.crt
使用上述文件连接生产者发送消息时失败,报错:
INFO:kafka.conn:<BrokerConnection node_id=bootstrap-0 host=10.67.249.253:9094 <connecting> [IPv4 ('10.67.249.253', 9094)]>: connecting to 10.67.249.253:9094 [('10.67.249.253', 9094) IPv4] INFO:kafka.conn:Probing node bootstrap-0 broker version INFO:kafka.conn:<BrokerConnection node_id=bootstrap-0 host=10.67.249.253:9094 <handshake> [IPv4 ('10.67.249.253', 9094)]>: Loading SSL CA from certs/prod/broker.crt INFO:kafka.conn:<BrokerConnection node_id=bootstrap-0 host=10.67.249.253:9094 <handshake> [IPv4 ('10.67.249.253', 9094)]>: Loading SSL Cert from certs/prod/customuser.crt INFO:kafka.conn:<BrokerConnection node_id=bootstrap-0 host=10.67.249.253:9094 <handshake> [IPv4 ('10.67.249.253', 9094)]>: Loading SSL Key from certs/prod/customuser.key [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)
此前使用Strimzi集群生成的默认证书时连接完全正常,请问哪里配置错误?
核心问题
SSL验证失败的本质是两个关键配置缺失:
- 客户端信任链不匹配:你当前使用的
broker.crt是Strimzi默认集群CA的证书,但Kafka监听器用的是内部CA签发的自定义证书,客户端无法通过默认CA验证自定义证书的合法性。 - 证书SAN未包含连接IP:客户端用
10.67.249.253这个IP连接,但证书SAN字段里没有该IP,即使修复信任链,后续仍会出现主机名不匹配的错误。
具体修复步骤
1. 替换客户端信任的CA证书
客户端需要信任签发Kafka监听器证书的内部CA根证书,而非Strimzi默认CA:
- 将你的内部CA根证书导出为文件(如
internal-ca.crt),替换之前的broker.crt,客户端连接时指定这个CA证书。
2. 补全证书SAN字段
重新生成自定义证书,在SAN中添加以下内容:
IP:10.67.249.253(bootstrap服务IP)IP:10.67.249.251、IP:10.67.249.252、IP:10.67.249.250(各broker节点IP)- 或者客户端改用已在SAN中的自定义域名
kafka-datalake-produkty-prod-azure.custom.domain:9094连接,这是更规范的做法。
3. 确保证书链完整性
检查kafka-tls Secret中的listener.cer是否为完整证书链:
- 如果自定义证书由中间CA签发,需将中间CA证书与服务器证书拼接(服务器证书在前,中间CA在后)作为
listener.cer内容,否则Kafka返回的证书链不完整,客户端无法追溯到根CA。
4. 调整客户端连接配置
若改用自定义域名连接,需将客户端的bootstrap server地址改为kafka-datalake-produkty-prod-azure.custom.domain:9094,确保客户端能正常解析该域名(已配置DNS A记录,无需额外操作)。
内容的提问来源于stack exchange,提问作者Krzysztof

