Kafka-Kerberos票据刷新问题

        线上kafka使用了 kerberos 认证,每隔24小时,票据过期,无法自动续期,出现消息发送失败问题。

        从日志可以发现会有如下报错:

2023-09-14 17:48:47,144 [kafka-kerberos-refresh-thread-kafka/hdp-1@HADOOP.COM] [] WARN  [o.a.kafka.common.security.kerberos.KerberosLogin] KerberosLogin.java:216 - [Principal=kafka/hdp-1@HADOOP.COM]: Error when trying to renew with TicketCache, but will retry 
java.io.IOException: Cannot run program "/usr/bin/kinit": CreateProcess error=2, 系统找不到指定的文件。
	at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1128)
	at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1071)
	at org.apache.kafka.common.utils.Shell.runCommand(Shell.java:85)
	at org.apache.kafka.common.utils.Shell.run(Shell.java:76)
	at org.apache.kafka.common.utils.Shell$ShellCommandExecutor.execute(Shell.java:204)
	at org.apache.kafka.common.utils.Shell.execCommand(Shell.java:268)
	at org.apache.kafka.common.utils.Shell.execCommand(Shell.java:255)
	at org.apache.kafka.common.security.kerberos.KerberosLogin.lambda$login$0(KerberosLogin.java:212)
	at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.io.IOException: CreateProcess error=2, 系统找不到指定的文件。
	at java.base/java.lang.ProcessImpl.create(Native Method)
	at java.base/java.lang.ProcessImpl.<init>(ProcessImpl.java:492)
	at java.base/java.lang.ProcessImpl.start(ProcessImpl.java:153)
	at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1107)
	... 8 common frames omitted

        由于线上系统日志输出比较多,也并没有对warn级别日志做单独的过滤,所以最初并没有发现这个提示。从报错信息看,相关业务逻辑是在 KerberosLogin 类中。

        其实每次启动项目(springboot+kakfa),KerberosLogin 会初始化 kerberos 认证过程,如下图:

yml文件相关配置:

spring:
  application:
    name: kerberos
  kafka:
    consumer:
      bootstrap-servers: hdp-1:6667,hdp-2:6667,hdp-3:6667
      group-id: kafka-example
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      enable-auto-commit: true
      auto-commit-interval: 1000
      auto-offset-reset: earliest
    producer:
      bootstrap-servers: hdp-1:6667,hdp-2:6667,hdp-3:6667
      acks: -1
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.apache.kafka.common.serialization.StringSerializer
    security:
      protocol: SASL_PLAINTEXT
    jaas:
      enabled: true
      login-module: com.sun.security.auth.module.Krb5LoginModule
      options:
        useKeyTab: true
        storeKey: true
        useTicketCache: false
        keyTab: file:D:/code/kerberos/kafka.keytab
        principal: kafka/hdp-1@HADOOP.COM
    properties:
      sasl:
        mechanism: GSSAPI
        kerberos:
          service:
            name: kafka
          min:
            time:
              before:
                relogin: 1

        查看 KerberosLogin 源码,isUsingTicketCache (是否使用票据缓存),对应配置中的useTicketCache:

如果 useTicketCache 设置成 true,会经过如下逻辑:

tips: 如果大家查看源码的话,可以关注一下 KerberosLogin 的 login 方法,此方法创建了一个 定时任务的线程,用来解决票据刷新问题的,具体代码我就不贴图啦。

 此方法会调用 shell 命令:

 后续有查看了kafka的官方文档,发现有相关的配置项:

文档链接:Kafka 中文文档 - ApacheCNApache Kafka: A Distributed Streaming Platform.https://kafka.apachecn.org/documentation.html#producerconfigs

        至此找到了问题出现的原因,由于线上项目 useTicketCache 设置成了 true, 导致每次票据刷新的定时任务都会经过上述逻辑,调用 Kerberos kinit 命令,但是项目运行的服务器并没有 kinit,所以出现异常,票据刷新失败。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值