我正在运行一些Java 8 Kafka应用程序,其中一些是Kafka流,其他则是普通的生产者/消费者。
对于它们每个都没有功能性问题,它们在大多数情况下都可以正常运行。
但是,对于他们每个人,我都经常发生SaslAuthenticationException的情况。由于它们每两周左右发生一次,因此我不确定如何复制/推断出根本原因:
错误:
Failed to create channel due to
org.apache.kafka.common.errors.SaslAuthenticationException: Failed to configure SaslClientAuthenticator
Caused by: org.apache.kafka.common.KafkaException: Principal could not be determined from Subject, this may be a transient failure due to Kerberos re-login
堆栈跟踪:
Failed to create channel due to
org.apache.kafka.common.errors.SaslAuthenticationException: Failed to configure SaslClientAuthenticator
Caused by: org.apache.kafka.common.KafkaException: Principal could not be determined from Subject, this may be a transient failure due to Kerberos re-login
at org.apache.kafka.common.security.authenticator.SaslClientAuthenticator.firstPrincipal(SaslClientAuthenticator.java:441) ~[kafka-clients-2.0.1.jar!/:na]
at org.apache.kafka.common.security.authenticator.SaslClientAuthenticator.<init>(SaslClientAuthenticator.java:135) ~[kafka-clients-2.0.1.jar!/:na]
at org.apache.kafka.common.network.SaslChannelBuilder.buildClientAuthenticator(SaslChannelBuilder.java:244) ~[kafka-clients-2.0.1.jar!/:na]
at org.apache.kafka.common.network.SaslChannelBuilder.buildChannel(SaslChannelBuilder.java:194) ~[kafka-clients-2.0.1.jar!/:na]
at org.apache.kafka.common.network.Selector.buildAndAttachKafkaChannel(Selector.java:289) [kafka-clients-2.0.1.jar!/:na]
at org.apache.kafka.common.network.Selector.registerChannel(Selector.java:280) [kafka-clients-2.0.1.jar!/:na]
at org.apache.kafka.common.network.Selector.connect(Selector.java:215) [kafka-clients-2.0.1.jar!/:na]
at org.apache.kafka.clients.NetworkClient.initiateConnect(NetworkClient.java:864) [kafka-clients-2.0.1.jar!/:na]
at org.apache.kafka.clients.NetworkClient.access$700(NetworkClient.java:64) [kafka-clients-2.0.1.jar!/:na]
at org.apache.kafka.clients.NetworkClient$DefaultMetadataUpdater.maybeUpdate(NetworkClient.java:1035) [kafka-clients-2.0.1.jar!/:na]
at org.apache.kafka.clients.NetworkClient$DefaultMetadataUpdater.maybeUpdate(NetworkClient.java:920) [kafka-clients-2.0.1.jar!/:na]
at org.apache.kafka.clients.NetworkClient.poll(NetworkClient.java:508) [kafka-clients-2.0.1.jar!/:na]
这就是我向Kafka提供JAAS Kerberos身份验证的方式(在我的配置文件中,我提供了诸如kdc,realm,keytab,principal之类的信息):
@Value("${kafka.sasl.kerberos.kdc}")
private String kdc;
@Value("${kafka.sasl.kerberos.realm}")
private String realm;
@Value("${kafka.sasl.kerberos.keytab}")
private Resource keytab;
@Value("${kafka.sasl.kerberos.principal}")
private String principal;
@Bean
public InMemoryConfiguration kafkaOpts() throws IOException {
System.setProperty("java.security.krb5.kdc", kdc);
System.setProperty("java.security.krb5.realm", realm);
Map<String, Object> options = new HashMap<>();
options.put("keyTab", copyResourceToTempFile(keytab, ".keytab").toString());
options.put("principal", principal);
options.put("useKeyTab","true");
options.put("storeKey","true");
AppConfigurationEntry kafkaClientConfig = new AppConfigurationEntry(
"com.sun.security.auth.module.Krb5LoginModule", LoginModuleControlFlag.REQUIRED, options);
Map<String, AppConfigurationEntry[]> jaasConfigEntries = new HashMap<>();
jaasConfigEntries.put("KafkaClient", new AppConfigurationEntry[] {kafkaClientConfig});
InMemoryConfiguration jaasConfig = new InMemoryConfiguration(jaasConfigEntries);
javax.security.auth.login.Configuration.setConfiguration(jaasConfig);
return jaasConfig;
}
public static Path copyResourceToTempFile(Resource resource, String extension) {
try (InputStream in = resource.getInputStream()) {
Path tempFile = Files.createTempFile("spring-boot-", extension);
Files.copy(in, tempFile, StandardCopyOption.REPLACE_EXISTING);
return tempFile;
} catch (IOException e) {
log.error("Error creating resource to file",e);
return null;
}
}
答案 0 :(得分:0)
我们也面临同样的问题。与kafka连接后,突然我们失去了连接,应用程序重试登录,但失败。 但是我们使用以下配置更新jaas auth配置文件:
com.sun.security.auth.module.Krb5LoginModule required useTicketCache=true;
对我来说这是完美的工作。