• Kafka-Kerberos票据刷新问题


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

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

    1. 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
    2. java.io.IOException: Cannot run program "/usr/bin/kinit": CreateProcess error=2, 系统找不到指定的文件。
    3. at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1128)
    4. at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1071)
    5. at org.apache.kafka.common.utils.Shell.runCommand(Shell.java:85)
    6. at org.apache.kafka.common.utils.Shell.run(Shell.java:76)
    7. at org.apache.kafka.common.utils.Shell$ShellCommandExecutor.execute(Shell.java:204)
    8. at org.apache.kafka.common.utils.Shell.execCommand(Shell.java:268)
    9. at org.apache.kafka.common.utils.Shell.execCommand(Shell.java:255)
    10. at org.apache.kafka.common.security.kerberos.KerberosLogin.lambda$login$0(KerberosLogin.java:212)
    11. at java.base/java.lang.Thread.run(Thread.java:829)
    12. Caused by: java.io.IOException: CreateProcess error=2, 系统找不到指定的文件。
    13. at java.base/java.lang.ProcessImpl.create(Native Method)
    14. at java.base/java.lang.ProcessImpl.(ProcessImpl.java:492)
    15. at java.base/java.lang.ProcessImpl.start(ProcessImpl.java:153)
    16. at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1107)
    17. ... 8 common frames omitted

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

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

    yml文件相关配置:

    1. spring:
    2. application:
    3. name: kerberos
    4. kafka:
    5. consumer:
    6. bootstrap-servers: hdp-1:6667,hdp-2:6667,hdp-3:6667
    7. group-id: kafka-example
    8. key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
    9. value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
    10. enable-auto-commit: true
    11. auto-commit-interval: 1000
    12. auto-offset-reset: earliest
    13. producer:
    14. bootstrap-servers: hdp-1:6667,hdp-2:6667,hdp-3:6667
    15. acks: -1
    16. key-serializer: org.apache.kafka.common.serialization.StringSerializer
    17. value-serializer: org.apache.kafka.common.serialization.StringSerializer
    18. security:
    19. protocol: SASL_PLAINTEXT
    20. jaas:
    21. enabled: true
    22. login-module: com.sun.security.auth.module.Krb5LoginModule
    23. options:
    24. useKeyTab: true
    25. storeKey: true
    26. useTicketCache: false
    27. keyTab: file:D:/code/kerberos/kafka.keytab
    28. principal: kafka/hdp-1@HADOOP.COM
    29. properties:
    30. sasl:
    31. mechanism: GSSAPI
    32. kerberos:
    33. service:
    34. name: kafka
    35. min:
    36. time:
    37. before:
    38. 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,所以出现异常,票据刷新失败。

  • 相关阅读:
    AOP中5种通知的注解
    FAST-LIO,FAST-LIO2与FASTER-LIO
    H5生成二维码
    IO流 -- 调研
    TOUGH2系列建模方法及在CO2地质封存、水文地球化学、地热、地下水污染等领域中的实践技术应用
    java毕业设计商场后台管理系统源码+lw文档+mybatis+系统+mysql数据库+调试
    SpringMVC+Vue项目高校课程评价系统
    mirai Bot初始化配置
    【DevPress】V2.4.1版本发布,增加抽奖组件
    2.1.4 面向对象:类的继承(Python)
  • 原文地址:https://blog.csdn.net/W_Meng_H/article/details/133385890