如何让Kafka集群同时兼容新旧CA证书,实现无停机客户端升级?
让Kafka同时兼容新旧证书/CA的解决方案
1. 合并新旧证书到同一密钥库
Kafka的密钥库(JKS或PKCS12)支持存储多个密钥条目,你需要把旧证书和新证书都保存在同一个密钥库中,这样代理就能同时用它们处理SSL连接。
- 如果用JKS格式:
- 导出旧密钥条目到新的合并密钥库:
keytool -exportkeystore -srckeystore old_keystore.jks -destkeystore combined_keystore.jks -srcalias old_alias -destalias old_alias - 把新密钥条目导入合并后的密钥库:
keytool -importkeystore -srckeystore new_keystore.jks -destkeystore combined_keystore.jks -srcalias new_alias -destalias new_alias - 验证条目是否都存在:
keytool -list -v -keystore combined_keystore.jks
- 导出旧密钥条目到新的合并密钥库:
- 若是PKCS12格式,只需在命令中加上
-storetype PKCS12参数即可。
2. 把新旧CA都加入信任库
代理的信任库需要同时信任旧CA和新CA,这样不管客户端用旧CA还是新CA签发的证书,都能通过验证。
- 导入旧CA证书:
keytool -importcert -file old_ca.crt -keystore combined_truststore.jks -alias old_ca - 导入新CA证书到同一个信任库:
keytool -importcert -file new_ca.crt -keystore combined_truststore.jks -alias new_ca - 验证CA是否都在库中:
keytool -list -v -keystore combined_truststore.jks
3. 调整Kafka代理的SSL配置
修改server.properties中的SSL相关配置,确保代理能加载多证书并信任新旧CA:
# 密钥库路径和密码 ssl.keystore.location=/path/to/combined_keystore.jks ssl.keystore.password=你的密钥库密码 ssl.key.password=你的密钥密码(如果和密钥库密码不同的话) # 信任库路径和密码 ssl.truststore.location=/path/to/combined_truststore.jks ssl.truststore.password=你的信任库密码 # 启用兼容的TLS协议,覆盖新旧客户端 ssl.enabled.protocols=TLSv1.2,TLSv1.3 # 保留默认的密钥管理器算法,确保支持多证书选择 ssl.keymanager.algorithm=SunX509
Kafka在TLS握手时会自动根据客户端的信任链匹配合适的证书,不用额外配置选择逻辑。
4. 验证兼容性
- 用旧客户端(配置旧CA信任链)测试生产/消费,确认正常。
- 用新客户端(配置新CA信任链)测试,同样确认正常。
- 用OpenSSL命令验证:
# 测试旧证书兼容 openssl s_client -connect kafka-broker:9093 -CAfile old_ca.crt # 测试新证书兼容 openssl s_client -connect kafka-broker:9093 -CAfile new_ca.crt
两次测试都应该显示连接成功,证书验证通过。
5. 逐步迁移客户端
确认代理同时支持新旧连接后,就可以分批升级客户端:
- 每次选一部分客户端,把它们的信任链换成新CA,同时更新客户端的证书(如果是双向认证的话)。
- 所有客户端升级完成后,再从代理的密钥库和信任库中删除旧证书和旧CA,最后恢复OpenSSL的SECLEVEL到默认值。
之前操作问题的说明
- 替换证书后仍用旧证书:是因为密钥库中旧条目排在前面,Kafka默认选第一个有效条目,合并后两个条目都存在,就能自动适配。
- 重命名密钥导致旧客户端被拒:是因为你只保留了新证书,旧客户端的信任链无法验证新证书,必须同时保留新旧证书和CA才行。
内容的提问来源于stack exchange,提问作者Federico Fissore
相关产品推荐
相关产品推荐

